Skip to content

Architecture overview

mcomtask is a multi-tenant SaaS ERP built as a modular monolith with compiler-enforced module boundaries. This page is the short version; the reasoning lives in the architecture design spec.

Concern Choice
Backend Go, Gin, sqlc, pgx v5, goose, River (Postgres-backed jobs)
Frontend React 19, Vite, TanStack Query / Router / Table, shadcn on Radix, i18next
Database Postgres 17, shared schema, row-level security per organization
Contract Spec-first OpenAPI via oapi-codegen; REST only, SSE for realtime
Money shopspring/decimal in Go, NUMERIC(19,4) in Postgres, a string on the wire
Storage S3-compatible; presigned uploads, bytes never transit the API
Tests testify + testcontainers-go against real Postgres
flowchart TD
  M["modules/ — HTTP surface per business area<br/>expenses, payables, receivables, crm, payroll, …"]
  P["platform/ — shared capabilities<br/>workflow, posting, numbering, documents, i18n, …"]
  K["kernel/ — tenancy, money, audit, errors, event bus"]
  M --> P --> K

Dependencies point downward only. A kernel package importing a platform package is a bug. Nothing outside a module may import its internal/; cross-module access goes through contract.go or a published event. The package map lists every package with its own doc comment.

Every request runs in one transaction, reads included. The tenant is set with SET LOCAL inside that transaction, which is what makes row-level security safe under connection pooling. The organization comes from the authenticated session, never from a request header.

Modules never write journal lines. They register posting rules with accounting/, which reacts to semantic tags on workflow states, never to state names — that is what lets a customer rearrange their workflow safely. The ledger is append-only; corrections are reversals.

Binary Role
cmd/api HTTP server; wires modules
cmd/worker River workers: FX sync, reminders, OCR, exports, retention
cmd/migrate goose runner
cmd/operator The service provider’s private console across organizations
cmd/orgadmin Creates organizations — there is deliberately no public sign-up
cmd/telegram-webhook Points Telegram’s webhook at a deployment
cmd/myinvois-fake Local stand-in for LHDN’s MyInvois API