# PROMPTS.md — Claude Code CLI Prompt Sequence

Copy-paste these prompts into Claude Code **one at a time, in order**. Do not
start a prompt until the previous one's acceptance criteria are green and you
have committed the work.

**Setup first (once):** copy `CLAUDE.md` to the Laravel project root and the
`docs/` folder alongside it, so every session can read them.

```
your-laravel-project/
├── CLAUDE.md
├── docs/            ← the whole docs folder from this package
├── app/ ...
```

---

## PROMPT 0 — Phase 0: Foundation, Branding & Auth Rework

```
Read CLAUDE.md fully, then docs/02-ARCHITECTURE.md, docs/03-DATA-MODEL.md,
docs/04-SECURITY.md, docs/05-UI-UX.md, and docs/modules/M01-foundation.md.
Then inspect the current state of this Laravel project before changing anything:
it already has default auth scaffolding (login, register, dashboard) and an
admin template installed — inventory what exists first.

Then implement Phase 0 (module M01) in this order:

1. TEMPLATE MAP: inspect the installed template's real components and produce
   docs/05a-TEMPLATE-MAP.md documenting its buttons, cards, tables, form
   controls, modals, badges, tabs, toasts, chart library, and empty-state
   pattern. All future UI is built ONLY from these primitives.

2. BRANDING: implement the locked brand palette from docs/05-UI-UX.md §8 as
   CSS custom properties (and Tailwind config mapping if the template uses
   Tailwind): Gold #F5B800, Gold Light #FFD54F, Gold Muted #B8891A, Charcoal
   #1E1E1E, Charcoal 2 #2D2D2D, Off-white #F9F5EC, Text Light #E8E0CC, Text
   Muted #A09070. Restyle the template shell (sidebar, top bar, cards,
   buttons, links, focus rings) to the dark gold-on-charcoal theme. Body text
   is Text Light, never gold; gold is for accents, headings and interactive
   elements only. Apply this to the login page and current dashboard so the
   theme is visible immediately.

3. AUTH REWORK: the default scaffolding needs changing to match M01:
   - REMOVE public registration entirely (route, controller, links, view) —
     this system is invite-only; users are created by an admin invite that
     emails a signed, expiring set-password link.
   - Keep login but add: rate limiting (5 attempts per email+IP with lockout),
     session regeneration on login, and the password policy (min 12 chars).
   - Add TOTP 2FA (enrolment, challenge on login, hashed recovery codes) and
     an EnforceTwoFactor middleware for permission groups flagged requires_2fa.
   - Restyle all auth pages to the brand palette.

4. TENANCY & CORE: firms migration/model/seeder (seed one firm), FirmScope
   global scope + BelongsToFirm trait + CurrentFirm service, ULIDs on all new
   models, settings table + SettingsService (cached), number_sequences +
   NumberingService (write the concurrency test FIRST: parallel calls must
   never produce duplicate numbers).

5. RBAC: install spatie/laravel-permission with teams mode on firm_id. Seed
   the complete permission matrix and default roles exactly as listed in
   docs/modules/M01-foundation.md. Wire permission middleware.

6. ADMIN SCREENS: offices CRUD and all reference-data CRUD (courts,
   practice_areas, matter_stages, contact_categories, document_types),
   following the list/form page patterns in docs/05-UI-UX.md, plus user
   management (invite, suspend, force-logout, 2FA reset with logged reason).

7. SECURITY SCAFFOLDING: SecurityHeaders middleware (CSP, X-Frame-Options
   DENY, X-Content-Type-Options, Referrer-Policy), activitylog wired on all
   new models, and the ROUTE-AUDIT Pest test that fails whenever any route
   lacks permission middleware (allow-list: login, logout, 2FA challenge,
   health check).

8. REBUILD THE DASHBOARD as a placeholder "My Day" shell in the new theme
   (real widgets come in Phase 5) — a branded page with empty-state cards is
   enough for now.

Work test-first where the spec says so. When done, run php artisan test,
./vendor/bin/pint, and ./vendor/bin/phpstan analyse, verify every M01
acceptance criterion in docs/modules/M01-foundation.md, update
docs/00-INDEX.md status, and give me a summary of what changed plus anything
you had to deviate on.
```

---

## PROMPT 1 — Phase 1: Contacts, Clients & Matters (M02 + M03)

