Skip to content

ADR-0009: Isolated Rental Frappe Stack

Status: Superseded by ADR-0010 Date: 2026-09-03 Deciders: Anil Kumar Pandey (approved), Staff Architect Impacted Repos: rental-api-server, reservation-api-server

Context

The rental domain (BZRental* DocTypes) was originally developed as part of the BookingZone Frappe application. As the rental product matured, several concerns emerged:

  1. Schema coupling: Rental DocTypes used Frappe Link fields to BookingZone entities (BZBooking, BZOutlet, BZCustomer, BZLockerUnit, BZVenue, BZServiceItem). This created tight coupling at the database level.

  2. Deployment coupling: Rental and booking changes had to deploy together, even when changes were independent.

  3. Blast radius: A rental-specific bug or migration could impact booking availability, which is the core revenue path.

  4. Team autonomy: The rental team needed freedom to iterate on their domain without coordinating every database change with the booking team.

The insurance ecosystem (insurance-ecosystem-frappe) faces similar isolation needs — it runs RiskBridge / god-agent / company listing / research features that have no business being in the booking SoT.

Decision

  1. rental-api-server runs as an isolated Frappe v15 application with its own:
  2. VPC (10.30.0.0/16)
  3. RDS MariaDB instance
  4. ECS cluster (rental-dev-cluster)
  5. ECR repository (rental-dev-frappe)
  6. CodePipeline (rental-dev-pipeline)

  7. Do not install bookingzone app on rental RDS. The rental database contains only frappe, erpnext (if needed), and rental apps.

  8. Do not VPC-peer for Frappe Links. Cross-references to BookingZone entities (BZBooking, BZOutlet, BZCustomer, BZLockerUnit, BZVenue, BZServiceItem) are stored as Data fields (string IDs), not Link fields. Resolution happens via HTTPS calls to reservation-api-server.

  9. insurance-ecosystem-frappe follows the same isolation pattern:

  10. VPC (10.20.0.0/16)
  11. ECS cluster (insurance-dev-cluster)
  12. Own RDS instance
  13. No VPC peering to BookingZone

  14. Shared AWS resources are limited to:

  15. CodeStar connection (GitHub integration)
  16. frappe-erpnext-base Docker image (common Frappe/ERPNext base layer)

  17. reservation-api-server remains the booking source of truth. ADR-0001 (Frappe as SoT) continues to apply for booking domain. Rental and insurance are sister products, not replacements.

Consequences

Positive

  • Independent deployments: Rental can ship without booking release cycles.
  • Fault isolation: Rental bugs cannot corrupt booking inventory locks.
  • Clear ownership: Each team owns their database schema end-to-end.
  • Scaling independence: Rental RDS can be sized separately from booking.

Negative / Trade-offs

  • No referential integrity: Cross-domain references are validated at application layer, not database layer. Orphan references are possible if a booking is deleted without notifying rental.
  • Network latency: HTTP calls to resolve BZ* entities add latency compared to local Link field resolution.
  • Operational complexity: Two Frappe stacks to monitor, back up, and upgrade instead of one.

Risks / Mitigations

  • Risk: Stale or invalid BZ* references in rental data. Mitigation: Rental API validates references on write via HTTP call to reservation-api-server. Background job audits existing references weekly.

  • Risk: Breaking changes to reservation-api-server API affect rental. Mitigation: Published API contracts (ADR-0005); rental consumes versioned endpoints.

  • Risk: Inconsistent data if HTTP call fails mid-transaction. Mitigation: Rental uses idempotent writes; reference resolution is read-only and can be retried.

Alternatives Considered

  • VPC peering with cross-database Links: Rejected. Frappe Links require shared database; cross-VPC database access adds complexity and latency without solving the coupling problem.

  • Single database with schema namespacing: Rejected. Still couples deployment and blast radius. Frappe doesn't support true schema isolation within one site.

  • Microservices without Frappe: Rejected. Rental team has Frappe expertise; rewriting in another framework would slow delivery.

Implementation Notes

Temporary 501 Shims

After reservation-api-server#893, the booking whitelist retains shims for: - consumer_rental* - rental_inventory - scooterbug_*

These return HTTP 501 (Not Implemented) to guide clients toward calling rental-api-server directly. Shims will be removed once all clients migrate.

Cross-Reference Pattern

# rental-api-server: storing a reference
rental_doc.booking_id = "BK-2026-00123"  # Data field, not Link
rental_doc.save()

# rental-api-server: resolving a reference
booking = requests.get(
    f"{RESERVATION_API_URL}/api/method/bookingzone.api.booking.get_booking",
    params={"booking_id": rental_doc.booking_id},
    headers={"Authorization": f"token {API_KEY}"}
).json()

Infrastructure Layout

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