- Introduction
- Pitch
- Hogwarts
- Live Demo
- MVP
- Roadmap
- Launch Sprint
- PRD
- Get Started
- Localhost
- Architecture
- Structure
- Pattern
- Page
- Layout
- Content
- Types
- Config
- Actions
- Queries
- Authorization
- Validation
- Form
- Table
- Detail
- Card
- Util
- Hooks
- List Params
- Views
- README.md
- ISSUE.md
- Technology Stack
- Database
- File
- CDN Assets
- Entry Points
- Dashboard
- Authentication
- Credentials
- OAuth
- Flow Diagrams
- Multi-Tenancy
- Offline
- Onboarding
- Onboarding Videos
- Add Values
- Admission
- Application
- Attendance
- Compliance
- Profile
- Exams
- Exam Wizard
- Timetable
- Classrooms
- Notifications
- Conference
- LMS (Lumos)
Finance
- Finance
- Fee Management
- Invoice
- Wallet
- Salary
- Payroll
- Timesheet
- Expenses
- Budget
- Receipt
- Accounts
- Banking
- Reports
- Dashboard
- Permissions
- Messages
- Integration Flow
- Provision
- AI Document Processing
- Document Intelligence
- Internationalization
- Translation
- Translation Guide
- Icons
- Docs Factory
- Inspiration
- Listings
- Teachers
- Students
- Catalog
- Library
- Contributing
- Code of conduct
- GitHub Workflow
- Database Seeds
- Database Safety
- Test Accounts
- Playwright
- Prettier
- Block Rebound
Sales & GTM
types.ts holds DTOs, row shapes, form-step props, and component contracts for a feature. Never duplicated in content.tsx, columns.tsx, or actions.ts.
Categories
| Category | Shape | Reference |
|---|---|---|
| DTO + Row + FormProps | Compact listing types from Zod schemas (20–60 lines) | listings/teachers/types.ts |
| Prisma extension | Extends Prisma models with relations using & | finance/payroll/types.ts |
| Comprehensive domain | Full coverage — data, filters, sort, props, responses | saas-dashboard/tenants/types.ts |
| Component props | Pure React contracts (no DB, no Prisma) | atom/<name>/types.ts |
Rules
| # | Rule |
|---|---|
| 1 | Single source of truth — share via src/lib/types.ts if cross-feature |
| 2 | PascalCase for types, interfaces, enums |
| 3 | Derive from Zod with z.infer — never hand-write a schema mirror |
| 4 | Extend Prisma with Prisma.XxxGetPayload<{ include }>, never retype 90 fields |
| 5 | Prisma.XxxWhereInput stays in queries.ts / actions.ts |
| 6 | Stay under ~300 lines — split into types/student.ts etc. |
| 7 | Import canonical ActionResponse from @/lib/action-response |
Canonical example — DTO + Row + FormProps
import type { Teacher } from "@prisma/client"
import { z } from "zod"
import { teacherCreateSchema, teacherUpdateSchema } from "./validation"
export type TeacherDto = Pick<
Teacher,
"id" | "firstName" | "lastName" | "email" | "phone"
>
export type TeacherRow = TeacherDto & {
classCount: number
subjects: string[]
}
export type TeacherCreateInput = z.infer<typeof teacherCreateSchema>
export type TeacherUpdateInput = z.infer<typeof teacherUpdateSchema>
export interface TeacherFormProps {
initialData?: TeacherDto
onSuccess?: () => void
}Prisma extension
import type { Prisma } from "@prisma/client"
export type PayrollWithRuns = Prisma.PayrollGetPayload<{
include: {
runs: { include: { lines: true } }
school: { select: { id: true; name: true; currency: true } }
}
}>Anti-patterns
- Duplicate
ActionResponse(38+ files) — import from@/lib/action-response. ExtendedUserredefined (5 files) — canonical issrc/components/auth/user.ts.PaginationParamsredefined (10+ files) — lift tosrc/lib/types.ts.- Hand-written Prisma replicas —
registration/types.tshad 486 lines retyping aStudent. UsePrisma.StudentGetPayload<...>. - Row types diverging from columns — update
types.ts, notcolumns.tsx. anyin types.ts (26 occurrences) — replace with inferred Zod or Prisma payload.- Inline type defs in
content.tsx(268),columns.tsx(80),actions.ts(110) — move totypes.ts. - Identical type files in different features — extract to
src/lib/types.ts.
Naming
- File:
types.ts. - Suffix-coded:
<Name>Dto,<Name>Row,<Name>Input,<Name>Props,<Name>Response,<Name>Filters. - One concept per name.