Appearance
ADR: Organization / Sub-organization / Outlet ownership v1
Status
Accepted
Date
2026-06-25
Context
MyHoreca Pay needs one ownership model for RBAC, delete/retention decisions, counterparty matching rules, and Syrve/iiko mapping. Without a shared model, agents and future tasks can accidentally use different scopes for bank imports, normalized transactions, matching rules, allocations, postings, reconciliation, and audit.
The final UI and product term for the operational endpoint is Outlet. Do not replace it with Location in user-facing product terminology unless a later ADR changes this decision.
Organization and Sub-organization are tenant/business ownership levels. Outlet is the operational/product endpoint where day-to-day bank import, allocation, Syrve/iiko mapping, posting, reconciliation, and review work may become scoped when the Outlet is known.
An Organization may have zero or more Outlets. An Organization may also have child organizations. A child Sub-organization is not a fully independent tenant: it inherits rules and parent administrative control as defined in this ADR.
Decision
The ownership model is:
text
Platform
- Organization
- Sub-organization
- Outlet
- OutletWe accept these rules:
OrganizationIdis required for business data.OutletIdis nullable when the object is organization-level or when the Outlet is not yet safely resolved.- Matching rules are inherited from the parent organization by child organizations.
- Parent
OrganizationAdminautomatically receivesOrganizationAdminrights in child organizations. - A child organization is not treated as a fully standalone tenant for inheritance, audit, matching rules, or administrative control.
LocationAdmin/ outlet-scoped admin is not part of the MVP and must not be required for the MVP workflow.
Terminology
| Term | Meaning |
|---|---|
| Platform | MyHoreca Pay operator scope. Platform roles manage global settings, quotas, pilot enablement, and production safety gates. |
| Organization | Primary customer/business ownership scope. Business data must have an OrganizationId. |
| Sub-organization | Child organization under a parent Organization. It has its own business scope but inherits parent rules and parent OrganizationAdmin authority. |
| Outlet | Final UI/product term for an operational endpoint such as a restaurant, branch, or work location. An Outlet belongs to an Organization or Sub-organization and may be unresolved during import/matching. |
Ownership table
| Entity | OrganizationId | OutletId | Notes |
|---|---|---|---|
| Organization user / role assignment | Required | Nullable | Organization-level RBAC; parent OrganizationAdmin applies to child organizations. |
| Bank import batch | Required | Nullable | Outlet may be unresolved during import. |
| Normalized transaction | Required | Nullable | Transaction can stay organization-level until matching resolves Outlet. |
| Counterparty matching rule | Required | Nullable | Organization-level rules are inherited by child organizations; Outlet-specific rules may override only when explicitly designed later. |
| Syrve/iiko connection settings | Required | Nullable | Organization-level by default; Outlet-specific mapping may be added when Outlet is known. |
| Syrve/iiko document mapping | Required | Nullable | Needs review if Outlet cannot be resolved safely. |
| Payment allocation | Required | Nullable | Allocation must not force fake Outlet assignment. |
| Posting approval / safety gate | Required | Nullable | Must preserve audit and scope. |
| Reconciliation result | Required | Nullable | Follows the transaction/allocation ownership scope. |
| Audit entry | Required | Nullable | Must preserve acting user, organization scope, optional Outlet scope, and inherited-admin context when relevant. |
NeedsReview when Outlet is unresolved
If Outlet is not determined safely, the object remains organization-scoped with OutletId = null.
The workflow must not assign a fake Outlet, default Outlet, or guessed Outlet only to satisfy a non-null field. Ambiguous or unresolved Outlet state must be represented explicitly as NeedsReview or an equivalent review-required status in future implementation tasks.
Allocation or posting to Syrve/iiko must be blocked or require explicit review when the selected mapping requires an Outlet and the product cannot resolve it safely.
Audit must record why review was required, including whether the reason was missing Outlet evidence, ambiguous Outlet candidates, inherited rule conflict, or unsafe Syrve/iiko mapping.
RBAC consequences
- Parent
OrganizationAdminreceives admin rights in child organizations automatically. - Inherited rights must not erase the audit trail. Audit entries must preserve the acting user, the effective organization scope, and whether access came from parent-admin inheritance.
- Child organization is not considered a fully independent tenant for matching rule inheritance, ownership reasoning, or parent admin access.
LocationAdmin/ outlet-scoped admin is not part of MVP and must not be required for the MVP bank import, matching, allocation, posting review, reconciliation, or anomaly workflow.- Future outlet-scoped administration requires a separate ADR or an update to this ADR.
- For mandatory active organization/Outlet context and platform-role operational gating, see ADR: RBAC and tenancy v2.
Delete / retention consequences
- Delete on Organization or Sub-organization must consider child organizations, Outlets, and all business data under that scope.
- Soft-delete, archive, or suspension is preferred over physical deletion for financial records.
- Financial and audit entities must retain ownership scope after deletion/archive decisions so historical evidence remains explainable.
- Hard delete of financial records, audit entries, bank imports, allocations, postings, reconciliation results, or anomaly evidence requires a separate safety decision and must not be introduced silently.
Syrve/iiko mapping consequences
- Syrve/iiko mapping always has an
OrganizationId. OutletIdmay remain nullable until an Outlet is known and safe to apply.- If the product cannot safely determine Outlet for a mapping that needs it, the object must move to
NeedsReview. - Unsafe posting must not execute without a resolved or explicitly reviewed mapping.
- Syrve/iiko connection settings may be organization-level by default. Outlet-specific mapping can be added only when product behavior and safety checks are explicit.
Non-goals
- Do not change runtime backend/frontend code.
- Do not add migrations.
- Do not add new roles to MVP.
- Do not add real bank files, secrets, raw bank lines, full account numbers, or private customer data.
- Do not accept new business decisions outside this ADR.
How AI agents must use this ADR
- Read this ADR before tasks related to RBAC, tenancy, matching, delete/retention, Syrve/iiko mapping, audit, ownership fields, import scoping, allocation scoping, posting gates, or reconciliation scope.
- Do not replace Outlet back to Location in UI/product terminology.
- Do not make
OutletIdmandatory for all business entities. - Do not treat child organization as a fully independent tenant.
- For mandatory active organization/Outlet context and platform-role operational gating, see ADR: RBAC and tenancy v2.
- If a task conflicts with this ADR, propose a new ADR or an update to this ADR before changing docs, code, schema, or product behavior silently.
- Keep runtime code unchanged in ADR-only tasks.
Consequences
- Future RBAC and tenancy work must model parent-child organization inheritance explicitly.
- Business entities should be organization-owned first, with optional Outlet scope when known.
- Import and matching workflows can proceed at organization scope while Outlet remains unresolved, but unsafe Syrve/iiko allocation/posting must require review.
- Audit must be able to explain inherited admin access and unresolved Outlet review decisions.
- MVP remains Accountant-led and must not depend on
LocationAdminor any outlet-scoped admin role.