- 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
config.ts holds enum option arrays, labels, defaults, and metadata. Pure data — no functions, no Prisma imports, no React.
Categories
| Category | Shape | Reference |
|---|---|---|
| Form step definitions | STEPS, STEP_FIELDS, TOTAL_FIELDS for wizards | listings/teachers/config.ts |
| Constants with labels | Option arrays, status badges, color maps | saas-dashboard/tenants/config.ts |
| Navigation maps | Sidebar / header / footer items with RBAC | template/platform-sidebar/config.ts |
| Feature-rich domain | Limits, rules, defaults | school-dashboard/dashboard/config.ts |
| Infrastructure | Framework configs (Next, NextAuth, AI) | auth.config.ts, next.config.ts |
Rules
| # | Rule |
|---|---|
| 1 | as const for literal type inference |
| 2 | Named exports only (NextAuth's auth.config.ts is the framework exception) |
| 3 | No circular imports — lift shared shapes to src/lib/config/ |
| 4 | No utility functions — formatFileSize() belongs in util.ts |
| 5 | No type definitions — types belong in types.ts |
| 6 | No raw process.env — read via @/env.mjs |
| 7 | Stay under ~300 lines — split when bloated |
Canonical example
import type { Prisma } from "@prisma/client"
export const GENDER_OPTIONS = [
{ value: "MALE", label: "Male" },
{ value: "FEMALE", label: "Female" },
] as const
export const STATUS_OPTIONS = [
{ value: "ACTIVE", label: "Active", variant: "default" },
{ value: "TRANSFERRED", label: "Transferred", variant: "secondary" },
{ value: "GRADUATED", label: "Graduated", variant: "success" },
] as const
export const PAGE_SIZE_OPTIONS = [10, 20, 50, 100] as const
export const DEFAULT_FILTERS: Prisma.StudentWhereInput = { active: true }i18n
Configs hold values; the dictionary owns translation. UI looks up the translated label using the value as a key:
const genderLabel =
dictionary.school.students.gender[option.value] ?? option.labelAnti-patterns
GENDER_OPTIONSredefined (4 files) with inconsistent values — lift tosrc/lib/config/options.ts.PAGE_SIZE_OPTIONSredefined (5+ files) — same fix.MAX_FILE_SIZEredefined (7+ files) — useSIZE_LIMITSfromfile/config.ts.Roletype redefined — import from@prisma/client.- Utility functions (
formatFileSize) — move toutil.ts. - Types in config (
PlatformNavItem) — move totypes.ts. - Raw
process.env— read via@/env.mjs. - Empty config files — delete or fill.
- Bloated files (
dashboard/config.ts485 lines) — split by concept. - English-only labels — UI looks up via dictionary.
Naming
- File:
config.ts. - Primitives:
UPPER_SNAKE_CASE. Object literals:camelCase. - One concept per export.