Architecture
- A modular monolith, not microservices. In production there are two processes:
server.ts(HTTP) andworker.ts(BullMQ). - REST first. Every endpoint validates its input with Zod. Errors carry typed XEC codes (
XEC-AUTH-1001, …) and go through one central handler. - Auth: a short-lived HS256 access token (15 minutes, sent as
Authorization: Bearer, kept in memory in the browser) plus a rotating refresh token in an httpOnlySameSite=Strictcookie. - Core doesn’t know plugins exist. Plugins add things through registries. Core loops over whatever is registered and never hardcodes a plugin’s tables, ids or routes. Search and the home feed both work this way.
Plugin (onEnable) ──registers──▶ core registry ──core iterates──▶ merged result e.g. registerSearchSource(...) searchRegistry GET /api/search