Architecture Overview
Dictumal is a full-stack Next.js application that uses AI to help users draft and enforce personal computing constitutions.
Tech Stack
| Layer | Technology |
|---|---|
| Framework | Next.js (App Router) |
| Language | TypeScript |
| Styling | Tailwind CSS + shadcn/ui |
| Database | PostgreSQL via Prisma ORM |
| Authentication | NextAuth.js (Google OAuth) |
| AI | OpenRouter API (Anthropic Claude) |
| Cloud Deploy | DigitalOcean Droplets |
| Hosting | Vercel |
Directory Structure
dictumal/
prisma/
schema.prisma # Database schema
migrations/ # Prisma migrations
src/
app/
api/ # API route handlers
auth/ # NextAuth endpoints
chat/ # AI chat streaming
chat-sessions/ # Chat session CRUD
clauses/ # Clause CRUD + history
constitutions/ # Constitution CRUD
deployments/ # Deploy + status + preview
export/ # Multi-format export
...
constitution/[id]/ # Constitution view + draft pages
dashboard/ # User dashboard
docs/ # Documentation (you are here)
login/ # Auth page
components/
constitution/ # Clause cards, history, deploy dialog
docs/ # Docs sidebar
ui/ # shadcn/ui primitives
lib/
ai/ # OpenRouter client + prompts
deploy/ # DigitalOcean, cloud-init, domain extraction
auth.ts # NextAuth configuration
prisma.ts # Prisma client singletonKey Design Decisions
Server Components by Default
Pages are server components wherever possible, fetching data directly from Prisma. Client components are used only for interactive UI elements like the chat interface, deploy dialog, and sidebar navigation.
AI-Powered Drafting
The chatbot uses OpenRouter (Anthropic Claude) with carefully crafted system prompts for each drafting mode. Responses are streamed to the client using the Web Streams API for real-time display.
Structured Clause Data
Each clause stores both a naturalLanguage description and a structured irData (intermediate representation) JSON field. This allows the same clause to be displayed to users in plain language while being machine-parseable for enforcement.
Chat Session Persistence
Every conversation is persisted as a ChatSession with a JSON messages field. Sessions are linked to clauses via a junction table (ChatSessionClause) with a relation type (ORIGIN, AMENDMENT, REFERENCE), enabling full traceability.
Streaming Deployment Path
Deployment is implemented as a server-driven state machine:PROVISIONING -> CONFIGURING -> ACTIVE. The status route polls DigitalOcean and readiness probes for VNC/Guacamole/HTTPS before promoting to active.
Browser launch is handled by /api/deployments/[id]/launch, which issues a redirect to Guacamole with an encrypted short-lived token.
Core files: src/app/api/deployments/**, src/lib/deploy/digitalocean.ts, src/lib/deploy/cloud-init.ts, src/lib/deploy/guacamole-json-auth.ts.