Skip to content

The platform model

Everything in BreezyCorp hangs off one hierarchy. Understanding it is the single most useful thing before you start clicking around, because it explains what you can see, what work attaches to what, and why isolation between firms is absolute.

Tenant → Group → Entity → Branch

Tenant            the firm (an isolation boundary). Tenant 0 is Spade itself.
  └─ Group        a client relationship — a family of companies under one account manager
       └─ Entity  a legal entity (a company), with its incorporation date, financial year end, GST status
            └─ Branch   a branch or representative office of that entity
  • Tenant — the top of the world. Every record belongs to exactly one tenant, and no role sees across tenants. When BreezyCorp is offered to other firms, each firm is its own tenant; today the firm operates as Tenant 0.
  • Group — how a client is organised. A Group Principal logs in once and sees the whole group; an account manager owns the relationship at this level.
  • Entity — the legal company that work is actually done for. Officers, shareholdings, addresses, business activities, charges, and the controller register all hang off the entity. So do the module artifacts — a payroll cycle, a journal batch, an FS engagement, an XBRL filing.
  • Branch — a foreign or local branch / representative office of an entity, where one exists.

A single client login can therefore resolve to a portfolio across jurisdictions (a group-scoped login) or to one company (an entity-scoped login).

Products attach to entities

A client doesn't buy "the platform" — each entity subscribes to the products it needs (Secretarial, Bookkeeping, Payroll, Tax, FS, XBRL, and so on). That subscription is what makes a product's nav and intake appear for that entity. A payroll-only entity is never asked about a chart of accounts; a bookkeeping-only entity is never asked to confirm XBRL tags.

Tenant isolation is enforced at the database

Isolation is not an application-level filter you have to remember to apply. Every tenant-scoped table carries a tenant_id, and a row-level-security (RLS) policy on the database only returns rows for the current tenant. The platform sets the tenant context per request or per background job; with no context set, the query returns zero rows (fail-closed).

What this means for you:

  • An operator in one tenant cannot read another tenant's data, by construction — not because the UI hides it, but because the database refuses to return it.
  • If you ever see data you shouldn't, that's a serious incident, not a curiosity — follow Tenant leak suspected.

Jurisdiction is data, not code

Singapore is the first jurisdiction and India the second. New jurisdictions arrive as rule packs and form packs — versioned data the platform evaluates — rather than as new branches of code. An entity renders in its jurisdiction's language and rules; a group that spans jurisdictions shows each entity in its own.

The human gate

The hierarchy is where work lives; the human gate is how it moves. Agents prepare proposed actions, but a regulated or external action — a filing, a client dispatch — only happens when a human operator approves it. Client roles supply data, confirm, and sign where they are the lawful signatory, but no client role approves a regulated action. That principle is wired into the roles and explained in The review inbox and the human gate.

Where to go next

Internal use only — BreezyCorp