Skip to Content
Multi-Company

Multi-Company

Arkan ERP supports running multiple companies within a single tenant. Each company has fully isolated data while sharing the same user accounts and platform infrastructure.

Architecture

Tenant (Organization) -> Company A (e.g., Holding Co.) -> Company B (e.g., Subsidiary 1) -> Company C (e.g., Subsidiary 2)
  • Users belong to the tenant and can be granted access to one or more companies
  • All data (transactions, records, settings) is scoped to a specific company
  • Users switch between companies without logging out

Company Switching

The active company is set via the X-Company-Id HTTP header on every API request. The frontend provides a company switcher in the top navigation bar.

# Request scoped to Company A curl -H "Authorization: Bearer TOKEN" \ -H "X-Company-Id: company-a-uuid" \ https://api.arkanerp.com/api/v1/projects # Switch to Company B -- just change the header curl -H "Authorization: Bearer TOKEN" \ -H "X-Company-Id: company-b-uuid" \ https://api.arkanerp.com/api/v1/projects

7 Layers of Isolation

Company data isolation is enforced at every level of the stack:

LayerMechanismPurpose
1. HTTP HeaderX-Company-Id extractionIdentify target company
2. Access GuardCompanyGuardVerify user has access to the company
3. Application ScopeCompanyScope Prisma middlewareAuto-inject company_id in all queries
4. Event ContextDomainEvent carries companyIdEnsure events are processed in correct context
5. CHECK ConstraintCHECK (company_id IS NOT NULL)Prevent null company references (27 tables)
6. Foreign KeysON DELETE RESTRICTPrevent cross-company cascade deletes (23 tables)
7. Row-Level SecurityPostgreSQL RLS policiesDatabase-level enforcement (8 tables)

Even if application code has a bug, layers 5-7 prevent data leakage at the database level.

Consolidated Reporting

View aggregated data across all companies you have access to:

  • Consolidated P&L — Combined revenue and expenses across companies
  • Consolidated Balance Sheet — Aggregated assets, liabilities, and equity
  • Cross-company dashboard — KPIs summed or averaged across companies
  • Intercompany eliminations — Automatically exclude intercompany transactions from consolidated views

Intercompany Transactions

Record transactions between companies within the same tenant:

  1. Company A creates an intercompany invoice to Company B
  2. The system creates matching records in both companies:
    • Company A: Accounts Receivable entry
    • Company B: Accounts Payable entry
  3. On payment, both sides are settled automatically
  4. Consolidated reports eliminate these transactions to avoid double-counting

Company Settings

Each company has independent configuration:

SettingDescription
Company nameLegal entity name
CurrencyBase currency for transactions
Fiscal yearStart month for financial periods
Tax configurationVAT rates and tax codes
Chart of accountsIndependent account structure
Number sequencesInvoice, PO, and document numbering
Logo and brandingPer-company branding on documents
Active modulesEach company can enable different modules

User Access

Users are granted company access with specific roles:

User: ahmed@company.com -> Company A: Admin -> Company B: Member -> Company C: (no access)

A user’s role can differ per company. See Permissions for role details.

API Endpoints

MethodPathDescription
GET/companiesList companies the user can access
POST/companiesCreate a new company
GET/companies/:idGet company details
PATCH/companies/:idUpdate company settings
POST/companies/:id/switchSet active company context
Last updated on