ADR-0010: Zero Runtime Dependency Between Rental and Booking¶
Status: Accepted
Date: 2026-09-05
Deciders: Anil Kumar Pandey (approved), Staff Architect
Impacted Repos: rental-api-server, reservation-api-server
Supersedes: ADR-0009
Context¶
ADR-0009 established that
rental-api-server runs as an isolated Frappe stack with its own VPC, RDS, and
ECS cluster. Cross-references to BookingZone entities were stored as Data fields
(string IDs) and resolved via HTTPS calls to reservation-api-server.
After operating under this model, several concerns emerged:
-
Runtime coupling via HTTP: While the stacks were physically isolated, rental still depended on
reservation-api-serveravailability for reference resolution. This created an operational dependency that undermined the isolation goal. -
Locker domain ownership ambiguity:
BZLocker*DocTypes (BZLockerUnit, BZLockerBank, BZLockerRental, etc.) were still residing inreservation-api-serverbut are primarily consumed by the rental workflow. This split ownership created confusion about which team maintains these entities. -
Unnecessary coupling surface: Requiring HTTPS calls for cross-references means rental availability depends on booking availability, defeating the fault isolation benefits.
Decision¶
-
rental-api-serverandreservation-api-serverhave ZERO runtime dependency. Neither service requires the other to be available for normal operation. No mandatory HTTP calls between the two services. -
Cross-references use opaque Data IDs only. When rental needs to reference a booking entity, it stores the ID as an opaque string. Resolution (if needed) happens out-of-band — via background sync jobs, data exports, or operator lookup — not as part of the request path.
-
No Frappe Link fields between domains. This remains from ADR-0009 but is now explicit: Link fields create schema coupling and are prohibited.
-
BZLocker*DocTypes move torental-api-server. The locker domain (BZLockerUnit, BZLockerBank, BZLockerRental, BZLockerReservation, and related DocTypes) is owned byrental-api-server. BookingZone focuses on booking + 100% test coverage. -
Optional future sync is out-of-band. If cross-domain reporting or analytics requires combined data, this happens via:
- Scheduled batch exports
- Data warehouse ETL
- Operator-initiated lookups
These are explicitly NOT request-path dependencies.
- Infrastructure isolation from ADR-0009 remains in effect. Separate VPCs, RDS instances, ECS clusters — no VPC peering.
Consequences¶
Positive¶
- True fault isolation: Rental operates independently; booking outages do not cascade to rental workflows.
- Clear domain ownership: Locker domain has a single owner
(
rental-api-server), eliminating cross-team coordination overhead. - Simpler operational model: No need to monitor cross-service HTTP health as a dependency.
- Independent scaling and deployment: Each team ships on their own schedule with no runtime coordination required.
Negative / Trade-offs¶
- No real-time cross-domain queries: Operators cannot get live booking details from within the rental UI without switching systems.
- Data staleness in reports: Cross-domain reports depend on sync job frequency.
- Migration effort: Moving BZLocker* to rental requires data migration and client updates.
Risks / Mitigations¶
-
Risk: Orphan MariaDB tables after migration. Mitigation: After deleting
BZLocker*andBZRental*DocTypes fromreservation-api-server, operators must manually drop orphan tables. Migration runbook will include explicitDROP TABLEinstructions. -
Risk: Stale opaque IDs if booking entities are deleted. Mitigation: Rental treats external IDs as opaque references; validation is the operator's responsibility via periodic audit reports.
-
Risk: Clients still calling deprecated rental endpoints on
reservation-api-server. Mitigation: 501 shims (from ADR-0009 / reservation-api-server#893) remain until all clients migrate. Add monitoring for 501 response volume.
Alternatives Considered¶
-
Keep HTTPS cross-references (ADR-0009 status quo): Rejected. Introduces runtime coupling that undermines isolation goals.
-
Shared read replica for cross-domain queries: Rejected. Adds operational complexity; read replicas still create a dependency path.
-
Keep locker in booking, add rental-specific locker DocTypes: Rejected. Duplicates domain logic; locker is fundamentally a rental concern.
Implementation Notes¶
Migration Checklist¶
- Create
BZLocker*DocTypes inrental-api-serverwith matching schema. - Migrate data from
reservation-api-serverMariaDB to rental RDS. - Update all rental clients to call
rental-api-serverfor locker operations. - Remove
BZLocker*DocTypes fromreservation-api-servercodebase. - Operator action required: Drop orphan MariaDB tables from
reservation-api-serverRDS:
Cross-Reference Pattern (Updated)¶
# rental-api-server: storing an opaque reference
rental_doc.booking_id = "BK-2026-00123" # Opaque Data field
rental_doc.save()
# Resolution is OUT-OF-BAND, not request-path:
# - Background sync job copies relevant booking metadata to rental
# - Operator looks up booking in separate admin UI if needed
# - Reports join data at the warehouse layer
Infrastructure Layout (Unchanged from ADR-0009)¶
| Component | BookingZone | Rental | Insurance |
|---|---|---|---|
| VPC CIDR | 10.0.0.0/16 | 10.30.0.0/16 | 10.20.0.0/16 |
| ECS Cluster | bookingzone-dev-cluster |
rental-dev-cluster |
insurance-dev-cluster |
| RDS | Shared MariaDB | Own MariaDB | Own MariaDB |
| ECR | bookingzone-dev-frappe |
rental-dev-frappe |
insurance-dev-frappe |
References¶
- ADR-0009 — Superseded; original isolation decision with HTTPS cross-references
- ADR-0001 — Frappe as source of truth (remains binding for booking domain)
- ADR-0005 — Published API contracts
- repo-registry.md — Repository registry with isolation details
- reservation-api-server#893 — 501 shim implementation