Skip to main content

Conventions

Both repos have a CONVENTIONS.md (backend) or CLAUDE.md (both) documenting load-bearing rules. The most important ones are duplicated here for fast reference.

Backend (marketplace-fleapoai-service)

Env vars

  • Never read process.env directly inside a NestJS module. Use AppConfigService.
  • Exceptions: main.ts, migrate.ts, seed.ts (bootstrap scripts only).

Schema

  • src/db/schema/auth.ts is CLI-generated. Do not hand-edit. Regenerate via pnpm db:auth-schema.
  • src/db/schema/business.ts is hand-written.

Migrations

  • Never run drizzle-kit push against any non-local DB.
  • Workflow: pnpm db:generate --name <slug> → review SQL → commit → pnpm db:migrate.

TypeScript config

  • module: commonjs + moduleResolution: node — not nodenext. better-auth's ESM-first build will fail under nodenext.
  • noUncheckedIndexedAccess: false — kept off because Drizzle's destructure pattern.

Auth

  • createAuth() is a factory, not a singleton. Call it inside an @Module factory provider with the DI-injected db and config.
  • permissions.ts must include EVERY action better-auth's admin plugin might check — including built-ins (user.list, session.revoke, etc.) — or platform_admin will hit 403.
  • The frontend's src/lib/permissions.ts must mirror this file byte-for-byte.

Request lifecycle

The order in main.ts is load-bearing:

AuthMiddleware → AuditLogMiddleware → LoggingInterceptor → ApiResponseInterceptor → ErrorHandlingInterceptor → Guards → Handler

Don't reorder.

Webhook controller

Uses @Res() + raw body. Don't add interceptors or wrap the response.

Frontend (fleapo-marketplace)

Mock vs live data

  • The catalog reads from live API via Orval-generated hooks.
  • src/data/agents.ts mock arrays are still present for staging and admin pages that don't have backend support yet.
  • Don't delete mock arrays until a live endpoint replaces them.

shadcn/ui

  • src/components/ui/ are shadcn primitives. Do not hand-edit. Use the shadcn CLI to add new ones.

Framer Motion

  • layoutId follows pattern agent-{part}-{prefix}{slug}.
  • Always pass a unique layoutIdPrefix to AgentCard when the same agent might appear in multiple grids on the same page.

Tailwind / CSS

  • Colors via CSS custom properties (hsl(var(--primary))).
  • Brand primary #19B4B0.
  • Geist + Geist Mono.
  • Path alias @/src/.

Routing

  • New routes go in src/App.tsx.
  • Admin routes nest under <AdminLayout>.

Both repos

  • pnpm is the package manager. No npm i or yarn add.
  • Tests live next to source files or in src/test/.
  • Branch names: feat/<x>, fix/<x>, chore/<x>, refactor/<x>.