Skip to content

Design Decisions

eugnmueller-87 edited this page Jun 24, 2026 · 1 revision

Design Decisions (ADRs)

The repo keeps formal Architecture Decision Records in docs/decisions/. Summary below; read the source ADRs for full context and consequences.

ADR Decision Why it matters
001 Six-role system (procurement, it, user, controlling, admin) Drives navigation, board filters, action buttons, and future RLS row filtering. Legal was deactivated — legal works in Jira, not the tool.
002 PostgREST over a custom API Browser can't open raw TCP; a custom Node/Express layer is extra surface to build and secure. PostgREST auto-generates REST straight from the schema — no backend layer to maintain.
003 n8n as orchestrator (self-hosted VPS, Traefik) Built-in IMAP/SMTP/HTTP/schedule/code triggers + branching on agent responses. Managed tools (Zapier/Make) can't reach a self-hosted DB + custom RPCs.
004 DocuSign JWT Grant for e-signatures Server-to-server auth, no per-user OAuth popup, embedded signing inside the board, callback updates ticket status.
005 Ask Assistant scope matrix In-app chat answers only from inside TrueSpend (DB rows + RAG store) — no web access, no model world-knowledge leaking in. Constrained by today's single shared JWT.
006 Money RPCs fail-closed; money writes leave the browser A static browser JWT could be extracted via DevTools to approve purchases. Money RPCs move server-side (n8n) and fail-closed. This is the keystone of the Security-Model.
007 dbmate is the migration runner; schema.sql is generated schema.sql had drifted ~6 months / ~50 objects behind the migration chain. The ordered db/migrations/ chain is now canonical; the snapshot is generated, not hand-edited.
008 Contract ingestion — demo seed now, agentic routes later Documents the staged path for getting contracts into the structured register; also records a real schema↔code divergence bug and its fix.

The throughline

Read top-to-bottom, the ADRs tell one consistent story: push every trust and correctness guarantee down to the database, keep the application layer thin, and treat the LLM as an untrusted advisor. PostgREST removes a custom API layer (002); the RPC boundary + fail-closed money writes (006) put authority in the DB, not the client; dbmate makes the schema the canonical, versioned source of truth (007). That coherence is the thing worth pointing a reviewer at.

Clone this wiki locally