2.1 KiB
ClientHub — Project Instructions
Project
ClientHub — Portale clienti per consulente di personal branding.
- Dashboard cliente via link segreto (no login)
- Admin area per gestione clienti, fasi, task, deliverable, pagamenti
- Deploy: Vercel su
welcomeclient.iamcavalli.net
GSD Workflow
This project uses the Get Shit Done workflow. Planning lives in .planning/.
Current State
See .planning/STATE.md for current phase and active work.
See .planning/ROADMAP.md for full phase structure.
See .planning/REQUIREMENTS.md for all requirements with REQ-IDs.
Phase Execution
- Run
/gsd-plan-phase Nto plan a phase before executing - Run
/gsd-execute-phase Nto execute a planned phase - Run
/gsd-progressto check current status
Architecture Constraints
The following decisions are LOCKED from the data model and must be respected in all phases:
-
clients.tokenis a separate rotatable field — NEVER the primary key. Clients have a stable UUIDidand a separatetokenfield used for secret link access. Rotation = single UPDATE ontoken. -
Client API never exposes
quote_items. Theaccepted_totalfield on theclientsrow is the only price the client API returns. Quote line items are admin-only. Enforced at the query layer, not the UI. -
deliverables.approved_atis immutable. Once set, it cannot be unset by the client. Admin-only override only if strictly necessary. -
Two independent auth paths:
/c/[token]/*→ Next.js Middleware validates token against DB, 404 on miss/admin/*→ Auth.js Credentials session check
-
No file hosting in v1. Documents are external URLs (Google Drive, PDF links) stored as text.
Stack
Next.js 15 (App Router) · Neon (serverless Postgres) · Drizzle ORM · Auth.js v4 · nanoid · Tailwind v4 · shadcn/ui · Zod · React Hook Form
Security
- Client tokens: cryptographically random via
nanoid(21 chars, ~126 bit entropy). Never derived from client name or sequential ID. - Admin area: protected by Auth.js session before Phase 2 ships to production.
- Payment privacy:
quote_itemsnever returned by client-facing API routes.