Skip to content

Architecture

  • A modular monolith, not microservices. In production there are two processes: server.ts (HTTP) and worker.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 httpOnly SameSite=Strict cookie.
  • 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