```
Read CLAUDE.md, docs/00-INDEX.md (confirm M01 is done), then
docs/modules/M02-contacts-clients.md and docs/modules/M03-matters.md, and the
API shapes in docs/readmes/M02-contacts-clients-README.md and
docs/readmes/M03-matters-README.md.

Implement M02 first, then M03, per their specs:
- M02: contacts, clients, client_contacts, conflict_checks migrations →
  models → ConflictCheckService (test first with overlapping names across
  contacts, matter parties, opposing counsel) → controllers/views per the
  UI patterns → NDPR client data export → Pest tests (CRUD, conflict check,
  cross-firm isolation, permission denial).
- M03: matters + matter_team + matter_parties + matter_events +
  matter_comments → enums → Matter model with the visibleTo() scope and
  MatterObserver → RegisterMatter Action (test concurrency-safe numbering and
  the minimum-one-team-member rule first) → controllers → the tabbed matter
  detail page WITH placeholder tabs for Hearings/Tasks/Billing/Documents
  (later phases fill them) → Pest tests.

Everything styled to the brand palette using only components from
docs/05a-TEMPLATE-MAP.md. Matters index gets the full list-page pattern:
KPI strip, filter bar, data table with status badges per the badge color
convention. Finish with tests + pint + phpstan green, all M02 and M03
acceptance criteria verified, docs/00-INDEX.md updated.
```

---

## PROMPT 2 — Phase 2: Litigation & Tasks (M04 + M05)

```
Read CLAUDE.md, confirm M02+M03 done in docs/00-INDEX.md, then
docs/modules/M04-litigation.md, docs/modules/M05-tasks.md and their
readmes/ counterparts.

Implement M04 Part A (hearings + witnesses/testimonies + the
RecordHearingOutcome Action with the transactional adjournment chain), then
Part B (roster: hearing_attendances, RosterService clash detection, roster
board view, signed iCal feed, queued PDF daily cause list), then Part C
(the deadline & limitation engine — write the reminder idempotency test on
deadline_reminders_sent FIRST, then the scheduled command; add the red
banner on matter pages for deadlines within 14 days, independent of the
notification pipeline).

Then M05: task_templates + tasks + task_comments →
GenerateTasksFromTemplate Action (test offset and assignee-role resolution)
→ wire auto-generation into RegisterMatter → views (My Tasks +
matter Tasks tab, replacing its placeholder).

This phase is the highest-liability code in the system — do not skip the
adjournment-chain rollback test, the reminder-idempotency test, or the
clash-warning test. Finish with the usual green checks, acceptance criteria
verified, index updated.
```

---

## PROMPT 3 — Phase 3: Time, Billing & Finance (M06 + M07)

```
Read CLAUDE.md, confirm Phase 2 done, then docs/modules/M07-finance.md
FIRST (M06 depends on its LedgerService), then docs/modules/M06-time-billing.md,
plus both readmes.

Build in this order:
1. M07 core: chart of accounts seeder (respect the code ranges) →
   LedgerService (balance-invariant test first: unbalanced postings must be
   rejected; it is the ONLY writer to journal_lines) → journals read +
   reverse routes → bank accounts.
2. M07 trust: RetainerService — write the concurrent-overdraw test BEFORE
   implementing (two simultaneous drawdowns against a balance that covers
   only one: exactly one succeeds). Deposit/drawdown/refund with correct
   DR/CR postings per the spec.
3. M06: fee_arrangements → time_entries (unbilled-locking test first) →
   invoice generation Action (unit-test the VAT/WHT math with fixed figures
   from firm settings before any UI) → receipts + allocation posting through
   LedgerService → invoice/receipt PDFs on the Off-white print layout.
4. M07 appearance fees: scales → claims → AppearanceFeeClaimPolicy
   (self-approval structurally blocked, test first) → payBatch → wire the
   claim suggestion into M04's attended hearings.
5. The matter Billing tab (replacing its placeholder): fee arrangement,
   unbilled time, invoices, receipts, retainer balance, outstanding.
6. Aging + profitability + trial-balance queries (surfaced fully in Phase 5)
   with the standing invariant test that the trial balance nets to zero
   after a scripted sequence of all the above operations.

Money is decimal(18,2) everywhere, ₦-formatted right-aligned in UI. Finish
with green checks, acceptance criteria for both modules, index updated.
```

---

## PROMPT 4 — Phase 4: Documents & Communication (M08 + M09)

```
Read CLAUDE.md, confirm Phase 3 done, then docs/modules/M08-documents.md and
docs/modules/M09-communication.md plus both readmes.

M08 first: install spatie/laravel-medialibrary on a PRIVATE disk →
documents model + DocumentPolicy (write the three-tier confidentiality test
first, including the privileged ethical-wall allow-list) → UploadNewVersion
Action (append-only, sha256 per version) → authorized streamed download
controller with activity logging → search filtered at query level by
confidentiality → evidence register + queued exhibit-list PDF →
document-generation templates (engagement letter, hearing notice, invoice
cover, receipt) rendering on the Off-white print layout with gold heading
accents → replace the matter Documents tab placeholder.

Then M09: announcements + acknowledgement flow + read/ack matrix →
message threads (polled unread count, no websockets) → wire notification
classes for every domain event fired so far (MatterRegistered, HearingHeld,
deadline reminders, InvoiceSent, fee claim transitions, matter comments) →
notification centre grouped by type → SMS channel behind feature('sms') with
a provider-agnostic adapter (Termii primary) → daily digest command with the
own-items-only test and the never-send-empty test.

Green checks, acceptance criteria, index updated.
```

---

