03 · Data plane
True multi-tenant isolation: one dedicated database set per tenant, plus a platform master database.
Database topology
flowchart TB
subgraph MASTER["Master DB e.g. ppos-cloudfresh-dev"]
T[Tenants]
TE[tenant_employees]
PPC[platform_product_catalog]
end
subgraph TENANT["Per tenant slug e.g. mariospizza"]
M["dev-{slug}
POS · inventory · invoices · KDS
tickets · gift · signage · …"]
A["dev-analytics-{slug}
audit_logs · analytics services"]
H["dev-hr-{slug}
employees · payroll · PTO"]
end
API[Express getTenantConnection / multiDatabaseManager] --> MASTER
API --> M
API --> A
API --> H
PPC -.enrich.-> M
What lives where
| DB | Examples | Access notes |
|---|---|---|
| Master | Tenants, platform catalog, employee→tenant routing | Platform + routing only |
| Tenant main | pos_carts, Invoices, InventoryItems, kitchen_tickets, Signage*, Staff, tickets… | Day-to-day ops |
| Tenant analytics | audit_logs, sales/pos/customer analytics sinks | High-volume / reporting |
| Tenant HR | employees, payroll_runs, W4, benefits, PTO | Compliance separation |
Isolation risk model
Cross-tenant leakage is mainly a tenant resolution bug (wrong DB selected), not a missing
WHERE tenant_id on shared tables. Master-admin can cross tenants by design via master-admin routes (audited for mutations).
Code anchors
| Concern | File |
|---|---|
| Tenant pools | backend/config/tenantDatabase.js |
| HR/analytics naming | backend/config/multiDatabaseManager.js |
| Provisioning | backend/services/comprehensiveTenantProvisioning.js |
| Platform catalog | backend/services/platformProductCatalog.service.js |