Skip to main content

What is ASAB?

Start here

Imagine a giant LEGO building where lots of different shops all live inside, one on each floor. There is a bakery on one floor and a toy store on another. Each shop gets its own locked floor — the bakery can never wander into the toy store's stockroom, and the toy store can never peek at the bakery's money. But the whole building shares the same strong walls, the same front door, and the same security guard, so nobody has to build a whole new building just to open a shop.

ASAB is that building. It is one big software system where many separate companies each get their own private, locked-off "floor," but they all share the same well-built structure underneath. We rent out floors instead of selling each company a whole building.

There are also four different doors into the building, for four different kinds of people:

  1. A front door with a sign-up desk for new shops that want to move in.
  2. A building manager's office where the people who run the building can see every floor's health and turn services on or off.
  3. The floors themselves, where each shop does its daily work.
  4. A penthouse view for an owner who happens to own several shops at once and wants to see all of them on one screen.

Now let's say all of that again, precisely, the way an engineer needs it.


ASAB in one paragraph (the engineer version)

ASAB is a multi-tenant SaaS ERP. Every word there matters, so let's unpack each one:

  • ERP (Enterprise Resource Planning) — one connected system that runs the back office of a company: its money (accounting, invoices, payments), its stock (inventory, warehouses), its buying (procurement), its selling (CRM and sales), its making (manufacturing), and its paperwork (documents, approvals). Instead of ten disconnected apps that don't talk to each other, an ERP is the single place where a sale automatically updates stock, and stock automatically updates the ledger.
  • SaaS (Software as a Service) — customers don't install or own the software. They subscribe to it and use it over the internet; we run, update, and operate it for them.
  • Multi-tenant — a tenant is one customer company living inside the shared system. "Multi-tenant" means many tenants share the same running application and database without ever being able to see each other's data. That isolation is enforced at the deepest level (PostgreSQL row-level security), not merely hoped for in application code.
  • Platform — ASAB is not a single app. It is a four-layer platform (L1–L4, explained below) where a public sign-up gate, an operator control plane, the customer ERP, and an executive portal are distinct products that fit together.
Why a company needs an ERP

Without an ERP, a growing company keeps its sales in one spreadsheet, its stock in another, and its accounting in a third — and they constantly disagree. An ERP makes one number the truth: when sales records an order, stock and the general ledger update from that same event. ASAB's job is to be that single source of truth, for many companies at once, safely.


The four-layer platform (L1–L4)

ASAB's vision is built as four layers. Each layer is a different audience and a different "door" into the platform. Here is what each one is for — and, honestly, how built-out it is today. This handbook always describes the code as it is, not the dream.

L1 — Public Gate

What it is for. The public marketing and sign-up front door: a prospect visits a website, picks a plan, chooses their industry (Factory vs Insurance), pays, and a new tenant is created and provisioned automatically — no human operator in the loop.

As-built gap

L1 is greenfield today. There is no public marketing site, no subscription or pricing model, no platform billing, and no self-serve sign-up wired into a live public flow. The Angular app's root path redirects to a hardcoded default tenant workspace, and the only public routes are two narrow token-scoped pages (public/quotations/:quotationId/review and public/documents/portal). A prospect cannot create a company, pick a plan, or pay without a human operator running the admin APIs. What does exist — and is genuinely strong — is the back half of the funnel L1 must eventually feed into: the durable provisioning machinery in L2 (see below). See the Platform & Control Plane section for detail.

L2 — Operator / Control Plane

What it is for. The internal platform the ASAB team uses to run the building: see every tenant's status and health, provision new tenants, and turn module entitlements (a tenant's permission to use a given module) on and off.

This layer is realized as a separate deployable microservice, 4EOrganizationsManager, with its own four_e PostgreSQL schema. It owns the authoritative tenant registry (Organization then Tenant then Cell), a durable lease-based provisioning saga (a long-running, resumable workflow that survives crashes), module entitlements, API keys, and append-only monitoring tables. Code lives under backend/Applications/4EOrganizationsManager.

As-built gap

The write/provisioning engine is production-grade, but the operator-facing surface is thin. OrganizationsController and CellsController expose only POST (no list/get/update/suspend). There is no live entitlement feed to the runtime by default (the legacy worker reader uses static appsettings), no health aggregation or SLA rollups, and historically a single all-or-nothing FourEOrganizationsAdmin policy rather than role-graded RBAC. The operator UI (platform-admin) has run inside the tenant shell at :tenantSlug/platform.

L3 — Customer ERP + Verticals

What it is for. The actual ERP each tenant uses every day. It is a generic ERP core plus exactly one vertical (industry-specific) pack. Today the two verticals are Factory (Manufacturing / Alfawood, a furniture-cutting workflow) and Insurance Broker. A tenant subscribes to one vertical, and its users live under that vertical.

