Rebrand from Forte (music-store-specific) to LunarFront (any small business): - Package namespace @forte/* → @lunarfront/* - Database forte/forte_test → lunarfront/lunarfront_test - Docker containers, volumes, connection strings - UI branding, localStorage keys, test emails - All documentation and planning docs Generalize music-specific terminology: - instrumentDescription → itemDescription - instrumentCount → itemCount - instrumentType → itemCategory (on service templates) - New migration 0027_generalize_terminology for column renames - Seed data updated with generic examples - RBAC descriptions updated
67 lines
3.7 KiB
Markdown
67 lines
3.7 KiB
Markdown
# LunarFront — Project Conventions
|
|
|
|
## App
|
|
- **Name:** LunarFront
|
|
- **Purpose:** Small business management platform (POS, inventory, rentals, scheduling, repairs, accounting)
|
|
- **Company:** Lunarfront Tech LLC
|
|
|
|
## Tech Stack
|
|
- **Runtime:** Bun
|
|
- **Language:** TypeScript (strict mode, end-to-end)
|
|
- **API:** Fastify with Pino JSON logging
|
|
- **ORM:** Drizzle ORM (PostgreSQL 16)
|
|
- **Validation:** Zod (shared schemas between frontend and backend)
|
|
- **Queue:** BullMQ (Valkey-backed)
|
|
- **Cache:** Valkey 8 (Redis-compatible fork)
|
|
- **Monorepo:** Turborepo with Bun workspaces
|
|
- **Testing:** bun test (built-in, uses bun:test imports)
|
|
- **Linting:** ESLint 9 flat config + Prettier
|
|
|
|
## Package Namespace
|
|
- `@lunarfront/shared` — types, Zod schemas, business logic, utils
|
|
- `@lunarfront/backend` — Fastify API server
|
|
|
|
## Database
|
|
- Dev: `lunarfront` on localhost:5432
|
|
- Test: `lunarfront_test` on localhost:5432
|
|
- Multi-tenant: `company_id` (uuid FK) on all domain tables for tenant isolation
|
|
- `location_id` (uuid FK) on tables that need per-location scoping (inventory, transactions, drawer)
|
|
- Migrations via Drizzle Kit (`bunx drizzle-kit generate`, `bunx drizzle-kit migrate`)
|
|
|
|
## Key Entity Names
|
|
- `account` — billing entity (family, individual, or business)
|
|
- `member` — individual person on an account (NOT "student" — renamed to support multiple adults)
|
|
- `member.is_minor` — derived from date_of_birth, controls consent/portal rules
|
|
|
|
## Commands
|
|
- `bun run dev` — start all packages in dev mode
|
|
- `bun run test` — run all tests
|
|
- `bun run lint` — lint all packages
|
|
- `bun run format` — format all files with Prettier
|
|
|
|
## API Conventions
|
|
- **Every endpoint that returns a list must support pagination, search, and sorting** — no exceptions unless the endpoint is explicitly a lightweight lookup (see below)
|
|
- `?page=1&limit=25` — pagination (default: page 1, 25 per page, max 100)
|
|
- `?q=search+term` — full-text search across relevant columns
|
|
- `?sort=name&order=asc` — sorting by field name, asc or desc
|
|
- List responses always return `{ data: [...], pagination: { page, limit, total, totalPages } }`
|
|
- Search and filtering is ALWAYS server-side, never client-side
|
|
- Use `PaginationSchema` from `@lunarfront/shared/schemas` to parse query params
|
|
- Use pagination helpers from `packages/backend/src/utils/pagination.ts`
|
|
- **Lookup endpoints** (e.g., `/roles/all`, `/statuses/all`) are the exception — these return a flat unpaginated list for populating dropdowns/selects. Use a `/all` suffix to distinguish from the paginated list endpoint for the same resource.
|
|
|
|
## Frontend Table Conventions
|
|
- **Every table that displays data must use the shared `DataTable` component** (`components/shared/data-table.tsx`)
|
|
- All tables must support: **search** (via `?q=`), **sortable columns**, and **server-side pagination**
|
|
- Use the `usePagination()` hook (`hooks/use-pagination.ts`) — it manages page, search, and sort state via URL params
|
|
- All data columns that make sense to sort by should be sortable (e.g., name, email, date, status) — don't limit to just 1-2 columns
|
|
- Sub-resource tables (e.g., members within an account, payment methods) follow the same rules — use `DataTable` with pagination, not raw `<Table>` with unbounded queries
|
|
- Loading states should use skeleton loading (built into `DataTable`), not plain "Loading..." text
|
|
|
|
## Conventions
|
|
- Shared Zod schemas are the single source of truth for validation (used on both frontend and backend)
|
|
- Business logic lives in `@lunarfront/shared`, not in individual app packages
|
|
- API routes are thin — validate with Zod, call a service, return result
|
|
- All financial events must be auditable (append-only audit records)
|
|
- JSON structured logging with request IDs on every log line
|