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:
- Authentication / session state
- UI-only operational data (form builder, page builder, AI logs, audit logs)
- Caching / indexing of Frappe data (must be explicitly labeled)
- 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_conditionsandhas_permissionhooks. - 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:
- Backend publishes OpenAPI spec from
@frappe.whitelist()methods. - Generated TypeScript types are published as
@bookingzone/api-types. - Frontends pin a version of
@bookingzone/api-typesand 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
BZPaymentTransactionwith 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_resourceswithSELECT FOR UPDATEsemantics — 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) precedefrappe.get_doc. - All public DocType fields with safe defaults;
reqd: 1only 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. |