--- description: ERP backend core stack, security, and API conventions alwaysApply: true --- # ERP Backend — Core Conventions Stack: Node.js 20+ · Express (CommonJS) · PostgreSQL 15+ · Prisma · Joi · Winston ## Non-negotiables - CommonJS only (`require` / `module.exports`) — no ESM - Validate all env vars on boot via `src/config/env.js`; refuse to start if invalid - Never commit `.env`; only `.env.example` - All protected routes: `authenticate` → `authorize(module, action)` → `validate(schema)` → controller - Soft delete: filter `deleted_at: null`; set `deleted_at = now()` instead of hard DELETE - Every mutation calls `auditLog({ tableName, recordId, action, oldValue, newValue, userId, requestId })` - Controllers return `ApiResponse`; throw `ApiError` for failures — no Prisma or business logic in controllers - Serialize `BigInt` as strings in JSON (`BigInt.prototype.toJSON`) ## Response envelope ```json { "success": true, "message": "...", "data": {}, "meta": { "page": 1, "limit": 20, "total": 57 } } ``` ## Security - JWT access (15m) in Bearer header; refresh tokens hashed (SHA-256) in DB, rotated on refresh - bcrypt passwords; account lockout after failed attempts - AES-256-GCM + HMAC blind index for PII (mobile, bank accounts) — encrypt in service layer - Rate limit `/api` globally; stricter limit on auth routes - File uploads: MIME allow-list, random filenames, serve via authenticated RBAC endpoint only ## API - Routes under `/api/v1/`; pagination `?page=1&limit=20` (no upper cap on limit); dates ISO 8601 UTC - RBAC actions: `view`, `create`, `edit`, `delete`, `approve`, `export` - Reference: `BACKEND_SETUP.md`, task checklist: `BACKEND_TASKS.md`