docs(02): add Phase 2 context — admin auth, mutation pattern, client interactions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Simone Cavalli
2026-05-15 00:39:31 +02:00
parent c22457b9a7
commit 904849178d
@@ -0,0 +1,126 @@
# Phase 2: Admin Area & Interactive Features - Context
**Gathered:** 2026-05-15
**Status:** Ready for planning
<domain>
## Phase Boundary
Costruire l'area admin autenticata e le funzionalità interattive cliente. Al termine di questa fase:
- L'admin accede a `/admin` con credenziale sicura e gestisce tutti i dati
- Il cliente può approvare deliverable e lasciare commenti dalla sua dashboard
L'area admin non è mai accessibile al cliente — path separato con sessione Auth.js.
Service catalog e quote builder sono Phase 3. Claude AI è Phase 4.
</domain>
<decisions>
## Implementation Decisions
### Autenticazione Admin
- **D-01: Auth.js v4 (`next-auth@4`)** — versione stabile. La v5 è ancora in beta RC al 2026-05-15. Installare `next-auth@4` + `@auth/drizzle-adapter` non è necessario (singolo admin hardcoded, no DB table per utenti).
- **D-02: Credenziali admin via env vars** — Singolo admin: `ADMIN_EMAIL` + `ADMIN_PASSWORD` in `.env.local`. No tabella `users` in DB. CredentialsProvider di Auth.js valida contro le env vars, restituisce session con `{ id: "admin", email: ADMIN_EMAIL }`.
- **D-03: Sessione JWT** — Nessuna tabella session nel DB. JWT stateless firmato, scadenza 30 giorni. Non serve adapter.
- **D-04: Protezione route admin** — `src/proxy.ts` già gestisce `/c/[token]`. Aggiungere matcher `/admin/:path*` → redirect a `/admin/login` se no session. Il check sessione avviene nel middleware (getToken da next-auth/jwt) — nessun DB call per ogni request.
### Mutation Pattern
- **D-05: Server Actions** — Next.js 15/16 nativo. Nessuna API route separata per le operazioni admin CRUD. Il form chiama una Server Action → Drizzle scrive DB → `revalidatePath` aggiorna la pagina. Pattern consistente con l'uso di Server Components già stabilito in Phase 1.
- **D-06: API route solo per client interactions** — Le approvazioni e i commenti del cliente passano per API routes (non Server Actions) perché il contesto del client non ha session admin. Route pattern: `POST /api/client/approve` e `POST /api/client/comment` — validate token via header o cookie custom, non Auth.js.
### Admin UI Layout
- **D-07: Lista → dettaglio** — `/admin` → lista clienti con badge stato pagamenti. Click su cliente → `/admin/clients/[id]` con dettaglio completo.
- **D-08: Tabs per sezioni cliente** — Nella pagina dettaglio cliente, usare tabs: Panoramica | Fasi & Task | Documenti | Pagamenti | Commenti. shadcn non ha tabs installato — aggiungere `@radix-ui/react-tabs` + componente.
- **D-09: Sidebar assente in v1** — Nessuna sidebar globale. Nav minimal: logo + link "Clienti" + pulsante logout. Desktop-first ma responsive.
### Client Interactions (DASH-05, DASH-06)
- **D-10: Approvazione deliverable** — Pulsante "Approva" visibile solo se `approved_at` è null. Nessun modal di conferma — l'azione è semplice e l'approved_at immutabile basta come audit. POST a `/api/client/approve` con `{ deliverableId }`, token letto da cookie o URL (il token è già in `params` nel client route).
- **D-11: Commenti inline** — Textarea + pulsante "Invia" direttamente sotto task/deliverable. POST a `/api/client/comment`. Lista commenti sopra il form, ordinati per `created_at` asc. Autore mostrato come "Tu" (cliente) o "iamcavalli" (admin). No real-time — reload della pagina sufficiente in v1.
### Reusable Assets da Phase 1
- Schema DB: completo e non richiede modifiche. `comments`, `deliverables.approved_at`, `payments` già pronti.
- shadcn/ui installati: badge, button, card, input, label, select, table, textarea — usabili as-is.
- Drizzle ORM + postgres-js: pattern stabilito in Phase 1, stesso setup.
- Zod + react-hook-form: già installati, usare per tutti i form admin.
- `src/lib/client-view.ts`: già applica data isolation — non toccare per questa fase.
### Claude's Discretion
- Struttura esatta delle Server Actions (file naming: `actions.ts` per domain o singolo file)
- Ordine campi nei form admin (quale sequenza per nuovo cliente)
- Icone lucide-react per stati (quale icona per `da_saldare` / `inviata` / `saldato`)
- Colori badge admin (riutilizzare `--color-success`, `--color-warning`, `--color-info` da globals.css)
</decisions>
<canonical_refs>
## Canonical References
**Downstream agents MUST read these before planning or implementing.**
### Progetto & Requisiti
- `.planning/PROJECT.md` — Contesto progetto e decisioni chiave
- `.planning/REQUIREMENTS.md` — REQ-IDs Phase 2: ADMIN-01, ADMIN-02, DASH-05, DASH-06
- `.planning/ROADMAP.md` — Success criteria Phase 2
- `CLAUDE.md` — Architectural constraints LOCKED (token/PK separati, accepted_total, approved_at immutabile, due path auth)
### Codice Esistente
- `src/db/schema.ts` — Schema completo, nessuna modifica necessaria in Phase 2
- `src/proxy.ts` — Edge middleware esistente (aggiungere matcher admin)
- `src/lib/client-view.ts` — Data isolation layer (non toccare)
- `src/app/globals.css` — Design tokens e @source not directives
### Phase 1 Context
- `.planning/phases/01-foundation-client-dashboard/01-CONTEXT.md` — Decisioni D-04 (brand hardcoded), D-05 (light & clean), D-12 (note admin-only)
</canonical_refs>
<code_context>
## Existing Code Insights
### Reusable Assets
- `src/components/ui/`: badge, button, card, input, label, progress, select, separator, table, textarea — tutti pronti
- `src/db/schema.ts`: export types `Client`, `Phase`, `Task`, `Deliverable`, `Comment`, `Payment`, `Document`, `Note` — usare as-is
- `src/lib/utils.ts`: `cn()` utility da shadcn — riusare ovunque
### Pattern Stabiliti
- Server Components per fetch dati (nessun `useEffect`, nessun client-side waterfall)
- Drizzle query con `.innerJoin()` e `.where(eq(...))` — vedere `src/lib/client-view.ts`
- `revalidatePath` dopo mutazioni per aggiornare UI senza client state
### Integration Points
- `src/proxy.ts`: aggiungere `'/admin/:path*'` al matcher + logica `getToken` per redirect
- Client approval/comment: POST API routes che leggono token dal path URL del referrer o body request
### Package da Aggiungere
- `next-auth@4` — Auth.js per admin session
- `@radix-ui/react-tabs` + shadcn tabs component — per tabs nella pagina dettaglio cliente
- `@radix-ui/react-dialog` + shadcn dialog — per eventuali modali (confirm delete, ecc.)
</code_context>
<deferred>
## Deferred Ideas
- **Brand customization panel** (colori, logo admin) → Phase 3+ o post-roadmap
- **Sidebar globale** → non necessaria con lista→dettaglio in v1
- **Real-time commenti** (WebSocket/polling) → v2, non v1
- **Multi-admin / ruoli** → fuori scope (singolo admin in tutta la roadmap)
- **Password change UI** → non necessaria (env var, admin solo)
</deferred>
---
*Phase: 2 — Admin Area & Interactive Features*
*Context gathered: 2026-05-15*