5.7 KiB
5.7 KiB
1. Auth and strict types parity
- 1.1 Add
MustVerifyEmailtoUserand require verified + active incanAccessPanel; update seed so admin/assistant are verified; feature tests for unverified denial and verified access - 1.2 Confirm Filament/Laravel password reset is enabled; add feature tests for registered vs unknown email without account enumeration — required a custom
App\Filament\Pages\Auth\RequestPasswordResetoverriding Filament's stock page, which discloses account existence via a distinguishable danger notification onPassword::INVALID_USER - 1.3 Add
declare(strict_types=1);to project-owned PHP files missing it (e.g.AdminPanelProvider); architecture/unit regression as needed — 15 files total:AdminPanelProvider,Controller, and 13 Filament Resource Pages classes - 1.4 Run
composer pint,composer phpstan, andcomposer test:featurefor auth changes — all green
2. Local runtime and PHP 8.4 alignment
- 2.1 Extend
docker-compose.ymlwith FrankenPHPappservice (build Dockerfile, depend on healthy postgres, publish 8000); document in README - 2.2 Align README/docs to PHP 8.4 canonical (keep Composer
^8.3); verify Dockerfile/CI already on 8.4 - 2.3 Smoke local compose:
docker compose up -d→GET /upreturns 200 — run as an isolated-p fase0smokeproject (separate container names/ports via a!overridecompose overlay, kept outside the repo) so it didn't collide with theamare-postgrescontainer already running for a concurrent sibling worktree session.depends_on: condition: service_healthycorrectly gatedappon Postgres's healthcheck,curl localhost:18000/upreturned200, anddocker exec ... php artisan migrate --forcesucceeded — provingDB_HOST: postgresresolves theappcontainer to thepostgresservice by Compose's service-name DNS, not just that the image boots. Torn down afterwards (down -v+ image removal); the shared siblingamare-postgrescontainer was untouched throughout. - 2.4 Run
composer qualityafter compose/docs changes — pint/phpstan/test:feature all green locally (browser suite is CI-only, per AGENTS.md)
3. Quality gates: npm audit and coverage
- 3.1 Add npm audit step to
composer qualityand CIstatic(policy: production deps; document any allowlist) —npm audit --omit=dev --audit-level=high, rationale documented inline inci.yml; currently a vacuous forward guard sincepackage.jsonhas no runtimedependencies - 3.2 Enable Domain/Application coverage in CI
unitwith 80% fail threshold; exclude views/migrations/framework — scoped via a dedicatedphpunit.coverage.xml(not the project-widephpunit.xml), run asUnit,Architecture,Featurebecause theApplication/Queries/Marketingclasses are only exercised via Feature/HTTP tests; measured locally withpcovat 98.1%, well above the 80% gate - 3.3 Add/adjust unit tests if current Domain/Application coverage is below threshold — no-op: measured coverage (98.1%) already clears 80% with existing Feature-suite coverage of the Marketing queries plus existing
PageMeta/HomeContentunit tests - 3.4 Verify CI
staticandunitfail appropriately on intentional audit/coverage breakage in a branch experiment or equivalent proof — blocked: no push/PR in this task's scope, so no real CI run exists to break intentionally; defer to a follow-up once a PR is open
4. Staging/production Compose and Dokploy prep
- 4.1 Add versioned Compose template (
docker-compose.deploy.yml: web, queue, scheduler, migrate one-shot) parameterized byAPP_IMAGE/IMAGE_TAGfor staging and production stacks - 4.2 Document Dokploy project setup: GHCR registry credentials, Postgres per environment, Compose import, required env vars (APP_KEY, DB, Resend, R2), trusted proxies/session cookies
- 4.3 Document rollback procedure: move environment alias to previous SHA and redeploy without rebuild
- 4.4 Document PostgreSQL daily backup (≥14d retention), restore procedure, and test restore on staging before first production promotion
5. Deploy workflow and smoke
- 5.1 Create
.github/workflows/deploy-staging.ymlgated on successful CI onmain: build image, pushghcr.io/...:<sha>+:staging, trigger Dokploycompose.deploy - 5.2 Create
.github/workflows/promote-production.yml(workflow_dispatch+ confirmation): retag same digest as:production, deploy production stack, smoke - 5.3 Wire migrate-before-serve (Compose migrate service) and healthcheck on
/up - 5.4 Add post-deploy smoke script/job for
/up,/,/admin/loginreturning 200 - 5.5 Store orchestration secrets only in GitHub; Laravel/DB/R2/Resend only in Dokploy; ensure no secrets in image layers
6. Phase 0 exit evidence
- 6.1 Perform first successful staging deploy of a
mainSHA and capture evidence (workflow URL, smoke output) — run 31395107465 deployed7e68c0esuccessfully; smoke recorded/up,/and/admin/loginreturning HTTP 200. - 6.2 Verify rollback to previous SHA works once on staging
- 6.3 Update
SPEC.md§18 Fase 0 checkboxes only for items with evidence; note remaining deferred items if any — local runtime/auth/audit/coverage evidence was recorded by PR #39, and the staging exit criterion was subsequently marked complete from successful run 31395107465. - 6.4 Run full
composer qualityand confirm all five CI jobs + staging deploy path green — local quality evidence is recorded in task 2.4; PR #39 passedstatic,unit,feature,browserandcontainer, then run 31395107465 deployed that exact merge SHA and passed all three smoke endpoints. - 6.5 Report in SPEC §24 format; archive this change only after remaining parity tasks are complete — blocked by tasks 3.4 and 6.2, tracked separately in MAN-125.