Skip to content

BookingZone System Constitution

Universal engineering principles for the entire BookingZone platform. Every repo's local constitution inherits from this file. Repo-specific principles extend, but cannot contradict, the principles below.

Version: 1.0.0 Ratified: 2026-05-03 Scope: All BookingZone platform repositories (see repo-registry.md)

Core Principles

I. Single Source of Truth — Frappe

Frappe (reservation-api-server) is the source of truth for all business domain data. Frontends, kiosks, and adjacent services consume the Frappe API; they do not maintain parallel canonical stores of business entities.

Permitted local data in non-Frappe repos:

  1. Authentication / session state
  2. UI-only operational data (form builder, page builder, AI logs, audit logs)
  3. Caching / indexing of Frappe data (must be explicitly labeled)
  4. Repo-specific operational data with no Frappe equivalent

Forbidden local data in non-Frappe repos:

  • Bookings, customers, outlets, businesses, service items, schedules
  • Payment transactions, gift cards, promo codes, memberships
  • Anything corresponding to an existing BZ* doctype

See ADR-0001 for the full rationale.

II. Multi-Tenant Scope Discipline

The platform operates on a strict tenant hierarchy: Business → Outlet → Customer / Booking.

Every API call, query, and UI element MUST honor this hierarchy:

  • Every business-scoped query is filtered by business, outlet, or both.
  • Cross-tenant queries require explicit System Admin role.
  • Permission checks use the canonical role set: System Admin, Business Admin, Outlet Manager, Customer, Guest.
  • Default permission posture is deny-by-default — every BZ doctype registers permission_query_conditions and has_permission hooks.
  • Multi-outlet managers resolve their active outlet via bookingzone.api.scope_context.resolve_manager_active_outlet.

See ADR-0002 for the tenant model in full.

III. Domain Terminology Is Canonical

Every domain term has exactly one canonical name. The canonical names live in glossary/domain-terms.md.

Examples:

  • "Booking" — never "Reservation", never "Order"
  • "Outlet" — never "Location", never "Branch", never "Site"
  • "Customer" — never "Guest" (Guest = unauthenticated visitor only)
  • "Business" — never "Tenant", never "Account"

Frontends MAY display localized labels to end users, but internal names (API fields, code identifiers, spec text) MUST use canonical terms.

IV. Type Safety End-to-End

All TypeScript repos run strict mode. All Python repos use type hints.

Cross-repo contracts are enforced via:

  1. Backend publishes OpenAPI spec from @frappe.whitelist() methods.
  2. Generated TypeScript types are published as @bookingzone/api-types.
  3. Frontends pin a version of @bookingzone/api-types and CI fails on breaking-change without an explicit version bump.

See ADR-0005 for the contract pipeline.

V. Spec-Driven Development

Net-new features and substantive changes follow Spec-Kit phases: specify → plan → tasks → analyze → implement.

Cross-cutting features (touching 2+ repos) follow the master/trace pattern:

  • One master spec lives in bz-platform-context/specs/SYS-NNN-*/.
  • Each impacted repo creates a trace spec in its local specs/ pointing to the master.
  • A repo-impact note (bz-platform-context/specs/SYS-NNN-*/repo-impact/<repo>.md) describes what changes in each repo.

Bug fixes, refactors under ~50 LOC, and dependency upgrades may skip the spec flow but MUST link the PR to the related spec or ADR.

See ADR-0004 for the spec-driven workflow.

VI. Audit & Observability (PCI / SOC-2 ready)

  • All payment operations log to BZPaymentTransaction with PCI-safe redaction (no PAN, no CVV, no full card token in plain logs).
  • All sensitive admin operations (refunds, role changes, cancellations) emit a structured audit log entry.
  • All AI-generated content (page builder, form builder, AI QA) writes a prompt+output audit row.
  • Errors propagate via structured loggers, not silent catch {} blocks.
  • Frontend errors surface to users (toast) AND log to the server.

VII. Idempotency & Resource Safety

  • Payment operations carry an idempotency_key; replay returns the original result, never a duplicate charge.
  • Resource locking uses bookingzone.api.lock_manager.atomic_lock_resources with SELECT FOR UPDATE semantics — no TOCTOU patterns.
  • All scheduler jobs are wrapped in try/except; one failure does not cascade.
  • Background jobs use deterministic deduplication keys.

VIII. Timezone Discipline

  • All datetimes are stored as UTC in the database.
  • All datetimes are displayed in the outlet timezone.
  • Conversions go through bookingzone.services.timezone_service.tz_service.
  • API responses include the timezone identifier alongside any local time.

IX. Communication Channel Routing

Channel selection is fixed across the platform:

Channel Use For Do NOT Use For
OpenPhone All booking-related SMS and calls (confirmations, reminders) Marketing
SlickText One-off marketing campaigns Booking workflows
GoHighLevel (GHL) Email delivery + CRM contact sync Transactional SMS
AWS SES / Frappe email System emails (password reset, alerts) Marketing
Twilio / SNS Permitted as fallback in notifications service Direct use outside notifications service

X. Naming Conventions

Artifact Convention Example
Frappe DocTypes BZ prefix + PascalCase BZBooking, BZOutlet
Frappe API methods bookingzone.api.<module>.<snake_case> bookingzone.api.booking.create_booking
Python files snake_case payment_service.py
Python classes PascalCase BookingService
TS components PascalCase BookingDetail.tsx
TS files (non-component) kebab-case frappe-client.ts
Cross-cutting spec IDs SYS-NNN-<slug> SYS-001-ghl-outlet-mapping
Repo-local spec IDs NNN-<slug> 042-cognito-sso

XI. Backward Compatibility & Defensive Coding

  • DocType field access uses getattr(doc, 'field', default) — old records may lack newer fields.
  • Existence checks (frappe.db.exists) precede frappe.get_doc.
  • All public DocType fields with safe defaults; reqd: 1 only when truly mandatory.
  • Schema migrations include backward-compatible patches.
  • Breaking API changes require a major version bump in @bookingzone/api-types.

Governance

  • This constitution supersedes ad-hoc rules in scattered markdown files across all repos.
  • Amendments require: PR to this file + version bump + entry in Amendment Log + 2 maintainer approvals.
  • A repo's local constitution MAY add stricter principles but MUST NOT contradict any principle here.
  • Specs and PRs that conflict with a principle MUST either bring themselves into compliance or propose a constitution amendment in the same PR.

Amendment Log

Version Date Change
1.0.0 2026-05-03 Initial ratification. Extracted system-level principles from bookingzone-frappe-context.mdc and supporting rule files.