Skip to content

Project Structure

Michel edited this page Mar 29, 2026 · 2 revisions

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.

High-Level Layout

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

Frontend — React 19 SPA

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

Key Frontend Conventions

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.

Backend — Express API

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

Request Flow

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.

API Response Format

// 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" });

Database

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.

AI System Files

.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

.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.

Tests

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).

Clone this wiki locally