I designed the VELOZITY_assignment backend with a clean, practical multi‑layered architecture that separates concerns from the UI down to data persistence.
- Frontend → Express Server/Router → Auth Middleware (JWT Verify) → Role Middleware (RBAC Forbidden) → Zod Schemas (Validation) → Thin Controller → Service Layer (Business Rules & Ownership Validation) → Prisma ORM (PostgreSQL) and SocketService (Real‑Time Emit)
Thin Controllers only extract payloads, call service methods, and format responses, keeping request handling simple and testable.
All business logic, DB mutations, ownership checks, and event dispatching live in the Service Layer; route handlers never run direct DB queries.
Authorization is fail‑closed: a route‑level requireRole middleware and row‑level checks inside services (e.g., task.assignedToId === user.id or project.pmId === user.id) both must pass.
Global error middleware returns a uniform JSON envelope: { "success": false, "error": { "code": "FORBIDDEN", "message": "You can only access tasks assigned to you" } } and logs stack traces server‑side only.
For a high‑level view of the stack, see the velozity assignment tech stack page.

