Unify commercial runtime ownership across backend and frontend so platform, experience, and hospitality modules use the shared commercial source of truth. Co-authored-by: Cursor <cursoragent@cursor.com>
18 KiB
==================== FILE: F:\TorbatYar\docs\architecture\adr\ADR-001.md
ADR-001: Database-per-Service
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2025-01-01 |
| Deciders | Platform Architecture |
| Supersedes | — |
| Superseded by | — |
Context
TorbatYar is a multi-tenant SuperApp that will grow to many business modules. Shared databases create tight coupling, migration contention, and cross-team schema conflicts.
Decision
Every service owns exactly one database. Cross-service data access is forbidden. Services communicate only via REST API, Webhook, Async Event, and Outbox/Inbox.
Consequences
Positive
- Independent schema evolution per service
- Clear ownership boundaries
- Microservice-ready from day one
Negative
- No cross-DB joins; eventual consistency required
- Duplicate reference data must be synchronized via events/APIs
Neutral
- Core Platform database (
core_platform_db) remains the registry for tenants, plans, entitlements, and service discovery
Alternatives Considered
- Shared monolithic database with schema prefixes
- Schema-per-tenant in one database
Related Documents
==================== FILE: F:\TorbatYar\docs\architecture\adr\ADR-002.md
ADR-002: Strict Frontend / Backend Separation
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2025-01-01 |
| Deciders | Platform Architecture |
| Supersedes | — |
| Superseded by | — |
Context
Mixing UI and server logic in one deployable unit blocks independent scaling, white-label hosting, and multi-client UIs.
Decision
Backend lives only under backend/. Frontend lives only under frontend/. Communication is exclusively through versioned REST APIs (and future WebSocket if needed). No shared source except contracts, schemas, generated SDKs, and type definitions.
Consequences
Positive
- Independent deploy and scale
- Clear ownership of business logic (backend only)
- Multiple UIs can share the same APIs
Negative
- Requires disciplined API versioning
- Local DX needs Docker or two runtimes
Alternatives Considered
- Monorepo full-stack Next.js with API routes as primary backend
- Server-rendered Django templates
Related Documents
==================== FILE: F:\TorbatYar\docs\architecture\adr\ADR-003.md
ADR-003: Row-Level Multi-Tenancy with tenant_id
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2025-01-01 |
| Deciders | Platform Architecture |
| Supersedes | — |
| Superseded by | — |
Context
Every business module must isolate tenant data. Database-per-tenant is operationally heavy for early phases.
Decision
Use shared databases per service with mandatory tenant_id on every business table. Tenant resolution order: X-Tenant-ID → X-Tenant-Slug → subdomain → custom domain → user current_tenant_id. Cross-tenant queries are forbidden.
Consequences
Positive
- Simple ops on a single DB per service
- Consistent middleware and repository filters
- Compatible with subdomain and custom-domain white-label
Negative
- Requires rigorous tenant filters in every query
- Noise-neighbor risk at very large scale (future mitigation possible)
Alternatives Considered
- Database-per-tenant
- Schema-per-tenant
Related Documents
==================== FILE: F:\TorbatYar\docs\architecture\adr\ADR-006.md
ADR-006: Transactional Outbox / Inbox for Events
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2025-01-01 |
| Deciders | Platform Architecture |
| Supersedes | — |
| Superseded by | — |
Context
Services must publish domain events reliably without dual-write failures between DB commits and message brokers.
Decision
Every service that emits events writes to outbox_events in the same business transaction. A worker processes pending outbox rows. Consumers record inbox_events by event_id for idempotency. Event envelope is shared.events.EventEnvelope.
Consequences
Positive
- Atomic business + event persistence
- Idempotent consumption
- Message-bus swap later without rewriting producers
Negative
- Near-real-time, not hard real-time
- Requires Celery/worker ops
Alternatives Considered
- Direct broker publish in request path
- Change-data-capture only
Related Documents
==================== FILE: F:\TorbatYar\docs\architecture\adr\ADR-008.md
ADR-008: White-Label Branding via Config and Tenant Profile
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2025-01-01 |
| Deciders | Product + Platform Architecture |
| Supersedes | — |
| Superseded by | — |
Context
The platform must serve many tenant brands without hardcoding colors, logos, or names in source.
Decision
Platform brand defaults come from environment / theme.config.json. Tenant brand fields live on tenants (primary_color, secondary_color, logo_url, favicon_url, …). Frontend applies CSS variables. Public tenant-site APIs resolve theme by host for subdomain/custom-domain experiences.
Consequences
Positive
- Brand changes without rebuild
- Tenant onboarding captures brand early
Negative
- Runtime theme loading must stay cacheable and tenant-safe
Alternatives Considered
- Hardcoded themes per tenant in frontend builds
- Separate theme microservice from day one
Related Documents
==================== FILE: F:\TorbatYar\docs\architecture\adr\ADR-011.md
ADR-011: Independent Enterprise Loyalty Platform Service
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2026-07-24 |
| Deciders | Platform Architecture |
| Supersedes | — |
| Superseded by | — |
Context
Multiple business modules (Restaurant, Marketplace, Ecommerce, Academy, Booking, Healthcare, Salon, Gym, and future modules) need loyalty, points, rewards, campaigns, referrals, wallets, and gift cards. Embedding loyalty inside CRM or any single business module would couple unrelated domains and prevent reuse.
Decision
Loyalty is an independent shared platform service (loyalty-service) with:
- Dedicated database
loyalty_db(ADR-001) - Permission prefix
loyalty.* - Publish-only domain events
loyalty.* - Row-level multi-tenancy via
tenant_id(ADR-003) - Immutable point ledger as the sole source of balances (Phase 7.2+) — direct balance mutation is forbidden
- Consumption by business modules via REST API + Events only — never via shared tables or CRM ownership
Loyalty must not belong to CRM, Restaurant, or Ecommerce.
Consequences
Positive
- Reusable loyalty across all business modules
- Clear ownership and independent schema evolution
- Enforceable ledger / audit invariants
Negative
- Modules must integrate asynchronously for eventual consistency of customer 360 views
- Cross-module references use external IDs / refs only
Neutral
- Phase 7.0 ships foundation aggregates; engines (membership, points, rewards, campaigns, referral, wallet, gift card, analytics, public APIs) land in Phases 7.1–7.9
Alternatives Considered
- Loyalty subsystem inside CRM — rejected (CRM is Sales-only; Loyalty is cross-module)
- Per-module loyalty tables — rejected (duplication, inconsistent rules)
- Shared monolith database schema — rejected (ADR-001)
Related Documents
- Module Boundaries
- Database Architecture
- ADR-001 آ· ADR-003 آ· ADR-006
- Loyalty Phase 7.0
- Module Registry — loyalty
==================== FILE: F:\TorbatYar\docs\architecture\adr\ADR-012.md
ADR-012: Independent Enterprise Communication Platform
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2026-07-24 |
| Deciders | Platform Architecture |
| Supersedes | — |
| Superseded by | — |
Context
Business modules (CRM, Loyalty, Restaurant, etc.) need SMS and future channels. Putting providers inside each module would duplicate credentials, break failover consistency, and couple tenants to modules they may not subscribe to.
Core already sends auth OTP via Payamak — that auth path stays separate for now, but platform messaging must be a shared infrastructure service.
Decision
- Introduce
communication-servicewith sole ownership ofcommunication_db(port 8005). - All outbound messaging (SMS first; email/push/social/voice later) goes through this service’s APIs and events.
- Provider adapters live only inside Communication.
- Dynamic contact sources resolve contacts via remote APIs — never copy business-module rows.
- Tenants may activate Communication independently of other business modules.
- Failures are tracked asynchronously; they must not abort calling business transactions.
Consequences
Positive
- Single provider registry, failover, templates, OTP, audit, and monitoring
- Clear module boundary for CRM
CommunicationProvidercontract fulfillment - Extensible channel model without rewriting consumers
Negative
- Additional deployable service and database
- Eventual consistency for delivery status
Neutral
- Core auth OTP may later hand off to Communication when explicitly migrated
Alternatives Considered
- Expand
sms_panel/notificationscaffolds separately — rejected; unified Communication owns multi-channel routing. - Keep providers in each business module — rejected; violates independence and DRY.
Related Documents
==================== FILE: F:\TorbatYar\docs\architecture\adr\ADR-018.md
ADR-018: Enterprise Completeness Mandate for the AI Development Framework
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2026-07-25 |
| Deciders | Platform Architecture |
| Supersedes | — |
| Superseded by | — |
| Extends | ADR-013 |
Context
ADR-013 established the permanent AI Development Framework under docs/ai-framework/. Subsequent service phases still risked shipping CRUD-shaped slices without full production readiness (commands/queries, policies, specifications, OpenAPI, metrics, enterprise completeness verification) unless each phase prompt restated those expectations.
The framework must become the single source of truth so every future phase of every future service is production-ready by default, without additional prompting.
This ADR does not change completed business phases or modify business implementations. It upgrades process documentation and execution rules only.
Decision
- Elevate the AI Development Framework into an Enterprise Development Framework (same folder
docs/ai-framework/for backward compatibility; “AI Development Framework†remains the historical name). - Every implementation phase must satisfy the mandatory Definition of Done.
- Every implementation phase automatically includes the Mandatory Phase Artifacts (Business Analysis through Self Audit), deriving missing technical components from high-level roadmap text while remaining inside the current phase.
- CRUD is never sufficient for phase completion.
- Before Complete, verify all dimensions in Enterprise Completeness; missing required work is implemented before status change.
- Enforce Boundary Rules: no foreign service ownership, no logic duplication, no cross-DB access, integrate only via APIs/Events/Providers, never pull future-phase features forward.
- Quality gates, development loop, phase template, handover, testing/documentation templates, master prompt, and Cursor guidelines are updated to encode these rules.
- Completed business phases and existing business code are not retroactively rewritten by this ADR.
Consequences
Positive
- Production readiness becomes the default outcome of every phase
- Phase prompts stay thin; permanent rules live once in the framework
- Clear Completeness / DoD / Boundary vocabulary for agents and reviewers
Negative
- Higher documentation and verification effort per phase (intentional)
Neutral
- Path
docs/ai-framework/retained for compatibility; enterprise docs added alongside - ADR-013 remains Accepted; this ADR extends it
Alternatives Considered
- Keep restating enterprise rules in every phase prompt — rejected (drift, omission)
- Retroactively refactor all completed services to new package layouts — rejected (out of scope; compatibility)
- Treat CRUD + tests as enough for “foundation†phases — rejected (not production-ready)
Related Documents
- ADR-013
- AI / Enterprise Framework README
- Definition of Done
- Mandatory Phase Artifacts
- Enterprise Completeness
- Boundary Rules
- Quality Gates
- Development Loop
- Enterprise Phase Discovery
- Project Principles
- ADR-019 — Mandatory Enterprise Phase Discovery
==================== FILE: F:\TorbatYar\docs\architecture\adr\ADR-019.md
ADR-019: Mandatory Enterprise Phase Discovery
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2026-07-26 |
| Deciders | Platform Architecture |
| Supersedes | — |
| Superseded by | — |
| Extends | ADR-018, ADR-013 |
Context
ADR-018 made enterprise production readiness the default via Definition of Done, mandatory artifacts, completeness verification, and boundary rules. Agents could still begin implementation from a thin phase brief and under-derive scope—shipping CRUD-shaped work while missing policies, events, list UX, ops surfaces, or other current-phase responsibilities that already existed partially in the codebase or roadmap.
The Framework needs an explicit, mandatory Enterprise Phase Discovery stage that inspects roadmap, architecture, boundaries, prior handover, and the live codebase/APIs/domain/events/permissions/tests/docs before coding, then promotes every missing current-phase production capability into Scope.
This ADR does not implement business features and does not retrofit completed business phases.
Decision
- Adopt Enterprise Phase Discovery as a mandatory stage before Implementation for every phase.
- Discovery MUST use the full input set: Current Roadmap, Current Architecture, Service Boundaries, Previous Phase Handover, Existing Codebase, Existing APIs, Existing Domain Model, Existing Events, Existing Permissions, Existing Aggregates, Existing Tests, Existing Documentation.
- Discovery MUST derive every missing production-ready capability for the current phase and MUST NOT assume CRUD is sufficient.
- Missing current-phase capabilities automatically become implementation work before Complete.
- Discovery MUST NOT pull future-phase responsibilities, violate service boundaries, or duplicate another service.
- A Discovery Record is required in the phase document; quality gates and Definition of Done fail without it (implementation phases).
- Framework loop, gates, templates, master prompt, and Cursor guidelines are updated accordingly.
Consequences
Positive
- Phase responsibility is evidence-based (docs + code), not prompt-guessed
- Gaps are closed inside the phase instead of deferred as TODOs
- Boundary and anti-duplication checks happen before code is written
Negative
- Slightly longer pre-implementation analysis (intentional)
Neutral
- Docs-only phases still produce a Discovery Record against documentation/manifests
- ADR-013 and ADR-018 remain Accepted; this ADR extends them
Alternatives Considered
- Rely only on mandatory-artifact checklists without codebase inventory — rejected (misses drift vs existing code)
- Optional discovery “when unclear†— rejected (agents skip under time pressure)
- Expand every phase prompt with full discovery instructions — rejected (framework is single source of truth)