## PROMPT 5 — Phase 5: Dashboards, Reports & Admin (M10 + M12)

```
Read CLAUDE.md, confirm Phase 4 done, then docs/modules/M10-reporting.md and
docs/modules/M12-people-admin.md plus both readmes.

M10: build every dashboard widget as a plain-array service method with a
unit test BEFORE any view. Executive dashboard leads with the attention
panel (missed appearances, outcome-less hearings, deadlines ≤14 days,
overdue invoices, pending approvals), then KPIs and charts — chart series
use the brand palette (gold, gold muted, text muted + semantic status
colors), never library defaults. Replace the Phase 0 placeholder dashboard
with the real "My Day" page (mobile-first, verified at 390px). Matter
health grid backed by a single MatterHealthQuery service. Then the report
library: all seven reports with HTML preview + queued PDF/Excel via
report_runs, and ClientMatterReportService as the single sanitized source
(explicit test: zero internal remarks or comments in its output).

M12: staff records (seniority feeding M07 fee scales) → leave requests with
the roster "unavailable" warning wired into M04 assignment → audit review
screen over activity_log + security events → backups UI wrapper
(spatie/laravel-backup, nightly schedule, stale-backup banner past 48h) →
import wizards (template download → validation preview → transactional
commit) for legacy matters/clients/hearings → /admin/system health page.
Leave payroll unbuilt behind feature('payroll').

Green checks, acceptance criteria for both modules, index updated.
```

---

## PROMPT 6 — Phase 6: Client Portal (M11)

```
Read CLAUDE.md, confirm Phase 5 done, then docs/04-SECURITY.md §6 again in
full, docs/modules/M11-client-portal.md and
docs/readmes/M11-client-portal-README.md.

TESTS FIRST, before any portal view exists:
- The full IDOR suite: for every planned portal route, portal user of
  Client A requesting Client B's ulid gets 404 (never 403).
- The guard-confusion test: the portal guard can never resolve a staff User.
- The confidentiality hard-block test: ShareDocumentWithClient called
  directly on a confidential/privileged document throws, regardless of UI.

Then build: portal guard + portal_users + staff-side grant/disable with
signed expiring invites → PortalController base injecting client_id scoping
→ portal layout in the brand palette but the calmer variant per
docs/05-UI-UX.md §8 (more Off-white surfaces, gold reserved for the primary
action and logo) → dashboard/matters/invoices/receipts/documents pages, all
read-only, all through dedicated Portal DTOs and ClientMatterReportService →
shared_documents flow with the staff-side share action → portal_requests
notifying assigned lawyers. Rate-limit all portal POSTs; neutral error
messages on login per the README (disabled account indistinguishable from
wrong password).

Green checks, every M11 acceptance criterion, index updated.
```

---

## PROMPT 7 — Phase 7: Hardening & Performance

```
Read CLAUDE.md and docs/06-DEVELOPMENT-PLAN.md Phase 7, plus the full
security checklist in docs/04-SECURITY.md §10.

Execute the hardening pass: verify every checklist item and fix what fails —
route-audit green, policy coverage on every sensitive model, cross-firm
isolation suites green, portal IDOR suite green, 2FA enforced on privileged
roles, security headers on all responses, composer audit clean. Then
performance: seed a realistic large dataset (10k matters, 50k hearings, 20k
invoices), click-audit every list page for N+1 (preventLazyLoading must be
on), verify indexes are used on the hot queries from docs/03-DATA-MODEL.md
§6 (EXPLAIN the matter list, roster, aging, deadline scan), confirm all
queued jobs have retries/backoff and failed-job alerting. Tighten the CSP.
Produce a written hardening report at docs/07-HARDENING-REPORT.md listing
each checklist item, its status, and what was fixed.
```

---

## PROMPT 8 — Phase 8: UAT Prep & Go-Live

```
Read docs/06-DEVELOPMENT-PLAN.md Phase 8. Prepare go-live: production .env
review checklist, backup schedule verified plus a documented restore drill
(actually perform one against a scratch database and record the steps and
timing in docs/08-RESTORE-DRILL.md), demo/UAT seed data (a realistic firm:
8 staff across roles, 25 clients, 40 matters at varied stages, hearings past
and future, deadlines, invoices in every status, retainer balances), and
generate per-module quick-reference user guides into docs/user-guides/ (one
page each, plain English, matching the actual UI). Finish with a go-live
checklist document at docs/09-GO-LIVE-CHECKLIST.md.
```

---

## Tips for running these

- **One prompt per session.** If a session ends mid-phase, start the next
  with: *"Read CLAUDE.md and docs/00-INDEX.md, inspect the current code state,
  and continue Phase N from where it stopped — verify what's already done
  against docs/modules/MXX before writing anything new."*
- **Commit per module**, tag per phase (`v0.1-foundation`, `v0.2-matters`, …).
- If Claude Code proposes deviating from a spec, make it state the conflict
  and the reason in its summary — then update the spec doc if you accept it,
  so docs and code never drift apart.
