Files
Simone Cavalli feede57c05 docs(02-02): complete admin client list and create-client plan summary
- Covers Task 1 (admin-queries, NavBar, layout) and Task 2 (admin page, ClientRow, new client form + Server Action)
2026-05-15 19:55:19 +02:00

6.3 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
02-admin-area-interactive-features 02 ui
nextjs
server-actions
drizzle
shadcn
zod
nanoid
tailwind
phase provides
02-01 Auth.js session guard protecting all /admin/* routes via middleware
Admin client list at /admin with payment status badges (Acconto/Saldo per client)
New client creation form at /admin/clients/new with Server Action
Automatic payment stub creation (Acconto 50% + Saldo 50%) on client insert
ClientWithPayments query type and getAllClientsWithPayments() utility
Admin layout with NavBar (ClientHub logo, Clienti link, Esci logout button)
02-03
02-04
client-detail page (Plan 03 will build /admin/clients/[id])
added patterns
Server Components for admin data pages (no client state, no useEffect)
Server Actions with Zod validation for form mutations (D-05)
revalidatePath('/admin') + redirect after mutation
nanoid token generated server-side via $defaultFn — never user-supplied
Two-query fetch pattern: clients then payments, merged in-memory (avoids JOIN complexity)
created modified
src/lib/admin-queries.ts
src/components/admin/NavBar.tsx
src/app/admin/layout.tsx
src/components/admin/ClientRow.tsx
src/app/admin/page.tsx
src/app/admin/clients/new/page.tsx
src/app/admin/clients/new/actions.ts
Zod validates createClient input server-side before any DB write — malformed input throws cleanly with no partial inserts
Payment stubs inserted immediately on client creation with amount=0 and status=da_saldare — amounts updated separately by admin
Token is $defaultFn(() => nanoid()) — server-generated, never derived from user input, satisfies T-02-08
Admin page uses revalidate=0 to always fetch fresh data — admin operations require real-time list
Two-query pattern (clients + payments) merged in-memory chosen over Drizzle relations JOIN for simplicity at this scale
Server Action pattern: 'use server' + Zod schema + db.insert + revalidatePath + redirect
ClientRow: presentational component receiving ClientWithPayments, no data fetching
Badge variant mapping: da_saldare=destructive, inviata=secondary, saldato=default
ADMIN-01
ADMIN-02
30min 2026-05-15

Phase 02 Plan 02: Admin Client List + Create Client Summary

Admin home shows all clients with Acconto/Saldo payment badges; new client form inserts client row + two payment stubs via Zod-validated Server Action with nanoid token auto-generation

Performance

  • Duration: ~30 min
  • Started: 2026-05-15
  • Completed: 2026-05-15
  • Tasks: 2 (Task 1 pre-committed, Task 2 executed in this run)
  • Files modified: 7

Accomplishments

  • Admin dashboard at /admin renders all clients in a table with name, brand, totale, Acconto badge, Saldo badge, and truncated secret link
  • Empty state renders gracefully with a link to create the first client
  • /admin/clients/new form with nome, brand, brief fields wired to createClient Server Action
  • createClient validates with Zod, inserts client row (token auto-generated by nanoid), inserts Acconto 50% + Saldo 50% payment stubs, revalidates /admin, redirects to /admin/clients/[id]
  • Admin layout wraps all /admin/* pages with NavBar showing "ClientHub" + "Clienti" link + "Esci" logout button

Task Commits

  1. Task 1: Create admin-queries.ts, NavBar, and admin layout - 7029583 (feat)
  2. Task 2: Admin client list page and create-client flow - f77051a (feat)

Plan metadata: (docs commit follows)

Files Created/Modified

  • src/lib/admin-queries.ts - getAllClientsWithPayments() and getClientById() query utilities; ClientWithPayments type
  • src/components/admin/NavBar.tsx - Client component with logo, Clienti nav link, signOut button
  • src/app/admin/layout.tsx - Layout wrapper applying NavBar to all /admin/* pages
  • src/components/admin/ClientRow.tsx - Table row with payment status Badge components and secret link
  • src/app/admin/page.tsx - Server Component fetching all clients; renders table or empty state
  • src/app/admin/clients/new/page.tsx - Form page (Server Component) wired to createClient action
  • src/app/admin/clients/new/actions.ts - Server Action: Zod validation + db.insert(clients) + db.insert(payments) x2

Decisions Made

  • Zod validates createClient input before any DB operation — malformed input throws a clean error with no partial writes
  • Payment stubs created with amount: "0" — amounts set later by admin via separate update flow (Plan 03)
  • revalidate = 0 on /admin page ensures admin always sees fresh data after mutations
  • Token is entirely server-generated ($defaultFn(() => nanoid())) — user cannot supply or influence it (T-02-08 mitigated)

Deviations from Plan

None - plan executed exactly as written.

Issues Encountered

None. Build passed cleanly (existing CSS warning is pre-existing and unrelated to this plan).

Known Stubs

  • /admin/clients/[id] — redirect destination after client creation. The route does not exist yet; Next.js will render a 404 until Plan 03 builds the client detail page. This is explicitly noted in the plan as acceptable at this stage ("stub until Plan 03").

Threat Surface Scan

All threats in the plan's threat register are addressed:

Threat ID Disposition Status
T-02-06 mitigate Zod validates createClient before any DB write
T-02-07 mitigate /admin/* protected by 02-01 middleware session guard
T-02-08 mitigate Token is $defaultFn(() => nanoid()), never user-supplied
T-02-09 accept Token shown truncated in UI; full token only via /c/[token] link

No new security surfaces introduced beyond the threat model.

Next Phase Readiness

  • /admin client list and /admin/clients/new are fully functional end-to-end
  • createClient Server Action is the canonical pattern for future admin mutations
  • Plan 03 can build /admin/clients/[id] detail page using getClientById() already exported from admin-queries.ts
  • Payment stub amounts need an update flow (Plan 03 or later)

Phase: 02-admin-area-interactive-features Completed: 2026-05-15