-
Notifications
You must be signed in to change notification settings - Fork 0
Project Structure
Draft v0 is a full-stack TypeScript monorepo with a React 19 frontend and an Express backend, sharing the same repository and type system.
draft_v0/
├── src/
│ ├── client/ # React 19 SPA (Vite dev server)
│ └── server/ # Express API (Node.js)
├── prisma/ # Database schema and migrations
├── e2e/ # Playwright end-to-end tests
├── docs/ # Documentation (guides, ADRs)
├── .tasks/ # File-based task management
├── .github/ # Skills, agents, prompts, instructions
├── .claude/ # Rules, skills (mirrored from .github)
└── .vscode/ # Editor settings, MCP server config
src/client/
├── routes/ # TanStack Router file-based routes
│ ├── __root.tsx # Root layout (wraps all pages)
│ └── index.tsx # Home page route (/)
├── components/
│ └── ui/ # Custom UI components (Button, Typography)
├── lib/
│ ├── utils/ # Utility functions
│ └── query-client.ts # TanStack Query client config
├── hooks/ # Custom React hooks
├── main.tsx # App entry point
├── index.css # DSAi + Bootstrap import chain
├── custom.css # App-specific style overrides
└── routeTree.gen.ts # AUTO-GENERATED — never edit
src/collections/ # DSAi design token source (JSON)
├── color/ # Color palettes, semantic, neutral, etc.
├── typography/ # Font sizes, weights, line heights
├── spacing/ # Spacing scale
├── layout/ # Breakpoints, containers, grid
├── shadow/ # Box shadow definitions
└── border/ # Border radius and width
src/generated/ # Built token outputs (do not edit)
├── css/ # CSS custom properties + Bootstrap theme
├── scss/ # SCSS variables
├── js/ # CommonJS token module
├── ts/ # TypeScript definitions
└── json/ # Raw token JSON
src/scss/ # SCSS source files
├── dsai-theme-bs.scss # Bootstrap theme mapping
├── _variables.scss # Generated SCSS variables
├── _variables-dark.scss # Dark mode variables
└── _mixins.scss # Shared mixins
File-based routing — Create a file in src/client/routes/ and it becomes a route automatically. The routeTree.gen.ts is auto-generated and must never be edited manually.
// src/client/routes/about.tsx → becomes the /about route
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/about")({
component: AboutPage,
});
function AboutPage() {
return <div className="container py-4">About</div>;
}Path aliases:
-
@/*→src/client/*— use for all client-side cross-module imports -
@server/*→src/server/*— use for server-side imports
Styling — Components use Bootstrap 5.3 utility classes and --dsai-* CSS custom properties. Design tokens live in src/collections/ and are built to src/generated/ via pnpm tokens:build.
Data fetching — Always use useQuery() / useMutation() from TanStack Query. Never use useState + useEffect for server data.
src/server/
├── routes/ # HTTP route definitions
│ ├── index.ts # Route mounting (/api/...)
│ └── users.ts # /api/users routes
├── controllers/ # Request parsing, response sending
│ └── user.controller.ts
├── services/ # Business logic
│ └── user.service.ts
├── repositories/ # Prisma queries, data access only
│ └── user.repository.ts
├── lib/
│ └── prisma.ts # Prisma client singleton
└── index.ts # Express app entry point
Every API request follows the same layered path:
HTTP Request
↓
Route → Maps URL + HTTP method to a controller function
↓
Controller → Parses request body/params, calls service, sends response
↓
Service → Business logic, throws typed custom errors
↓
Repository → Prisma queries only, returns data to service
↓
Prisma (SQLite) → Database
Each layer has one job and never skips a layer. Controllers do not query the database. Repositories do not have business logic.
// Success
res.status(200).json({ data: result });
res.status(201).json({ data: created });
// Error
res.status(400).json({ error: "Bad Request", message: "Details here" });
res.status(404).json({ error: "Not Found", message: "Resource not found" });
res.status(409).json({ error: "Conflict", message: "Already exists" });
res.status(500).json({ error: "Internal Server Error" });prisma/
├── schema.prisma # Prisma schema — models, relations, constraints
└── dev.db # SQLite database file (git-ignored)
Schema changes: edit prisma/schema.prisma, then run pnpm db:push.
.github/
├── instructions/ # Global AI instructions (always active)
│ ├── copilot-instructions.md
│ ├── orchestrator.instructions.md
│ └── *.instructions.md
├── skills/ # 17 domain-specific AI skills
│ └── <skill-name>/
│ └── SKILL.md
├── agents/ # 8 specialized AI agents
│ └── <agent-name>.agent.md
└── prompts/ # 12 reusable prompt templates
└── <name>.prompt.md
.claude/
├── rules/ # 7 always-on convention rules
│ └── *.md
└── skills/ # Mirror of .github/skills/ for Claude
See AI Overview, Skills Reference, and Agents Reference for detail.
.tasks/
├── _template.md # Task template
├── backlog/ # Tasks not yet started
├── in-progress/ # Tasks being worked on
├── done/ # Verified and completed tasks
└── cancelled/ # Abandoned tasks with reasons
See Tasks Workflow for the full lifecycle.
e2e/
└── *.spec.ts # Playwright end-to-end tests
Unit tests live alongside source files with .test.ts suffix. Run with pnpm test (Vitest) or pnpm test:e2e (Playwright).