TorbatYar/adr-reference.md
Mortezakoohjani 0d424c500a feat(platform): complete commercial runtime consolidation
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>
2026-07-29 11:11:53 +03:30

18 KiB
Raw Blame History

==================== 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

  1. Shared monolithic database with schema prefixes
  2. Schema-per-tenant in one database

==================== 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

  1. Monorepo full-stack Next.js with API routes as primary backend
  2. Server-rendered Django templates

==================== 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

  1. Database-per-tenant
  2. Schema-per-tenant

==================== 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

  1. Direct broker publish in request path
  2. Change-data-capture only

==================== 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

  1. Hardcoded themes per tenant in frontend builds
  2. Separate theme microservice from day one

==================== 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:

  1. Dedicated database loyalty_db (ADR-001)
  2. Permission prefix loyalty.*
  3. Publish-only domain events loyalty.*
  4. Row-level multi-tenancy via tenant_id (ADR-003)
  5. Immutable point ledger as the sole source of balances (Phase 7.2+) — direct balance mutation is forbidden
  6. 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

  1. Loyalty subsystem inside CRM — rejected (CRM is Sales-only; Loyalty is cross-module)
  2. Per-module loyalty tables — rejected (duplication, inconsistent rules)
  3. Shared monolith database schema — rejected (ADR-001)

==================== 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

  1. Introduce communication-service with sole ownership of communication_db (port 8005).
  2. All outbound messaging (SMS first; email/push/social/voice later) goes through this service’s APIs and events.
  3. Provider adapters live only inside Communication.
  4. Dynamic contact sources resolve contacts via remote APIs — never copy business-module rows.
  5. Tenants may activate Communication independently of other business modules.
  6. 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 CommunicationProvider contract 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

  1. Expand sms_panel / notification scaffolds separately — rejected; unified Communication owns multi-channel routing.
  2. Keep providers in each business module — rejected; violates independence and DRY.

==================== 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

  1. 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).
  2. Every implementation phase must satisfy the mandatory Definition of Done.
  3. 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.
  4. CRUD is never sufficient for phase completion.
  5. Before Complete, verify all dimensions in Enterprise Completeness; missing required work is implemented before status change.
  6. 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.
  7. Quality gates, development loop, phase template, handover, testing/documentation templates, master prompt, and Cursor guidelines are updated to encode these rules.
  8. 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

  1. Keep restating enterprise rules in every phase prompt — rejected (drift, omission)
  2. Retroactively refactor all completed services to new package layouts — rejected (out of scope; compatibility)
  3. Treat CRUD + tests as enough for “foundation†phases — rejected (not production-ready)

==================== 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

  1. Adopt Enterprise Phase Discovery as a mandatory stage before Implementation for every phase.
  2. 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.
  3. Discovery MUST derive every missing production-ready capability for the current phase and MUST NOT assume CRUD is sufficient.
  4. Missing current-phase capabilities automatically become implementation work before Complete.
  5. Discovery MUST NOT pull future-phase responsibilities, violate service boundaries, or duplicate another service.
  6. A Discovery Record is required in the phase document; quality gates and Definition of Done fail without it (implementation phases).
  7. 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

  1. Rely only on mandatory-artifact checklists without codebase inventory — rejected (misses drift vs existing code)
  2. Optional discovery “when unclear†— rejected (agents skip under time pressure)
  3. Expand every phase prompt with full discovery instructions — rejected (framework is single source of truth)