Adds accounting-service PATCH/archive, fiscal helpers, COA templates and setup status, plus SuperApp Accounting UI (DS, scoreboard, masters, vouchers, ledger, ops modules) with session refresh and HTTPS public API URLs. Co-authored-by: Cursor <cursoragent@cursor.com>
59 lines
2.1 KiB
Markdown
59 lines
2.1 KiB
Markdown
# Multi-Tenant Architecture
|
|
|
|
> Architecture only. Status of onboarding delivery → [progress.md](../progress.md)
|
|
|
|
## Tenant Model
|
|
|
|
A **Tenant** is a workspace/organization on the platform. Users may belong to multiple tenants; `users.current_tenant_id` selects the active workspace.
|
|
|
|
### Lifecycle
|
|
|
|
```
|
|
draft → pending_activation → active → suspended / archived
|
|
```
|
|
|
|
Legacy values `inactive` / `deleted` remain for compatibility.
|
|
|
|
### Operational Roles (Core memberships)
|
|
|
|
`platform_admin`, `tenant_owner`, `tenant_admin`, `tenant_editor`, `tenant_viewer`
|
|
|
|
Membership status: `active` / `invited` / `disabled`. Every active tenant must retain at least one active `tenant_owner`.
|
|
|
|
## Tenant Resolution Order
|
|
|
|
1. Header `X-Tenant-ID`
|
|
2. Header `X-Tenant-Slug`
|
|
3. Subdomain from Host + `PLATFORM_BASE_DOMAIN`
|
|
4. Custom domain from Host
|
|
5. Authenticated user's `current_tenant_id` (when headers/host do not resolve)
|
|
|
|
Results land in `request.state.tenant_id` / `request.state.tenant_slug`. Tenant-aware endpoints use `require_tenant` / `get_tenant_resolution`.
|
|
|
|
## Domains
|
|
|
|
- Auto subdomain: `{slug}.{PLATFORM_BASE_DOMAIN}` (verified when provisioned)
|
|
- Custom domain: stored with `verification_status=pending` until DNS verification ships
|
|
- SSL expansion for tenant hosts: [ADR-009](adr/ADR-009.md)
|
|
|
|
## White-Label
|
|
|
|
Tenant branding fields live on `tenants`. Public tenant-site/theme resolution uses host-based tenant detection. Platform defaults remain env/`theme.config.json` ([ADR-008](adr/ADR-008.md)).
|
|
|
|
## Entitlement
|
|
|
|
`EntitlementService.check_feature_access(tenant_id, feature_key)` — Redis cache then DB. Disabled tenant, inactive subscription, or missing plan feature → deny. Custom access overrides plan.
|
|
|
|
## Hard Rules
|
|
|
|
- No cross-tenant queries.
|
|
- Every business write is tenant-scoped.
|
|
- Authorization for workspace actions uses Core memberships ([ADR-007](adr/ADR-007.md)).
|
|
|
|
## Related Documents
|
|
|
|
- [Identity Architecture](identity-architecture.md)
|
|
- [Authorization Architecture](authorization-architecture.md)
|
|
- [Deployment Architecture](deployment-architecture.md)
|
|
- [Glossary](../glossary.md)
|