133 lines
12 KiB
Markdown
133 lines
12 KiB
Markdown
# Agent Instructions
|
||
|
||
Read `WORKSPACE_MEMORY.md` before making structural changes to page code.
|
||
|
||
## Stack
|
||
|
||
- **Runtime:** Bun — not Node. Use `bun` commands, never `npm`/`npx`.
|
||
- **Framework:** `@moduletrace/bunext` — not Next.js. Routing is filesystem-based under `src/pages/`, served by `Bun.serve` in `src/server.ts`.
|
||
- **Database:** `@moduletrace/bun-sqlite` — MariaDB database. Schema in `db/schema.ts`, generated types in `db/types/db.ts`. Config in `bun-sqlite.config.ts` (DB name `rpe.db` in `./db`).
|
||
- **UI:** Tailwind CSS v4 + local `twui` components (`src/components/twui`) + shadcn/ui (`src/components/ui`). shadcn/ui configured via `components.json` (style: `radix-vega`), CSS entry at `src/components/twui/base.css` (imported by `src/styles/globals.css`). Uses `@shadcnblocks` registry for extra blocks (`src/components/shadcnblocks`).
|
||
- **Icons:** `lucide-react`.
|
||
- **Validation:** `zod` v4 (`[email protected]`).
|
||
|
||
## MCP Tool Usage Guidelines
|
||
|
||
When building, refactoring, styling, or auditing UI components and layouts, actively invoke these configured MCP servers:
|
||
|
||
### 1. `design-mcp` (UI/UX Engineering & Design Standards)
|
||
|
||
- **When to call:** Before constructing new page layouts, design systems, empty/loading states, or interactive UI flows.
|
||
- **Instruction:** Query `design-mcp` to ensure accessibility (a11y), proper layout hierarchy, visual balance, and consistent interaction patterns across application workflows.
|
||
|
||
### 2. `design-systems` (Design System Specs & Reference Patterns)
|
||
|
||
- **When to call:** When creating or extending reusable component interfaces, verifying design token structures, or inspecting component composition patterns.
|
||
- **Instruction:** Query `design-systems` to pull canonical UI patterns, atomic component guidelines, and standard prop naming conventions before creating custom components.
|
||
|
||
## Entrypoint
|
||
|
||
`src/server.ts` — runs `bunextInit()`, initializes a persistent **Piper TTS daemon** (global `PIPER_MANAGER`), starts `Bun.serve` with WebSocket upgrade on `/ws`, then starts cron.
|
||
|
||
## Commands
|
||
|
||
| Purpose | Command |
|
||
| -------------------------- | --------------------------------------------------------- |
|
||
| Dev server | `bun run dev` (runs `bun src/server.ts`) |
|
||
| Production | `bun run start` (`NODE_ENV=production bun src/server.ts`) |
|
||
| Type-check only | `bunx tsc --noEmit` |
|
||
| DB schema (tables) | `bun run db:schema` |
|
||
| DB schema (+vectors) | `bun run db:schema:vector` |
|
||
| DB admin UI | `bun run db:admin` |
|
||
| DB backup | `bun run db:backup` |
|
||
| Port SQLite → MariaDB | `bun run db:port-sqlite` |
|
||
| Install (private registry) | `bun install` (uses registry in `bunfig.toml`) |
|
||
|
||
No linter or formatter configured. Type-check is the primary verification step. 33 project-level `.test.ts`/`.test.tsx` files exist but no test runner script is configured — run individual tests with `bun test <file>`.
|
||
|
||
## Architecture
|
||
|
||
### Root Component & Context
|
||
|
||
`src/pages/__root.tsx` — sets up:
|
||
|
||
- Layout selection (admin/auth/public)
|
||
- WebSocket connection via `useWebSocket` + `useWebSocketEventHandler`
|
||
- `AppContext` (React context) providing `AppContextType` globally — includes user data, WebSocket, and `sendWebsocketData`
|
||
- Server-navigated URL push via `server:navigate-to-url` WebSocket event
|
||
|
||
## Path Alias
|
||
|
||
`@/*` resolves from repo root. Import like `@/src/components/ui/button`, `@/db/types/db`, `@/external/cloudflare/r2`.
|
||
|
||
## Admin Route Hierarchy
|
||
|
||
Two tiers of admin pages:
|
||
|
||
- **`/admin/*`** — Resident-facing features: access booking (`/admin/access`), payments (`/admin/payments/*`), chat (`/admin/chat/*`), dependants (`/admin/dependants`), notifications (`/admin/notification`), events (`/admin/events`), settings/profile, support/complaints. Additional sections: `association/`, `devops/`, `management/`, `workers/`
|
||
- **`/admin/admin/*`** — Admin-only features: user management (`/admin/admin/users/*`), payment schemes, payment management, documents/constitution, chat group management. Requires `admin` or `exco` role.
|
||
- **`/admin/security/*`** — Security features: gate control, guest access monitoring, dependant verification. Requires `security`, `exco`, `manager`, or `aco` role.
|
||
|
||
Admin sidebar navigation data in `src/layouts/admin/(data)/`. ElevenLabs voice agent widget integrated into admin layout (`src/layouts/admin/(partials)/eleven-labs-widget.tsx`).
|
||
|
||
## Page Directory Rules
|
||
|
||
For route-local code under `src/pages`, use non-routed meta folders:
|
||
|
||
- `(sections)` — page sections
|
||
- `(partials)` — components used by sections
|
||
- `(data)` — page-local data
|
||
- `(functions)` — page-local functions
|
||
- `(utils)` — page-local utilities
|
||
- `(hooks)` — page-local hooks
|
||
|
||
Keep route files (e.g. `index.tsx`) thin — compose from route-local meta folders.
|
||
|
||
Dynamic routes use `[param]` syntax (e.g. `[id]`, `[user_type]`, `[key]`). Catch-all routes use `[[...paths]]`.
|
||
|
||
Server functions use `index.server.ts` alongside `index.tsx` (e.g. `single-document/[id]/index.server.ts`).
|
||
|
||
## Shared Code Organization
|
||
|
||
- **`src/hooks/`** — Shared React hooks: `use-admin-crud-get`, `use-all-users-list-init`, `use-annual-dues-status`, `useAppContext`, `use-fetch-get`, `use-form-init`, `useLocalUser`, `use-mobile`, `use-payments-query`, `use-users-get`
|
||
- **`src/functions/`** — Shared functions split by target:
|
||
- `src/functions/backend/` — Server-only: DB queries (`grab-users` in `backend/db/`), email client, RAG ingest, media upload, embed/face ingest
|
||
- `src/functions/frontend/` — Client-safe: CRUD handlers, fetch handlers, Paystack script loader, URL parser
|
||
- `src/functions/general/` — Platform-agnostic: join builders in `general/joins/` (users, payments, guests, messages, chat groups)
|
||
- **`src/utils/`** — Utility modules: auth, cookies, crypto, CSRF, hashing, contact classification, RAG text chunking, user type parsing. Most have corresponding `.test.ts` files (auth, cookies, crypto, CSRF, hashing, contact classification, user type parsing).
|
||
- **`src/dict/`** — Dictionaries/constants: user types, access codes, gates, LLM providers/models, TTS voices, WebSocket rooms, messaging types, localStorage keys
|
||
- **`src/data/`** — Static data: `app-data.ts` (app constants — cookie names, limits, default models, Paystack endpoint), location data, super admin users, role documentation
|
||
- **`src/types/`** — Type definitions (~1,350 lines total across 4 files): `index.ts` (1,037 lines), `sql-joins.ts`, `paystack.ts`, `search-api.ts`
|
||
- **`src/lib/`** — `utils.ts` exports `cn()` (clsx + tailwind-merge), used by shadcn/ui components
|
||
- **`src/scripts/`** — Seed scripts for location and resident data
|
||
|
||
## Component Systems
|
||
|
||
| Directory | Description |
|
||
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||
| `src/components/twui/` | Local design system — publishable package with its own `package.json`. Contains elements, composites, editors (TinyMCE), form components, MDX support, hooks, layout, SVGs, and utilities |
|
||
| `src/components/general/` | Shared page components: AI chat, date-picker, logo, Paystack widgets, status-tag, user-avatar, face-search-card, guarantor-preview-modal, guarantor-info-row, etc. (search-select lives in `src/components/twui/form/SearchSelect.tsx`) |
|
||
| `src/components/pages/` | Public page components: `about/`, `constitution/`, `homepage/` |
|
||
| `src/components/shadcnblocks/` | Components from shadcnblocks.com registry (logo) |
|
||
|
||
## Conventions
|
||
|
||
- Prefer one function/component per file over monolithic files with multiple exports.
|
||
- **Modularization is non-negotiable: prioritize modularization over monolithic functions/components.** Repeated UI blocks must be extracted into their own reusable components driven by props (e.g. an info row component taking `{ icon, text }`), never repeated inline markup.
|
||
- **Every rendered array must have a separate component for each array item.** Always extract the item JSX into its own component and render it via `items.map((item) => <ItemComponent {...item} />)` — never inline the item's JSX inside the map callback.
|
||
- Always use object parameters (`{ foo, bar }`) instead of comma-separated positional parameters.
|
||
- Prefer existing patterns over new abstractions.
|
||
- `.env` is gitignored but exists locally with secrets. Do not commit it.
|
||
- `secrets/` directory is also gitignored.
|
||
- `external/` binary directories (`**/models`, `**/bin`, `**/x-86`, `**/arm-64`) are gitignored.
|
||
- The `bunext.config.ts` excludes `onnxruntime-node` and `@xenova/transformers` from SSR/page compilation (native modules that must stay server-side).
|
||
- `tsconfig.json` excludes `src/components/twui/mdx`, `src/components/twui/elements/RemoteCodeBlock.tsx`, and `src/components/twui/mdx/markdown/MarkdownEditorPreviewComponent.tsx` from type-checking.
|
||
|
||
## Conventions
|
||
|
||
- Prefer one function/component per file over monolithic files with multiple exports.
|
||
- **Modularization is non-negotiable: prioritize modularization over monolithic functions/components.** Repeated UI blocks must be extracted into their own reusable components driven by props (e.g. an info row component taking `{ icon, text }`), never repeated inline markup.
|
||
- **UNCHANGEABLE RULE — twui components always win over raw JSX elements.** ALWAYS use twui components (`H1`–`H5`, `P`, `Span`, `List`, `Img`, `Row`, `Stack`, `Container`, `Section`, `Border`, `Card`, `Button`, `Tag`, `Link`, etc.) before basic JSX elements (`<h1>`–`<h6>`, `<p>`, `<span>`, `<ul>`, `<li>`, `<img>`, `<a>`, `<button>`, `<div>`-as-card, etc.). Never introduce or reintroduce a raw JSX element where a twui equivalent exists. Override twui defaults via `className` (e.g. `mb-0!`) rather than reaching for the raw element.
|
||
- **UNCHANGEABLE RULE — twui components are preferred over shadcn/ui components.** Use twui before `src/components/ui/*` (shadcn) whenever a twui equivalent exists. The long-term goal is to phase out shadcn/ui entirely — do not introduce new shadcn usage where twui covers the need, and prefer migrating existing shadcn call sites to twui when touching them anyway.
|
||
- **LIMIT EDITS TO `src/components/twui/`** — it is a general, publishable library shared across projects (its own `package.json`), not scoped to this repo. Do not modify its components unless strictly necessary. Customize/appearance overrides for this project belong in `src/styles/globals.css` (e.g. tweaking `.twui-card`, `--color-*` tokens, font/type styles) rather than editing twui source files.
|