All list endpoints now return paginated responses:
{ data: [...], pagination: { page, limit, total, totalPages } }
Query params: ?page=1&limit=25&q=search&sort=name&order=asc
Changes:
- Added PaginationSchema in @forte/shared for consistent param parsing
- Added pagination utils (withPagination, withSort, buildSearchCondition,
paginatedResponse) in backend
- Refactored all services: AccountService, MemberService, CategoryService,
SupplierService, ProductService, InventoryUnitService
- Merged separate /search endpoints into list endpoints via ?q= param
- Removed AccountSearchSchema and ProductSearchSchema (replaced by
PaginationSchema)
- Added pagination test (5 items, page 1 limit 2, expect totalPages=3)
- Updated CLAUDE.md with API conventions
- 34 tests passing
2.6 KiB
2.6 KiB
Forte — Project Conventions
App
- Name: Forte
- Purpose: Music store management platform (POS, inventory, rentals, lessons, 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
@forte/shared— types, Zod schemas, business logic, utils@forte/backend— Fastify API server
Database
- Dev:
forteon localhost:5432 - Test:
forte_teston 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 modebun run test— run all testsbun run lint— lint all packagesbun run format— format all files with Prettier
API Conventions
- All list endpoints support server-side pagination, search, and sorting via query params:
?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
PaginationSchemafrom@forte/shared/schemasto parse query params - Use pagination helpers from
packages/backend/src/utils/pagination.ts
Conventions
- Shared Zod schemas are the single source of truth for validation (used on both frontend and backend)
- Business logic lives in
@forte/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