Skip to content

Architecture decisions (ADR index)

Architecture Decision Records (ADRs) capture why the system is shaped a certain way: alternatives considered, trade-offs, and consequences. They complement narrative pages such as System overview and Request flow by preserving decision history when people or vendors change.

This page provides:

  1. A lightweight ADR format suitable for this repo.
  2. Starter decisions inferred from the codebase layout (must be validated against your production policy).
  3. Pointers to where to store future ADRs (this file as an index, or docs/src/content/docs/reference/adr/ as split files if you outgrow one page).
  • Choosing an integration style (webhook-first vs poll-first, per-tenant OAuth storage, etc.).
  • Adding or removing a DocType override of core ERPNext behavior.
  • Changing guest-accessible API surfaces or authentication flows.
  • Material changes to scheduler frequency, idempotency, or data retention.
### ADR-NNN — Short title
- **Status:** Proposed | Accepted | Superseded by ADR-XXX
- **Date:** YYYY-MM-DD
- **Context:** Problem and constraints (business, compliance, team).
- **Decision:** What we chose, in one paragraph.
- **Alternatives considered:** Bullet list with why rejected.
- **Consequences:** Positive / negative; migration notes; monitoring.
- **Code / config pointers:** Paths, DocTypes, env keys (names only).

ADR-001 — Frappe / ERPNext as the application core

Section titled “ADR-001 — Frappe / ERPNext as the application core”
  • Status: Accepted (documentary)
  • Context: The product extends ERPNext via a custom app rather than a standalone service mesh.
  • Decision: Implement domain logic primarily as Frappe DocTypes, hooks, and whitelisted Python APIs under leekimerp/.
  • Consequences: Upgrades must respect ERPNext migrations; customizations use overrides and patches. Operational model is Bench site + MariaDB + workers.
  • Pointers: leekimerp/hooks.py, leekimerp/api/.

ADR-002 — Integrations as first-class API modules

Section titled “ADR-002 — Integrations as first-class API modules”
  • Status: Accepted (documentary)
  • Context: Xero, Stripe, DocuSign, and Singpass require server-side orchestration and often guest webhooks.
  • Decision: Centralize HTTP handlers in leekimerp/api/*.py with @frappe.whitelist, with integration-specific DocTypes for tokens and mapping.
  • Consequences: Security reviews must treat guest endpoints as a dedicated surface (Security checklist, API inventory). Signature verification and replay handling are implementation responsibilities in each module.
  • Pointers: api/xero.py, api/stripe_webhook.py, DocTypes under finance-ar-integrations.

ADR-003 — Static handover site separate from ERP runtime

Section titled “ADR-003 — Static handover site separate from ERP runtime”
  • Status: Accepted (documentary)
  • Context: Commercial handover requires browsable technical documentation; ERP Desk is not a wiki.
  • Decision: Host Astro + Starlight under docs/ and deploy separately (e.g. Cloudflare Pages).
  • Consequences: Documentation versioning tracks the docs/ tree and CI, not bench migrate. Links to code paths must be maintained manually or via conventions (Documentation conventions).

ADR-004 — Generated DocType reference with optional overlays

Section titled “ADR-004 — Generated DocType reference with optional overlays”
  • Status: Accepted (documentary)
  • Context: Hundreds of custom DocTypes exist; hand-maintaining every field narrative is costly.
  • Decision: Generate field tables into DocType reference and enrich selectively via docs/doctype-overlays/overlays.json and domain narratives (Domain documentation strategy).
  • Consequences: Thin per-DocType pages are acceptable if domain deep dives and critical-path DocTypes are documented in depth.

  1. Validate the starter ADRs against production reality (especially guest APIs and secrets handling).
  2. Add ADR-005+ when you make the next architectural change; keep entries short and link to PRs.
  3. Optionally split each ADR into reference/adr/adr-00n-title.md and replace this page with an index of links only.