{ "task_id": "ARCH-GATEWAY-COMPLIANCE-001", "summary": "Refactor 6 Gateway classes that violate the Gateway contract by wrapping Services instead of adapting single external dependencies (repository, settings, HTTP API, scope).", "assumptions": [ "Gateway definition: adapter for a single external dependency. No orchestration, no Service injection.", "Gateways that are pure pass-throughs to a Service should either be collapsed into the calling Service or re-wired to depend on the Repository/external dependency directly.", "Existing tests for Settings gateways will guide the refactoring pattern." ], "scope": { "in": [ "lib/Service/Access/PermissionGateway.php — wraps PermissionService, should depend on PermissionRepository", "lib/Service/Auth/AuthAvatarGateway.php — wraps UserAvatarService, should depend on Repository or be collapsed", "lib/Service/Settings/SettingsAppGateway.php — mixes Gateway + ThemeConfigService dependency", "lib/Service/AddressBook/AddressBookDirectoryGateway.php — orchestrates 3 Services (TenantService, DepartmentService, RoleService)", "lib/Service/Auth/AuthSavedFilterGateway.php — wraps UserSavedFilterService", "lib/Service/Auth/AuthTenantSsoGateway.php — wraps TenantSsoService", "All Factory registrars that wire the above gateways", "All callers of the above gateways (update injection sites)" ], "out": [ "Settings gateways (SettingsMetadataGateway, SettingsSmtpGateway etc.) — already correctly wired", "Auth gateways that depend on repositories/scope (AuthScopeGateway, AuthCryptoGateway) — compliant", "New feature work or UI changes", "Test coverage for unrelated components" ] }, "guardrails": { "required_guard_ids": [ "GR-CORE-001", "GR-CORE-002", "GR-TEST-001", "GR-TEST-002", "GR-LANG-001", "GR-LANG-002" ], "required_quality_gate_ids": [ "QG-001", "QG-002", "QG-003", "QG-004", "QG-006" ] }, "success_criteria": [ { "id": "SC-001", "criterion": "No Gateway in lib/Service/ injects a *Service class. All Gateway constructors receive only Repository interfaces, other Gateways, or framework abstractions." }, { "id": "SC-002", "criterion": "All 6 identified gateway files are either refactored to depend on repositories/externals or collapsed into their parent Service." }, { "id": "SC-003", "criterion": "PHPUnit (QG-001), PHPStan (QG-002), and Architecture Contract (QG-003) pass green." }, { "id": "SC-004", "criterion": "Structural rg checks (QG-004) show zero new violations for Service instantiation in gateways." }, { "id": "SC-005", "criterion": "Existing tests for callers of refactored gateways still pass with no behavioral regression; wiring-level test adjustments (mock type/method updates) are allowed." } ], "implementation_steps": [ { "id": "S1", "title": "Audit and classify each gateway violation", "description": "For each of the 6 gateways, determine the correct fix: (A) re-wire to Repository dependency, (B) collapse into parent Service, or (C) split into multiple single-dependency gateways. Document decision per gateway.", "guard_refs": ["GR-CORE-001"] }, { "id": "S2", "title": "Refactor PermissionGateway", "description": "Replace PermissionService dependency with PermissionRepository (and RolePermissionRepository if needed). Update PermissionGateway methods to call repository directly. Update Factory registrar.", "guard_refs": ["GR-CORE-001", "GR-CORE-002"] }, { "id": "S3", "title": "Refactor AuthAvatarGateway", "description": "Replace UserAvatarService dependency with the underlying repository or collapse gateway into AuthService. Update Factory registrar and all callers.", "guard_refs": ["GR-CORE-001", "GR-CORE-002"] }, { "id": "S4", "title": "Refactor SettingsAppGateway", "description": "Remove ThemeConfigService dependency. If theme resolution is needed, inject the underlying repository/settings gateway instead. Keep SettingsMetadataGateway dependency (compliant).", "guard_refs": ["GR-CORE-001", "GR-CORE-002"] }, { "id": "S5", "title": "Refactor AddressBookDirectoryGateway", "description": "This gateway orchestrates 3 Services — split into single-dependency gateways or move orchestration into AddressBookService. Remove redundant pass-through methods.", "guard_refs": ["GR-CORE-001", "GR-CORE-002"] }, { "id": "S6", "title": "Refactor AuthSavedFilterGateway and AuthTenantSsoGateway", "description": "Replace Service dependencies with Repository interfaces. Both are thin wrappers — re-wire to underlying repositories.", "guard_refs": ["GR-CORE-001", "GR-CORE-002"] }, { "id": "S7", "title": "Update Factory registrars and DI wiring", "description": "Update all Container/Registrars/ files that wire the refactored gateways. Ensure no circular dependencies introduced.", "guard_refs": ["GR-CORE-002", "GR-LANG-001"] }, { "id": "S8", "title": "Add/update tests for refactored gateways", "description": "Write unit tests for each refactored gateway verifying the new dependency wiring and behavior preservation.", "guard_refs": ["GR-TEST-001", "GR-TEST-002"] }, { "id": "S9", "title": "Run all quality gates", "description": "Execute QG-001 through QG-006. Fix any regressions.", "guard_refs": ["GR-LANG-002"] } ], "tests": [ "tests/Service/Access/PermissionGatewayTest.php — verify gateway uses repository directly", "tests/Service/Auth/AuthAvatarGatewayTest.php — verify refactored dependency", "tests/Service/Settings/SettingsAppGatewayTest.php — update existing test for removed ThemeConfigService dep", "tests/Service/AddressBook/AddressBookDirectoryGatewayTest.php — verify single-dependency contract", "tests/Service/Auth/AuthSavedFilterGatewayTest.php — verify refactored dependency", "tests/Service/Auth/AuthTenantSsoGatewayTest.php — verify refactored dependency", "tests/Architecture/CoreStarterkitContractTest.php — must stay green" ], "acceptance_checks": [ "SC-001: grep -r 'Service' lib/Service/**/*Gateway.php constructors shows zero Service type-hints (only Repository, Gateway, framework interfaces)", "SC-002: All 6 files listed in scope are either refactored or removed with functionality merged upstream", "SC-003: docker compose exec php vendor/bin/phpunit exits 0 AND docker compose exec php vendor/bin/phpstan analyse exits 0", "SC-004: QG-004 structural rg checks return 0 for gateway service-injection pattern", "SC-005: Full test suite green with no behavioral regression; wiring-level test updates are allowed" ], "risks": [ { "risk": "Circular dependency introduced when gateways switch from Service to Repository dependency", "mitigation": "Map full dependency graph before refactoring. Use PHPStan to detect cycles. Refactor one gateway at a time with QG-001+QG-002 after each." }, { "risk": "AddressBookDirectoryGateway split creates too many small gateways", "mitigation": "Prefer moving orchestration into AddressBookService over splitting. Only split if single-responsibility is clearly better." }, { "risk": "Behavioral regression in callers that depend on gateway method signatures", "mitigation": "Keep method signatures stable (same public API). Only change internal wiring. Existing caller tests catch regressions." } ] }