This is by far the most complete layer. The backend (11+ .NET 10 modules under backend/Modules) is Odoo-competitive per tenant, and the Angular frontend (frontend/angular/erp-saas-angular) mirrors that breadth across ~14 workspaces.

As-built gap

The defining L3 requirement — vertical gating so a Factory tenant cannot see or reach Insurance Broker (and vice versa) — was historically not enforced on the path that matters. As mapped, app.routes.ts had zero route guards, the sidebar was built from a fully static navigation map, and TenantRuntimeContext carried only { tenantSlug } with no vertical or enabledModules. On the backend, RuntimeApiPolicy was only RequireAuthenticatedUser() — no RequireModuleEntitlement requirement — so a Factory-only tenant's valid token could still call /api/insurance-broker/**. The data needed to gate (enabledModules[]) was already fetched by the client but never consumed. The frontend was also evidence-grade, not enterprise-grade (skeletal design system, no chart library, no i18n/RTL, several 3000+ line mega-components). Confirm the current state of gating, design tokens, and i18n against the code before relying on any of these as still-open.

L4 — Executive Portal

What it is for. A separate portal for an owner of multiple companies (say, one factory plus one insurance brokerage). They get one consolidated dashboard, one dashboard per company, and clean buttons to jump into each company's ERP. An owner of a single company simply sees that one dashboard plus one button.

As-built gap

L4 was greenfield at platform-mapping time. There was no owner identity that spans multiple tenants, no cross-company aggregation, no consolidated dashboard, and no "navigate into each company" shell. The 4E model is flat (Organization then N Tenant) with no owner field; Auth's company context is strictly single-tenant; Analytics is hard-scoped per tenant; and Finance cross-company consolidation is setup-metadata only (execution parked per ADR_0002). Note: in this codebase the in-product owner persona is called the Executive Portal / Ownernot "CEO" (that term is reserved for the human delivery-review stakeholder, to avoid a naming collision).


What makes ASAB special

  • Real tenant isolation, defense-in-depth. Every module uses PostgreSQL FORCE ROW LEVEL SECURITY with a fail-closed tenant_isolation policy, bound transaction-scoped, plus tenant-leading composite keys and indexes — proven by per-module Postgres persistence tests. One customer literally cannot read another's rows even if application code has a bug.
  • A genuine control plane, not just a login screen. 4EOrganizationsManager provides durable, resumable, evidence-logged tenant provisioning that most ERP-as-a-SaaS products simply do not have. (Odoo, our business-concept reference, has no comparable operator control plane.)
  • Generic core plus pluggable verticals. The reusable ERP capabilities live in the core; industry packs (ERP.Alfawood, ERP.InsuranceBroker) extend it and must not duplicate or own core behavior. A missing reusable capability is a core backlog item, never a vertical workaround.
  • Disciplined engineering contract. Every module follows the same six-project shape (Entity / Common / Utility / Api / Workers / Tests), CQRS is mandatory (Command/Query plus Handler plus Validator), controllers are HTTP boundaries only, and architecture tests enforce the dependency direction so no module reaches into another module's Entity project. The full protocol lives in AGENTS.md.
  • Built to beat Odoo on the platform, not just the features. The differentiation is airtight multi-tenancy, an operator control plane, and a polished, vertical-gated, multi-company experience as the L1/L3/L4 gaps close.

How to read this handbook

This site is organized so you can move from the big picture down to specific code. New hires should read top to bottom; experienced engineers can jump straight to a section.

SectionWhat you'll learnRead it when
Getting StartedOrientation, environment, and your first steps in the repo.You just joined.
Architecture & How It Fits TogetherThe four layers in depth, the module shape, CQRS, tenancy, messaging, and how a request flows end to end.You want the mental model before touching code.
Core ModulesThe reusable ERP capabilities — Finance, Inventory, Procurement, CRM/Sales, Documents, Workflow, Auth, Master Data, Analytics, Collaboration, and Manufacturing.You're about to work in (or call) a specific module.
Vertical ProductsThe industry packs on top of the core: Factory / Alfawood and Insurance Broker.You're working on vertical-specific behavior.
Platform & Control PlaneThe 4E control plane (L2) that owns the tenant fleet, module entitlements, and durable provisioning.You're working on tenancy, provisioning, or entitlements.
BRD FulfillmentRequirements traceability — which business requirements are met, partial, or open.You need to know what's promised vs. built.
DatabaseSchema and data-model notes, tenant keys, RLS, and indexing conventions.You're designing a migration or a query.
Glossary & ReferenceEvery term defined — tenant, entitlement, vertical, saga, cell, and more.You hit a word you don't know.
How this handbook tells the truth

Throughout these pages, an "As-built gap" warning (like the ones above) marks any place where the running code differs from the design, the BRD, or the four-layer vision. When you see one, trust the code description over the aspiration — and treat the gap as real backlog, not a typo.

Welcome to ASAB. Start with Getting Started, then build the mental model in Architecture.