plans doc and settings
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# CLAUDE.md — CoreCore (ImmobilienMaklerVerkaufssoftware)
|
||||
# CLAUDE.md — CoreCore
|
||||
|
||||
Multi-tenant admin application built on MintyPHP. Manages tenants, users, departments, roles, permissions, address books, mail, CSV imports, scheduled jobs, and Microsoft Entra ID SSO.
|
||||
|
||||
|
||||
124
agent-system/runs/CODE-DEDUP-REPOSITORY-001/plan.json
Normal file
124
agent-system/runs/CODE-DEDUP-REPOSITORY-001/plan.json
Normal file
@@ -0,0 +1,124 @@
|
||||
{
|
||||
"task_id": "CODE-DEDUP-REPOSITORY-001",
|
||||
"summary": "Extract repeated repository boilerplate (ID extraction, array sanitization, unwrap/normalization) into shared support utilities to eliminate ~290 lines of duplication across 6+ repository files.",
|
||||
"assumptions": [
|
||||
"MintyPHP DB layer returns nested arrays with table-name keys (e.g. $row['tenants']).",
|
||||
"All repositories use the same unwrap, unwrapList, extractIds, and sanitizePositiveIds patterns.",
|
||||
"A trait or static helper class is the right abstraction — no base repository class needed (repositories are thin)."
|
||||
],
|
||||
"scope": {
|
||||
"in": [
|
||||
"lib/Repository/Tenant/TenantRepository.php — unwrap, unwrapList, listIds extraction",
|
||||
"lib/Repository/Access/RoleRepository.php — unwrap, unwrapList, listIds extraction",
|
||||
"lib/Repository/Org/DepartmentRepository.php — unwrap, unwrapList, listIds extraction",
|
||||
"lib/Repository/Access/PermissionRepository.php — ID extraction patterns",
|
||||
"lib/Repository/Access/UserRoleRepository.php — ID sanitization",
|
||||
"lib/Repository/Org/UserDepartmentRepository.php — ID sanitization",
|
||||
"New file: lib/Repository/Support/RepositoryArrayHelper.php"
|
||||
],
|
||||
"out": [
|
||||
"Repository method signatures (public API unchanged)",
|
||||
"Repository SQL queries (not touched)",
|
||||
"Service layer changes",
|
||||
"Frontend changes"
|
||||
]
|
||||
},
|
||||
"guardrails": {
|
||||
"required_guard_ids": [
|
||||
"GR-CORE-001",
|
||||
"GR-LANG-001",
|
||||
"GR-LANG-002",
|
||||
"GR-TEST-001",
|
||||
"GR-TEST-002"
|
||||
],
|
||||
"required_quality_gate_ids": [
|
||||
"QG-001",
|
||||
"QG-002",
|
||||
"QG-003",
|
||||
"QG-006"
|
||||
]
|
||||
},
|
||||
"success_criteria": [
|
||||
{
|
||||
"id": "SC-001",
|
||||
"criterion": "A single RepositoryArrayHelper class exists in lib/Repository/Support/ providing extractIds(), sanitizePositiveIds(), unwrap(), and unwrapList() as static methods."
|
||||
},
|
||||
{
|
||||
"id": "SC-002",
|
||||
"criterion": "All 6+ repository files use RepositoryArrayHelper instead of inline implementations. No duplicate unwrap/extractIds/sanitize logic remains."
|
||||
},
|
||||
{
|
||||
"id": "SC-003",
|
||||
"criterion": "Repository public method signatures and return values are identical before and after refactoring (pure internal refactor)."
|
||||
},
|
||||
{
|
||||
"id": "SC-004",
|
||||
"criterion": "PHPUnit, PHPStan, and CS checks pass green."
|
||||
}
|
||||
],
|
||||
"implementation_steps": [
|
||||
{
|
||||
"id": "S1",
|
||||
"title": "Create RepositoryArrayHelper",
|
||||
"description": "Create lib/Repository/Support/RepositoryArrayHelper.php with static methods: extractIds(array $rows, string $tableKey): array, sanitizePositiveIds(array $ids): array, unwrap(?array $row, string $tableKey): ?array, unwrapList(mixed $rows, string $tableKey): array.",
|
||||
"guard_refs": ["GR-CORE-001", "GR-LANG-001"]
|
||||
},
|
||||
{
|
||||
"id": "S2",
|
||||
"title": "Write unit tests for RepositoryArrayHelper",
|
||||
"description": "Test all 4 methods with edge cases: empty arrays, null input, missing table keys, mixed types, duplicate IDs, negative IDs.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S3",
|
||||
"title": "Refactor TenantRepository",
|
||||
"description": "Replace inline unwrap/unwrapList/extractIds with RepositoryArrayHelper calls. Verify no signature changes.",
|
||||
"guard_refs": ["GR-CORE-001"]
|
||||
},
|
||||
{
|
||||
"id": "S4",
|
||||
"title": "Refactor RoleRepository and PermissionRepository",
|
||||
"description": "Replace inline implementations with RepositoryArrayHelper calls.",
|
||||
"guard_refs": ["GR-CORE-001"]
|
||||
},
|
||||
{
|
||||
"id": "S5",
|
||||
"title": "Refactor DepartmentRepository and UserDepartmentRepository",
|
||||
"description": "Replace inline implementations with RepositoryArrayHelper calls.",
|
||||
"guard_refs": ["GR-CORE-001"]
|
||||
},
|
||||
{
|
||||
"id": "S6",
|
||||
"title": "Refactor UserRoleRepository",
|
||||
"description": "Replace inline ID sanitization with RepositoryArrayHelper::sanitizePositiveIds().",
|
||||
"guard_refs": ["GR-CORE-001"]
|
||||
},
|
||||
{
|
||||
"id": "S7",
|
||||
"title": "Run all quality gates",
|
||||
"description": "QG-001 PHPUnit, QG-002 PHPStan, QG-003 Architecture, QG-006 CS check.",
|
||||
"guard_refs": ["GR-LANG-002"]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
"tests/Repository/Support/RepositoryArrayHelperTest.php — new, covers all 4 static methods with edge cases",
|
||||
"tests/Architecture/CoreStarterkitContractTest.php — must stay green",
|
||||
"Existing service tests that call repository methods indirectly — must stay green"
|
||||
],
|
||||
"acceptance_checks": [
|
||||
"SC-001: File lib/Repository/Support/RepositoryArrayHelper.php exists with 4 public static methods",
|
||||
"SC-002: rg 'foreach.*\\$row.*\\[.*id.*\\]' lib/Repository/ returns only RepositoryArrayHelper, not inline implementations",
|
||||
"SC-003: git diff shows no changes to public method signatures in repository files",
|
||||
"SC-004: QG-001 + QG-002 + QG-006 exit 0"
|
||||
],
|
||||
"risks": [
|
||||
{
|
||||
"risk": "Subtle behavioral difference in edge cases between inline and helper implementations",
|
||||
"mitigation": "Write comprehensive helper tests first (TDD). Run full QG-001 after each repository file change."
|
||||
},
|
||||
{
|
||||
"risk": "Table key naming inconsistency across repositories",
|
||||
"mitigation": "Audit all unwrap calls first to confirm table key naming. The helper accepts the key as parameter, so naming differences are handled."
|
||||
}
|
||||
]
|
||||
}
|
||||
116
agent-system/runs/TEST-COVERAGE-GATEWAYS-001/plan.json
Normal file
116
agent-system/runs/TEST-COVERAGE-GATEWAYS-001/plan.json
Normal file
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"task_id": "TEST-COVERAGE-GATEWAYS-001",
|
||||
"summary": "Add PHPUnit tests for 4 critical untested gateways: AuthCryptoGateway, SettingsCryptoGateway, OidcHttpGateway, PermissionGateway. These are security-critical components with 0% test coverage.",
|
||||
"assumptions": [
|
||||
"AuthCryptoGateway and SettingsCryptoGateway wrap lib/Support/Crypto.php — tests verify correct delegation and error handling.",
|
||||
"OidcHttpGateway makes HTTP calls to Microsoft OIDC endpoints — tests will mock the HTTP client.",
|
||||
"PermissionGateway may be refactored in ARCH-GATEWAY-COMPLIANCE-001. If so, test the refactored version. If not yet done, test current version.",
|
||||
"Focus on security-critical gateways first; remaining 19 untested gateways can follow in a later task."
|
||||
],
|
||||
"scope": {
|
||||
"in": [
|
||||
"New: tests/Service/Auth/AuthCryptoGatewayTest.php — encryption/decryption delegation",
|
||||
"New: tests/Service/Settings/SettingsCryptoGatewayTest.php — settings value encryption",
|
||||
"New: tests/Service/Auth/OidcHttpGatewayTest.php — OIDC token validation, HTTP error handling",
|
||||
"New: tests/Service/Access/PermissionGatewayTest.php — permission lookup delegation"
|
||||
],
|
||||
"out": [
|
||||
"Non-critical gateways (AddressBook, Import, Directory scope gateways)",
|
||||
"Production code changes",
|
||||
"Repository tests",
|
||||
"Integration tests with real HTTP or crypto operations"
|
||||
]
|
||||
},
|
||||
"guardrails": {
|
||||
"required_guard_ids": [
|
||||
"GR-TEST-001",
|
||||
"GR-TEST-002",
|
||||
"GR-SEC-005",
|
||||
"GR-LANG-001",
|
||||
"GR-LANG-002"
|
||||
],
|
||||
"required_quality_gate_ids": [
|
||||
"QG-001",
|
||||
"QG-002",
|
||||
"QG-006"
|
||||
]
|
||||
},
|
||||
"success_criteria": [
|
||||
{
|
||||
"id": "SC-001",
|
||||
"criterion": "All 4 test files exist with happy-path + error/edge-case coverage for every public method."
|
||||
},
|
||||
{
|
||||
"id": "SC-002",
|
||||
"criterion": "AuthCryptoGateway and SettingsCryptoGateway tests verify that Crypto class is used (not raw openssl), per GR-SEC-005."
|
||||
},
|
||||
{
|
||||
"id": "SC-003",
|
||||
"criterion": "OidcHttpGateway tests cover: successful token exchange, invalid token response, network timeout, malformed response body."
|
||||
},
|
||||
{
|
||||
"id": "SC-004",
|
||||
"criterion": "PHPUnit (QG-001) and PHPStan (QG-002) pass green."
|
||||
}
|
||||
],
|
||||
"implementation_steps": [
|
||||
{
|
||||
"id": "S1",
|
||||
"title": "Analyze public API of all 4 gateways",
|
||||
"description": "Read each gateway, list public methods, identify constructor dependencies, plan test scenarios.",
|
||||
"guard_refs": ["GR-TEST-001"]
|
||||
},
|
||||
{
|
||||
"id": "S2",
|
||||
"title": "Write AuthCryptoGatewayTest",
|
||||
"description": "Test encrypt/decrypt delegation to Crypto class. Test error handling for invalid keys, empty input, corrupted ciphertext.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-SEC-005"]
|
||||
},
|
||||
{
|
||||
"id": "S3",
|
||||
"title": "Write SettingsCryptoGatewayTest",
|
||||
"description": "Test settings value encryption/decryption. Test round-trip (encrypt then decrypt returns original). Test error paths.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-SEC-005"]
|
||||
},
|
||||
{
|
||||
"id": "S4",
|
||||
"title": "Write OidcHttpGatewayTest",
|
||||
"description": "Mock HTTP client. Test token exchange happy path, invalid response codes (401, 500), network errors, malformed JSON response, missing required fields in token response.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S5",
|
||||
"title": "Write PermissionGatewayTest",
|
||||
"description": "Test permission lookup methods. Mock underlying dependency (Service or Repository depending on ARCH-GATEWAY-COMPLIANCE-001 status).",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S6",
|
||||
"title": "Run quality gates",
|
||||
"description": "QG-001, QG-002, QG-006.",
|
||||
"guard_refs": ["GR-LANG-002"]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
"tests/Service/Auth/AuthCryptoGatewayTest.php",
|
||||
"tests/Service/Settings/SettingsCryptoGatewayTest.php",
|
||||
"tests/Service/Auth/OidcHttpGatewayTest.php",
|
||||
"tests/Service/Access/PermissionGatewayTest.php"
|
||||
],
|
||||
"acceptance_checks": [
|
||||
"SC-001: All 4 test files pass with >= 3 test methods each",
|
||||
"SC-002: AuthCrypto + SettingsCrypto tests assert Crypto class method calls via mock expectations",
|
||||
"SC-003: OidcHttpGatewayTest has test methods for success, 401, 500, timeout, malformed JSON",
|
||||
"SC-004: QG-001 + QG-002 + QG-006 exit 0"
|
||||
],
|
||||
"risks": [
|
||||
{
|
||||
"risk": "OidcHttpGateway may use PHP native curl/file_get_contents instead of injectable HTTP client",
|
||||
"mitigation": "If not mockable, document as tech debt and test at integration level with a mock HTTP server, or refactor to accept an HTTP client interface."
|
||||
},
|
||||
{
|
||||
"risk": "PermissionGateway may change in ARCH-GATEWAY-COMPLIANCE-001",
|
||||
"mitigation": "If ARCH task runs first, write tests against refactored version. If not, write tests against current version and note that tests may need update."
|
||||
}
|
||||
]
|
||||
}
|
||||
81
agent-system/runs/TEST-COVERAGE-POLICIES-001/plan.json
Normal file
81
agent-system/runs/TEST-COVERAGE-POLICIES-001/plan.json
Normal file
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"task_id": "TEST-COVERAGE-POLICIES-001",
|
||||
"summary": "Add PHPUnit test for the single untested authorization policy: OperationsAuthorizationPolicy. Achieves 100% policy test coverage (7/7).",
|
||||
"assumptions": [
|
||||
"OperationsAuthorizationPolicy follows the same pattern as the 6 tested policies (returns AuthorizationDecision).",
|
||||
"Can use the existing AuthorizationPolicyTestSupport trait for consistent assertions.",
|
||||
"Policy has constructor-injected dependencies (gateways) that can be mocked."
|
||||
],
|
||||
"scope": {
|
||||
"in": [
|
||||
"New: tests/Service/Access/OperationsAuthorizationPolicyTest.php"
|
||||
],
|
||||
"out": [
|
||||
"Other policy files (already tested)",
|
||||
"Production code changes",
|
||||
"Service or gateway tests"
|
||||
]
|
||||
},
|
||||
"guardrails": {
|
||||
"required_guard_ids": [
|
||||
"GR-TEST-001",
|
||||
"GR-TEST-002",
|
||||
"GR-CORE-005",
|
||||
"GR-LANG-001",
|
||||
"GR-LANG-002"
|
||||
],
|
||||
"required_quality_gate_ids": [
|
||||
"QG-001",
|
||||
"QG-002",
|
||||
"QG-006"
|
||||
]
|
||||
},
|
||||
"success_criteria": [
|
||||
{
|
||||
"id": "SC-001",
|
||||
"criterion": "OperationsAuthorizationPolicyTest exists and covers every public method with allowed + denied scenarios."
|
||||
},
|
||||
{
|
||||
"id": "SC-002",
|
||||
"criterion": "Test uses AuthorizationPolicyTestSupport trait for consistent assertion patterns."
|
||||
},
|
||||
{
|
||||
"id": "SC-003",
|
||||
"criterion": "All 7 policy test files pass green (100% policy coverage)."
|
||||
}
|
||||
],
|
||||
"implementation_steps": [
|
||||
{
|
||||
"id": "S1",
|
||||
"title": "Analyze OperationsAuthorizationPolicy",
|
||||
"description": "Read the policy file, identify public methods, constructor dependencies, and authorization decision logic.",
|
||||
"guard_refs": ["GR-CORE-005"]
|
||||
},
|
||||
{
|
||||
"id": "S2",
|
||||
"title": "Write OperationsAuthorizationPolicyTest",
|
||||
"description": "Use AuthorizationPolicyTestSupport trait. Test: allowed scenarios (correct permissions), denied scenarios (missing permissions, wrong scope), edge cases (null user, empty permissions).",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S3",
|
||||
"title": "Run quality gates",
|
||||
"description": "QG-001, QG-002, QG-006.",
|
||||
"guard_refs": ["GR-LANG-002"]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
"tests/Service/Access/OperationsAuthorizationPolicyTest.php"
|
||||
],
|
||||
"acceptance_checks": [
|
||||
"SC-001: Test file has >= 6 test methods covering allowed + denied + edge cases",
|
||||
"SC-002: Test class uses AuthorizationPolicyTestSupport trait (assertForbiddenDecision, assertDeniedDecision)",
|
||||
"SC-003: docker compose exec php vendor/bin/phpunit tests/Service/Access/ exits 0 with all 7 policy tests passing"
|
||||
],
|
||||
"risks": [
|
||||
{
|
||||
"risk": "OperationsAuthorizationPolicy may have different constructor signature than other policies",
|
||||
"mitigation": "Read the file first (S1). Adapt mocking strategy to match actual dependencies."
|
||||
}
|
||||
]
|
||||
}
|
||||
149
agent-system/runs/TEST-COVERAGE-SERVICES-001/plan.json
Normal file
149
agent-system/runs/TEST-COVERAGE-SERVICES-001/plan.json
Normal file
@@ -0,0 +1,149 @@
|
||||
{
|
||||
"task_id": "TEST-COVERAGE-SERVICES-001",
|
||||
"summary": "Add PHPUnit tests for 7 critical untested services: PermissionService, RoleService, DepartmentService, TenantService, MailService, UserLifecycleService, RateLimiterService.",
|
||||
"assumptions": [
|
||||
"All 7 services use constructor injection and are unit-testable with mocks (GR-TEST-002 compliant).",
|
||||
"Focus on happy path + at least one failure/edge case per public method (GR-TEST-001).",
|
||||
"Services that orchestrate repositories will have repositories mocked.",
|
||||
"MailService test will mock PHPMailer — no actual email sending."
|
||||
],
|
||||
"scope": {
|
||||
"in": [
|
||||
"New: tests/Service/Access/PermissionServiceTest.php — CRUD + permission assignment logic",
|
||||
"New: tests/Service/Access/RoleServiceTest.php — CRUD + role validation",
|
||||
"New: tests/Service/Org/DepartmentServiceTest.php — CRUD + hierarchy validation",
|
||||
"New: tests/Service/Tenant/TenantServiceTest.php — CRUD + tenant lifecycle",
|
||||
"New: tests/Service/Mail/MailServiceTest.php — composition + send + error handling",
|
||||
"New: tests/Service/User/UserLifecycleServiceTest.php — state transitions (active/inactive/deleted)",
|
||||
"New: tests/Service/Security/RateLimiterServiceTest.php — rate limit enforcement + reset"
|
||||
],
|
||||
"out": [
|
||||
"Repository tests (separate task)",
|
||||
"Gateway tests (separate task)",
|
||||
"Integration/E2E tests",
|
||||
"Production code changes (test-only task)",
|
||||
"Medium/low priority untested services (BrandingService, SearchDataService, etc.)"
|
||||
]
|
||||
},
|
||||
"guardrails": {
|
||||
"required_guard_ids": [
|
||||
"GR-TEST-001",
|
||||
"GR-TEST-002",
|
||||
"GR-LANG-001",
|
||||
"GR-LANG-002"
|
||||
],
|
||||
"required_quality_gate_ids": [
|
||||
"QG-001",
|
||||
"QG-002",
|
||||
"QG-006"
|
||||
]
|
||||
},
|
||||
"success_criteria": [
|
||||
{
|
||||
"id": "SC-001",
|
||||
"criterion": "All 7 test files exist and contain at least one happy-path and one failure/edge-case test per public method of the corresponding service."
|
||||
},
|
||||
{
|
||||
"id": "SC-002",
|
||||
"criterion": "Each test file uses proper mocking (createMock) for all injected dependencies — no real DB or HTTP calls."
|
||||
},
|
||||
{
|
||||
"id": "SC-003",
|
||||
"criterion": "Total new test methods >= 40 across the 7 files (average ~6 per service)."
|
||||
},
|
||||
{
|
||||
"id": "SC-004",
|
||||
"criterion": "PHPUnit full suite (QG-001) passes green including all new tests."
|
||||
},
|
||||
{
|
||||
"id": "SC-005",
|
||||
"criterion": "PHPStan (QG-002) passes green — test files are type-safe."
|
||||
}
|
||||
],
|
||||
"implementation_steps": [
|
||||
{
|
||||
"id": "S1",
|
||||
"title": "Analyze public API of all 7 services",
|
||||
"description": "Read each service file, list all public methods, identify constructor dependencies, and plan test scenarios (happy path + edge cases).",
|
||||
"guard_refs": ["GR-TEST-001"]
|
||||
},
|
||||
{
|
||||
"id": "S2",
|
||||
"title": "Write PermissionServiceTest",
|
||||
"description": "Test CRUD operations (createFromAdmin, updateFromAdmin, deleteById), permission assignment, and validation error paths.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S3",
|
||||
"title": "Write RoleServiceTest",
|
||||
"description": "Test CRUD operations, role validation (duplicate name, missing fields), and permission assignment.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S4",
|
||||
"title": "Write DepartmentServiceTest",
|
||||
"description": "Test CRUD operations, hierarchy validation, tenant scope enforcement.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S5",
|
||||
"title": "Write TenantServiceTest",
|
||||
"description": "Test CRUD operations, tenant lifecycle (activate/deactivate), slug generation, validation.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S6",
|
||||
"title": "Write MailServiceTest",
|
||||
"description": "Test email composition, recipient validation, template rendering, and error handling when SMTP fails. Mock PHPMailer.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S7",
|
||||
"title": "Write UserLifecycleServiceTest",
|
||||
"description": "Test state transitions: active->inactive, inactive->active, soft-delete, restore. Test audit trail calls.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S8",
|
||||
"title": "Write RateLimiterServiceTest",
|
||||
"description": "Test rate limit enforcement (under limit, at limit, over limit), reset, and TTL expiration.",
|
||||
"guard_refs": ["GR-TEST-001", "GR-TEST-002"]
|
||||
},
|
||||
{
|
||||
"id": "S9",
|
||||
"title": "Run quality gates",
|
||||
"description": "QG-001 PHPUnit full, QG-002 PHPStan, QG-006 CS check.",
|
||||
"guard_refs": ["GR-LANG-002"]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
"tests/Service/Access/PermissionServiceTest.php",
|
||||
"tests/Service/Access/RoleServiceTest.php",
|
||||
"tests/Service/Org/DepartmentServiceTest.php",
|
||||
"tests/Service/Tenant/TenantServiceTest.php",
|
||||
"tests/Service/Mail/MailServiceTest.php",
|
||||
"tests/Service/User/UserLifecycleServiceTest.php",
|
||||
"tests/Service/Security/RateLimiterServiceTest.php"
|
||||
],
|
||||
"acceptance_checks": [
|
||||
"SC-001: Each test file covers every public method of its service with happy + failure paths",
|
||||
"SC-002: rg 'createMock' in all 7 test files shows proper dependency mocking",
|
||||
"SC-003: phpunit --list-tests | grep -c 'Test::test' for new files totals >= 40",
|
||||
"SC-004: docker compose exec php vendor/bin/phpunit exits 0",
|
||||
"SC-005: docker compose exec php vendor/bin/phpstan analyse exits 0"
|
||||
],
|
||||
"risks": [
|
||||
{
|
||||
"risk": "Services with complex dependencies (MailService depends on PHPMailer, SMTP config) may be hard to mock",
|
||||
"mitigation": "Use interface-based mocking. If PHPMailer is used directly, mock at the gateway boundary instead."
|
||||
},
|
||||
{
|
||||
"risk": "UserLifecycleService may have implicit state dependencies (session, tenant context)",
|
||||
"mitigation": "Analyze constructor carefully. Mock all injected gateways/services. If static state access exists, document as tech debt for later refactor."
|
||||
},
|
||||
{
|
||||
"risk": "Scope creep — discovering untestable code that needs refactoring",
|
||||
"mitigation": "Document untestable patterns as findings but do NOT refactor production code in this task. Create follow-up tasks instead."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'app_title' => 'CoreCore',
|
||||
'app_locale' => 'de',
|
||||
|
||||
@@ -8,7 +8,7 @@ In 10 Minuten verstehen, was die Software tut, wie sie aufgebaut ist und welche
|
||||
|
||||
## Was ist CoreCore?
|
||||
|
||||
CoreCore ist eine mandantenfähige Admin-Software für Immobilienmakler-Prozesse mit klarer Rollen-/Rechtestruktur.
|
||||
CoreCore ist eine mandantenfähige Admin-Software mit klarer Rollen-/Rechtestruktur.
|
||||
|
||||
Kernmodule:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user