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:
@@ -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*
|
||||||
Reference in New Issue
Block a user