9.3 KiB
AGENTS.md - Project Constitution For AI Coding Agents
This file provides project-specific guidance for AI coding agents working in this repository.
Highest Priority
AI agents must follow instructions in this order:
- Existing project implementation
docs/AI_DEVELOPMENT_GUIDE.mddocs/PROJECT_ARCHITECTURE.mdAGENTS.mdkiranism-shadcn-dashboard- shadcn/ui
- TanStack Table, TanStack Query, TanStack Form, and nuqs patterns
- Next.js best practices
If instructions conflict, the higher item wins.
Mandatory Audit Before Code Changes
Before editing code, inspect the existing implementation for:
- Feature structure
- Shared components
- Shared hooks
- Shared route handlers and service patterns
- Shared dialogs and sheets
- Shared forms
- Shared tables
- Shared layout
- Auth and role checks
Do not guess. Reuse what exists before creating anything new.
Project Overview
This project is a Next.js 16 training-system dashboard built on an app-owned stack.
Current core stack:
- Framework: Next.js 16 App Router
- Language: TypeScript 5.7
- UI: shadcn/ui + Tailwind CSS v4
- Authentication: Auth.js
- Persistence: PostgreSQL + Drizzle ORM
- Data Fetching: TanStack React Query
- URL State: nuqs
- Forms: TanStack Form + Zod
- Charts: Recharts
- Monitoring: Sentry
The actual stack is Drizzle ORM and TanStack Form. Do not introduce Prisma, React Hook Form, or next-safe-action unless a future architecture decision explicitly adopts them.
Current architecture status:
- Auth is app-owned through
Auth.js - Multi-tenant access uses
users,organizations, andmemberships usersis now the single person entity for auth and training participationemployeesis legacy migration data only and should not be used for new runtime work- Core training modules are DB-backed:
userscoursestraining-recordstraining-matrixreports
- Some template pages still exist as placeholders or legacy seams
Auth And Roles
The current auth model is centered around:
usersorganizationsmemberships
Important files:
src/auth.tssrc/lib/auth/session.tssrc/lib/auth/roles.tssrc/proxy.tssrc/db/schema.ts
Current behavior:
- Authentication uses an Auth.js Credentials provider
- Passwords are verified against
users.password_hash - The user row stores
active_organization_id - Session enrichment loads membership and organizer context
- Self-service sign-up is disabled
Role model:
super_admin: system-level organizer managementadmin: organizer-level managementuser: standard end user
Preferred server-side helpers:
requireSession()requireOrganizationAccess(options?)
Do not introduce Clerk usage.
Sidebar Expectations
Sidebar visibility is role-based:
super_admin: sees organizer management plus all organizer-operational menusadmin: seesDashboard,Users,Courses,Training Records,Training Matrix,Reportsuser: sees onlyDashboard,Training Records,Reports
Nav filtering is UX only. Real protection must stay server-side.
Project Structure
/src
app/
auth/
dashboard/
api/
components/
config/
db/
schema.ts
features/
auth/
overview/
users/
courses/
training-records/
training-matrix/
reports/
products/
hooks/
lib/
styles/
types/
Relevant docs:
docs/AI_DEVELOPMENT_GUIDE.mddocs/PROJECT_ARCHITECTURE.mddocs/REFRACTOR_REPORT.mdplans/req.mdplans/implementation-plan.mdplans/system-test-flow.mddocs/themes.mddocs/nav-rbac.md
Canonical Features
Use these references in order:
training-records: canonical feature for CRUD, Route Handlers, Drizzle, DataTable, TanStack Form, upload, and review flows.employee-directory: canonical responsive DataTable and custom toolbar reference.announcements: canonical content publishing and state transition reference.audit-logs: canonical read-only table reference.
Feature and UI work must copy the existing pattern from these features before inventing a new approach.
Data Model Guidance
Runtime person data belongs on users.
User profile fields used by training features include:
employee_codedepartment_idposition_idcompany_namehired_at
Training participation should reference training_records.user_id.
Do not build new features on top of the legacy employees module.
Feature Architecture
Each feature should use:
src/features/<name>/api/
types.ts
service.ts
queries.ts
mutations.ts
Rules:
- components import contracts from
types.ts - services call local route handlers through
apiClient - route handlers talk to Drizzle
- prefer server prefetch +
HydrationBoundary+useSuspenseQuery()
Preferred backend path:
- Route Handlers + Drizzle + Auth.js session helpers
Legacy mock files are migration seams only:
src/constants/mock-api.tssrc/constants/mock-api-users.ts
DataTable Rules
For data tables, reuse:
DataTableDataTableToolbarDataTablePaginationDataTableViewOptionsDataTableColumnHeaderuseDataTable- TanStack
ColumnDef - shared faceted/date/slider filters
- row action menu components
Do not create a new table shell, toolbar, pagination component, sorting pattern, or view-options implementation when the shared stack can serve the feature.
Manual tables are only acceptable for small static layouts or legacy code that is intentionally left unchanged.
Forms
Use:
useAppForm- project field wrappers from
@/components/ui/tanstack-form - Zod validation
Master-data fields such as Department and Position should use dropdowns backed by server data, not free text.
Organizer-scoped defaults:
companyshould come from the active organizer/workspace context- normal admins should not choose arbitrary organizers
super_adminmay assign organizer context when creating users
Do not introduce React Hook Form into this project.
Dialog, Sheet, And Action Rules
Reuse:
DialogSheetAlertDialogAlertModalDropdownMenu
Use a row action menu when a row has multiple commands such as view, edit, publish, archive, or delete.
Upload Rules
Reuse existing upload components and storage helpers:
FileUploadercertificate-storage.tsannouncement-storage.tsonline-lesson-storage.ts
Do not create a new upload/storage implementation until the existing helpers are proven insufficient.
Responsive Rules
Pages must not overflow horizontally.
Use:
PageContainerw-full min-w-0 max-w-fulloverflow-x-autoonly inside table shells- wrapping button containers
shrink-0 whitespace-nowrapfor actions that must not clip
Do not create nested cards for page sections. Cards are for forms, filters, empty states, repeated content items, and focused tools.
Forbidden Without Approval
AI agents must not introduce:
- New dashboard layout
- New table framework
- New pagination pattern
- New toolbar framework
- New form framework
- New dialog framework
- New upload framework
- Prisma
- Clerk
- React Hook Form
next-safe-action- Mock data imports in runtime UI
Protected Data Rules
Use these rules consistently:
admincan see organizer-wide datausercan only see their own training data- reports for
usermust be self-scoped on the server even if URL params are manipulated - training-record participant selection must come from organizer-scoped
users
Development Commands
bun install
# or
npm install
bun run dev
# or
npm run dev
bun run build
# or
npm run build
bun run lint
# or
npm run lint
bun run migrate
# or
npm run migrate
Environment Configuration
Required:
AUTH_SECRET=your-long-random-secret
DATABASE_URL=postgres://postgres:postgres@localhost:5432/training_system
Optional Sentry variables may also be configured.
Notes For AI Agents
- Always use
cn()for className merging. - Keep new work inside
src/features/. - Server components are the default.
- Avoid
any; keep contracts explicit. - Use
PageContainerfor page headers. - Use TanStack Form + Zod via existing wrappers.
- Use icons only through
@/components/icons. - Prefer Route Handlers + Drizzle + React Query for new app-owned features.
- Never import mock API data directly into UI components.
- Use
@/authandsrc/lib/auth/session.tsfor auth checks. - Do not introduce Clerk usage.
- Treat
employeesas legacy migration data, not target runtime architecture. - Follow the migrated
users,courses, andtraining-recordspatterns for new CRUD work. - Read
docs/AI_DEVELOPMENT_GUIDE.mdanddocs/PROJECT_ARCHITECTURE.mdbefore substantial code changes. - If code being touched is off-pattern, propose a focused refactor before expanding that pattern.
- Consistency is more important than novelty. New work should look like it has always been part of the project.
Required Completion Checklist
Before final response, verify:
- Existing feature pattern was inspected.
- Shared components were reused.
- Shared hooks were reused.
- Shared dialogs/sheets/action menus were reused.
- Data tables use the shared DataTable stack.
- Forms use TanStack Form plus Zod.
- Route handlers and Drizzle patterns are preserved.
- Server-side auth and role checks are preserved.
- Folder structure and naming match the project.
- Responsive behavior does not clip buttons or overflow the page.