The Villa Life Platform Specification 2025-10-21
Executive Summary
This document defines the database architecture and backend platform for The Villa Life (TVL) — a next-generation hospitality and property management ecosystem. The platform is designed to support thousands of villas at launch, with a scalable foundation that can grow to millions of listings across multiple business models — including private villas, corporate retreats, and white-label marketplaces. At its core, TVL’s architecture unifies tenancy, supply, booking, pricing, and financial operations under a clean, modular data model that preserves data isolation, extensibility, and auditability at every level.
Design Philosophy
“Model for the future, implement for now.” The schema and service architecture implement the complete logical model from day one, even if the MVP only activates a subset of functionality. This allows the UI, APIs, and data integrations to be built against the future state, avoiding refactors as the platform scales.
- Full schema readiness: All core entities (Org, Account, Space, Booking, RatePlan, Payment) exist from the start.
- Incremental rollout: Early releases use simplified data paths but leverage the same underlying structure.
- Longevity built-in: The platform can evolve from villa management to enterprise-grade distribution without structural change.
Core Design Principles
Tenant Isolation & Multi-Org Scalability
All data is partitioned by org_id, providing logical multitenancy.
Orgs represent top-level entities (owners, operators, marketplaces).
Accounts represent operational contexts or sub-tenants within an Org.
This structure supports owner-managed listings, TVL-managed properties, and partner-operated networks under a unified schema.
Why it matters: TVL can scale horizontally, host multiple partner brands, and support co-management — without cross-data leakage or schema refactoring.
Composable Data Domains
The platform is organized into modular, composable domains, each representing a major functional pillar of the system.
| Domain | Description | Key Entities | 
|---|---|---|
| Tenancy & Identity | Who owns and acts on behalf of whom | Org, Account, User, Membership | 
| Authorization & Access Control | Role- and scope-based permissions across data domains | Role, Permission, PolicyRule | 
| Supply (Spaces & Units) | Inventory of villas, rooms, and assets | Space, Unit, AccountSpaceRole | 
| Availability, Calendars & Blocking | Time-based inventory management | AvailabilityCalendar, Block, Hold | 
| Pricing, Fees & Revenue Rules | Configurable pricing and commission models | RatePlan, FeeRule, RevenueRule | 
| Quotes, Holds & Bookings | Transaction lifecycle from inquiry to confirmed stay | Quote, Hold, Booking | 
| Payments, Payouts & Financials | Financial transactions, reconciliation, and reporting | Payment, Payout, Transaction, Ledger | 
| Content, Media & Metadata | Descriptive, visual, and structured listing data | Description, MediaAsset, Attribute, Tag | 
| Channels, Distribution & Syndication | Data exchange with OTAs, partners, and white-label sites | Channel, ChannelFeed, ChannelListing | 
| Delegation & Multi-Org Collaboration | Shared management and cross-tenant collaboration | Delegation, ResourceReference | 
| Search, Discovery & Indexing | Optimized data structures for fast search and filtering | SearchIndex, DiscoveryIndex | 
| Analytics, Events & Audit Trails | Observability, metrics, and compliance-grade audit logs | Event, AuditEvent, MetricSeries | 
| System Architecture & Data Infrastructure | Physical architecture and data pipeline strategy | Database, Cache, Queue, Warehouse | 
| Scalability, Resilience & Lifecycle Management | Growth, reliability, and continuous evolution | Shard, WorkerPool, Backup, FeatureFlag | 
Why it matters: Each domain is independently maintainable and extensible.
New capabilities (e.g., corporate retreats, branded marketplaces, AI-driven pricing) can be layered in without schema rewrites.
Event-Driven Consistency
Rather than relying solely on synchronous updates, all domains publish Events for downstream processing — powering search reindexing, analytics aggregation, and feed synchronization.
This approach ensures eventual consistency across all services and enables robust asynchronous scaling as the platform grows.
Transparency, Auditability & Compliance
Every key operation — bookings, payouts, delegation changes — is logged as a verifiable AuditEvent with user, timestamp, and state diff.
The schema is built to meet SOC2, PCI-DSS, and GDPR requirements out of the box.
Future-Proof Extensibility
- Every major entity is linked to org_idandaccount_id, allowing federated data ownership.
- Financial logic is modular — supporting complex revenue splits, taxes, and commissions.
- Availability and pricing are flexible — supporting real-time sync, dynamic pricing, and channel-specific rules.
- The system anticipates distributed tenancy, white-label syndication, and AI-powered automation.
Tenancy & Identity
Overview
Tenancy & Identity define who owns what and who can act on behalf of whom across the platform.
It is the foundational layer that governs multi-tenancy, account delegation, and user identity.
This structure separates the tenant boundary (Org) from the actors (Accounts) that operate within it, ensuring clean isolation, flexible delegation, and scalable access control.
TL;DR
- Org = Tenant boundary (brand, company, or marketplace).
- Account = Actor within an Org (owner, manager, marketplace, or internal ops).
- User = Person identity (email-based, global).
- Membership = Binding of User → Org[/Account] + Role.
- Role = Permission set describing what actions the User can take.
- Accounts are mandatory per Org, with one default Account auto-created (is_default=true).
This structure supports villa-only use today and scales to 1M+ listings and cross-org collaborations without refactors.
Relationships & Cardinality
- Org → Account: 1→* — each Org has at least one Account; one is_default=true.
- Org → Membership: 1→* — every Membership belongs to an Org.
- Account → Membership: 1→* — Membership may also be Org-wide (account_id = NULL).
- User → Membership: 1→* — a User may belong to many Orgs/Accounts.
- Membership → Role: 1→1 — each Membership carries exactly one Role.
- Org → Role: 1→* — Roles are seeded per Org or globally shared.
- All actor-owned data → (Org, Account): required foreign keys for ownership and isolation.
Core Concepts
Org (Tenant)
Purpose: Represents the top-level business boundary and isolation scope.
Owns: Accounts, Memberships, and all tenant data (Spaces, Bookings, Pricing, etc.).
Lifecycle: Created during onboarding; deactivated or suspended but never deleted for audit reasons.
Isolation: Always filters queries by org_id.
Account (Sub-tenant / Actor within an Org)
Purpose: Represents the entity that owns, manages, or operates assets within an Org (e.g., property owner, manager, marketplace, internal ops).
Always present: One default Account created automatically on Org creation.
Attributes: type = owner|manager|marketplace|internal, is_default = true|false.
Constraints: (org_id, is_default) unique to enforce single default per Org.
User (Person)
Purpose: Global individual identity.
Uniqueness: Unique by email; persistent even across multiple Orgs.
Lifecycle: Never hard-deleted; deactivation via deleted_at.
Why: Allows users to act across multiple Orgs (multi-tenant participation).
Membership (User to Org[/Account] + Role)
Purpose: Defines where and how a User can act.
Scope:
- account_id = NULL→ Org-wide access.
- account_id = value→ Account-specific access. Lifecycle: Can end (- ended_at) but retained for audit; no hard deletes.
Role (Permission bundle)
Purpose: Named profile that defines which permissions a Membership grants (e.g., admin, owner_admin, ops, viewer).
Why: Enables consistent permission assignment and auditability.
Lifecycle: Static seeds, but can be extended per Org if needed.
Authorization & Access Control
Overview
Authorization & Access Control define what actions users can take and where they can take them within the system.
It combines Membership-based scoping (Org and Account) with Role-based permissions (RBAC) to form a clear, auditable, and extensible model.
This layer ensures that every API call, UI action, and data mutation respects the correct Org and Account boundaries.
TL;DR
Access = scope + permissions: scope from Membership, actions from Role→Permission.
Org-wide Memberships (account_id = NULL) grant access to all Accounts within that Org.
Account Memberships restrict access to the given Account’s assets.
RBAC now; ABAC later (via policy_rules).
All actor-owned resources include (org_id, account_id); queries always filter within this scope.
MVP: explicit, auditable RBAC suitable for villa-only operations; scalable to multi-brand marketplaces.
Relationships & Cardinality
- Org → Account 1:* — tenancy boundary; all authorization happens within an Org.
- Org → Membership 1:* — defines who can act within the Org.
- Account → Membership 1:* — Memberships may target a specific Account.
- Membership → Role 1:1 — each Membership carries one Role.
- Role → Permission 1:* — Roles bundle Permissions.
- Org → PolicyRule 1:* — optional future ABAC policies (disabled at MVP).
- Actor-owned data → (Org, Account) — required FKs for authorization scope.
Core Concepts
Membership (scope of authority)
Connects a User to an Org (and optionally an Account) granting privileges of a Role.
Org-wide = account_id NULL; Account-level = populated.
Ends via ended_at; retained for audit trail.
Role (permission bundle)
Named grouping of permissions (admin, owner_admin, manager, ops, viewer).
Globally seeded defaults, extendable per Org.
Permission (action registry)
Atomic verbs recognized by the system (e.g., space.read, booking.manage, pricing.edit).
Versioned and centrally maintained.
RolePermission (link table)
Associates Roles with Permissions; each mapping has an effect (allow|deny).
Deny wins over allow.
PolicyRule (future ABAC)
Conditional allow/deny rules with JSON conditions (e.g., channel, region).
Disabled for MVP.
Rationale
Separation of scope vs authority: Membership determines where, Role determines what.
Predictable enforcement: queries filter by (org_id, account_id).
Scales from single villa to multi-Org marketplaces.
Future-proof: ABAC and Row-Level Security layer on without schema changes.
MVP Implementation (villa-only)
Seed Roles: admin, ops, owner_admin, manager, viewer.
Seed Permissions (core verbs for account, space, pricing, booking actions).
Role bundles:
- admin: all permissions
- ops: all except account.set_default
- owner_admin: manage own Spaces, Bookings, Pricing
- manager: operate Bookings within Account
- viewer: read-only
Org creator gets Org-wide admin Membership; default Account auto-created.
Operational Notes
- Cache effective (scope + permissions) set; invalidate on Membership/Role change.
- Index memberships (org_id,user_id,account_id)androle_permissions (role_id,permission_id).
- Log all access-denied events and Role changes.
- org_idfilter mandatory to prevent cross-tenant leakage.
Availability, Calendars & Blocking
Overview
Availability manages time-based inventory (Bookings, Holds, Blocks, iCal feeds).
Ensures safe coordination across channels and prevents double-bookings.
TL;DR
Single authoritative calendar per Space (villa MVP; Unit-level later).
Bookings, Holds, Blocks share same surface → precedence Booking > Hold > Block.
iCal export/import with tokenized URLs.
InventoryLock prevents double-sells.
Relationships & Cardinality
- Org → Space 1:*
- Space → AvailabilityCalendar 1:1
- AvailabilityCalendar → Booking 1:*
- AvailabilityCalendar → Hold 1:*
- AvailabilityCalendar → Block 1:*
- Space → iCalFeed 1:*
- Actor-owned data → (Org, Account)
Core Concepts
AvailabilityCalendar
Authoritative record of a Space’s inventory. Keys: (org_id, space_id).
Booking
Confirmed reservation; blocks time and overrides all other entries.
Lifecycle: pending → confirmed → checked_in → completed|canceled.
Hold
Temporary lock (TTL 10–30 min) during checkout; converted or expires.
Block
Non-booking busy period (maintenance, owner stay, external iCal).
source = manual|owner|partner|external|ops|system.
InventoryLock
DB or advisory lock guarding (calendar_id,start,end) per transaction.
iCalFeed
Handles outbound/inbound calendar sync. Tokenized URL; tracks etag & last_modified.
Rationale
Unified time model simplifies conflict resolution.
Bookings always override other events.
iCal imports idempotent and secure.
Audit trail for every change.
MVP Implementation
- One calendar per Space.
- Acquire InventoryLock→ create Hold → confirm → release.
- Two outbound iCal feeds (public, owner).
- External iCal imports as Blocks using If-None-Match headers.
- UI shows merged timeline (Bookings + Blocks).
Operational Notes
- Store UTC half-open intervals [start_at,end_at).
- EXCLUDE USING gist(calendar_id WITH =, time_range WITH &&)to prevent overlap.
- Materialized daily availability views for search.
- Bookings > Holds > Blocks > Available.
- Imported blocks never override confirmed Bookings.
Pricing, Fees & Revenue Rules
Overview
Defines rate computation and revenue allocation. Separates pricing logic from application (Quotes, Bookings).
TL;DR
Pricing = Rules + Context.
RatePlans define base rates; FeeRules add costs; RevenueRules split income.
Quotes snapshot pricing state at booking time.
Villa MVP: nightly rate + cleaning fee + fixed commission split.
Relationships & Cardinality
- Org → Space 1:*
- Space → RatePlan 1:*
- RatePlan → RateRule 1:*
- RatePlan → FeeRule 1:*
- RatePlan → RevenueRule 1:*
- RatePlan → Quote 1:*
- Quote → Booking 1:1
Core Concepts
RatePlan
Defines pricing set for a Space. (org_id,account_id,space_id).
RateRule
Base price and modifiers (season, LOS, lead time, channel).
Priority: date > stay length > lead time > channel.
FeeRule
Extra charges (fixed or percent) basis per stay|night|guest.
RevenueRule
Splits gross between Accounts and TVL. e.g. Owner 80%, TVL 20%.
Quote
Snapshot of evaluated pricing; immutable after conversion to Booking.
Rationale
Separation of definition vs application.
Explicit financial rules aid audit and transparency.
Scales to taxes, promos, and multi-party payouts.
MVP Implementation
- One RatePlan per Space (“Standard Rate”).
- Flat nightly rate (+seasonal multiplier).
- Cleaning fee + 20% TVL commission.
- Quotes generated at checkout; frozen on confirmation.
Future Enhancements
Dynamic pricing API integration.
Multi-currency support.
Tax engine and rule chaining.
Accounting sync for ledger integration.
Operational Notes
- Compute pipeline: RatePlan + Rules → Quote → Booking.
- Store minor units (cents).
- Index (org_id,space_id,valid_from)for RatePlans.
- Audit rate changes.
- Cache daily rates per Space for search.
Quotes, Holds & Bookings
Overview
Manages the complete reservation lifecycle — from inquiry to final booking — tying together Pricing, Availability, and Payments.
TL;DR
Quote → Hold → Booking is the core flow.
Quotes contain pricing snapshots.
Holds reserve inventory temporarily.
Bookings finalize stays and drive payments and reporting.
Villa MVP = single Unit bookings; simple state machine.
Future-ready = multi-Unit, multi-Account, and channel-aware lifecycle.
Relationships & Cardinality
- Org → Space 1:*
- Space → Quote 1:*
- Quote → Hold 1:1
- Quote → Booking 1:1
- AvailabilityCalendar → Hold 1:*
- AvailabilityCalendar → Booking 1:*
- Booking → Payment/Invoice 1:*
- Actor-owned data → (Org, Account)
Core Concepts
Quote
Priced offer based on RatePlan, dates, and occupancy.
Immutable snapshot (fields: checkin/checkout, nights, guests, totals).
Hold
Temporary inventory lock (TTL 15–30 min) during checkout.
Expires automatically or converts to Booking.
Booking
Authoritative reservation record.
State machine: pending → confirmed → checked_in → completed | canceled.
Immutable except for state transitions.
Links to Quote and Payments.
Rationale
Predictable workflow; atomic state changes for auditability.
Optimistic concurrency prevents double-booking.
Unified record for operations and finance.
MVP Implementation
- Quote generated from RatePlan; expires after 30 min.
- Hold created when checkout starts; TTL 15 min.
- Booking confirmed after payment; Hold released.
- Triggers calendar update and iCal feed regeneration.
- Illegal state transitions rejected with audit log.
Operational Notes
- Use InventoryLockon create.
- Index bookings on (org_id, space_id, checkin).
- Never delete bookings; mark canceled_at.
- Emit events: quote.created,booking.confirmed,booking.canceled.
Payments, Payouts & Financials
Overview
Tracks all money movement — from guest payments to owner payouts — with immutable journal entries and auditable ledgers.
TL;DR
Payments = inflows (guest → platform).
Payouts = outflows (platform → accounts).
Transactions = immutable journal entries.
Villa MVP: record payments & manual payouts.
Future-ready: automated settlements, multi-currency, and compliance.
Relationships & Cardinality
- Booking → Payment 1:*
- Booking → Payout 1:*
- Payment → Transaction 1:*
- Payout → Transaction 1:*
- Org → Ledger 1:1
- Ledger → Transaction 1:*
- Payment → Refund 1:*
Core Concepts
Payment
Guest inflow linked to Booking.
amount, currency, status (pending|succeeded|failed|refunded).
Payout
Outgoing disbursement to owner/partner Account.
Created automatically when Booking completed.
Transaction
Atomic ledger entry (debit|credit) with category and timestamp.
Double-entry compliant.
Ledger
One per Org; aggregates Transactions and balance.
Refund
Negative Payment creating compensating Transactions.
BalanceSummary
Computed view of pending balances per Account.
Rationale
Immutable journal for compliance.
Lineage to Booking and RatePlan for traceability.
Separation of intent (Rules) vs actual (Transactions).
Scalable multi-Org financial framework.
MVP Implementation
- Record Payments manually or via provider (Stripe).
- Compute payouts from RevenueRules (Owner 80%, TVL 20%).
- Insert Transactions for each Payment and Payout.
- Refunds = negative Transactions.
- Summaries by Org/Account for reporting.
Operational Notes
- Amounts in minor units (cents).
- Indexes on (org_id, booking_id, occurred_at).
- Payments idempotent via reference token.
- No soft deletes — use compensating entries.
- Audit every status change.
Content, Media & Metadata
Overview
Defines how Spaces and Units are described, visualized, and enriched.
Separates marketing content from operational data for re-use and syndication.
TL;DR
Content = text and descriptions.
Media = photos/videos/docs.
Metadata = structured attributes + tags.
Villa MVP: descriptions, photo gallery, amenities.
Future-ready: multi-language localization and AI metadata.
Relationships & Cardinality
- Org → Space 1:*
- Space → MediaAsset 1:*
- Space → Description 1:*
- Space → Amenity 1:*
- Space → Attribute 1:1
- Space → Tag :
- MediaAsset → Tag :
Core Concepts
Description
Marketing text (title, headline, body).
language_code, format (html|markdown).
Revisions versioned; archived for rollback.
MediaAsset
Images/videos/documents with ordering.
Fields: url, position, is_primary, caption, alt_text.
Stored in S3/CDN; metadata in DB.
Amenity
Boolean or parametric features (pool, wifi, parking).
Catalog-driven; used for search filters.
Attribute
Structured JSON metadata (e.g., {"max_guests":8,"bedrooms":4}).
Supports flexible feature expansion.
Tag
Categorical labels (theme, feature, marketing).
Multi-purpose for search and feeds.
Rationale
Decoupled presentation from data logic.
Reusable across web, marketing, and feeds.
Supports localization and versioning.
Structured metadata enables rich search and AI tagging.
MVP Implementation
- One Description per Space (default language).
- Photo gallery (5–20 images, ordered).
- is_primary = truefor cover photo.
- Amenity catalog (~50 keys).
- Attributes: max_guests,bedrooms,bathrooms,view.
- Tags optional (e.g., “Seaside”, “Private Chef”).
- Version changes logged to AuditEvents.
Operational Notes
- URLs signed and CDN-served.
- Index media_assets(space_id,position); GIN onattributes.
- UTF-8 for localization.
- Access limited to authorized Memberships.
- Soft delete via deleted_at.
- Pre-render cached HTML blobs for faster load.
Channels, Distribution & Syndication
Overview
Channels & Distribution govern how listings, rates, and availability are exported to and synchronized with external marketplaces and white-label sites.
TL;DR
- Channel = logical external connection (Airbnb, VRBO, TVL Brand).
- ChannelFeed = defines what data gets published (content, rates, availability).
- ChannelListing = maps internal Space/Unit → external listing ID.
- ChannelSync = records each import/export for observability.
Villa MVP: iCal-based exports and manual listing links.
 Future: two-way API sync, channel rulesets, and white-label marketplaces.
Relationships & Cardinality
- Org → Channel 1:*
- Channel → ChannelFeed 1:*
- Channel → ChannelListing 1:*
- Space → ChannelListing 1:*
- ChannelListing → ChannelSync 1:*
- Space → ChannelBlock 1:* (imported busy dates)
- Actor-owned data → (Org, Account)
Core Concepts
Channel
Represents an external integration.
type = ota | marketplace | api_partner | internal_brand
Active via API key or feed URL.
ChannelFeed
Specifies scope and format of data export (ical|json|xml|api).
Supports per-audience feeds (public, owner, partner).
ChannelListing
Maps Space/Unit to external listing ID.
Tracks sync status and last updated time.
ChannelSync
Operational log of export/import events for debug and analytics.
Fields: direction, scope, started_at, status, message_log.
ChannelBlock
Imported busy dates from external feeds → internal Availability Blocks.
Rationale
Unified model for all distribution paths (OTA, partner, marketplace).
Traceable sync via ChannelSync.
Simple MVP (iCal) with extensibility for full API integration.
Tenant-safe: each Org manages its own channels and feeds.
MVP Implementation
- Supported channels: Airbnb, VRBO, TVL public site.
- Exports: Availability via iCal.
- Imports: External iCal → ChannelBlock.
- Manual external IDs per listing.
- Sync logs retained 30 days.
- Tokenized URLs; duplicate UIDs deduped.
Operational Notes
- Jobs schedule syncs hourly (iCal) or real-time (API).
- Index channel_listings(space_id,channel_id)unique.
- Cache feeds with ETag headers.
- Audit each sync with user and timestamp.
Delegation & Multi-Org Collaboration
Overview
Delegation enables cross-Org collaboration without breaking tenant isolation — for example, letting TVL Ops manage owner villas on behalf of clients.
TL;DR
Delegation = controlled permission grant from one Org/Account to another.
Ownership never changes; access is extended.
MVP: TVL Ops acts for owners.
Future: multi-brand partnerships, white-label marketplaces, API delegations.
Relationships & Cardinality
- Org → Delegation 1:*
- Account → Delegation 1:*
- Delegation → ResourceReference 1:*
- Org ↔ Org many-to-many via Delegation
- Org → Membership 1:* (for DelegatedMembership resolution)
Core Concepts
Delegation
Record linking grantor Org → grantee Org.
scope = read|write|manage, resource_type = space|booking|pricing.
Active between start_at and end_at.
ResourceReference
Specific IDs shared under a Delegation (e.g., selected Spaces).
DelegatedMembership
Derived temporary Membership granting a user cross-Org access.
CollaborationLog
Audit trail of delegated actions (user, action, resource, timestamp).
Rationale
Enables co-management without data merging.
Audit trail + revocability for trust and compliance.
Foundation for B2B integrations and partner programs.
MVP Implementation
- Owner Org delegates to TVL Ops Org (scope=manage, resource_type=space).
- TVL Ops users gain derived manager role for those Spaces.
- Revocation on contract end; logged in CollaborationLog.
Operational Notes
- Authorization middleware checks Membership + DelegatedMembership.
- Index delegations(grantor_org_id,grantee_org_id,resource_type,status).
- Cascading revocation of derived Memberships.
- Delegations signed and audited.
Search, Discovery & Indexing
Overview
Provides fast, filterable search for Spaces and Units by flattening operational data into search-optimized indexes.
TL;DR
SearchIndex = flat searchable fields.
DiscoveryIndex = availability-aware metadata.
Villa MVP: filter by location, price, bedrooms, amenities.
Future: full-text search, personalization, geo-distributed shards.
Relationships & Cardinality
- Org → Space 1:*
- Space → SearchIndex 1:1
- Space → DiscoveryIndex 1:1
- Space → Tag :
- AvailabilityCalendar → DiscoveryIndex 1:*
Core Concepts
SearchIndex
Flattened record of Space fields (name, location, tags, price range, capacity).
Updated on change events.
DiscoveryIndex
Aggregated snapshot including availability and pricing facets.
FilterSet
Reusable JSON filter definitions for API queries.
SearchJob / ReindexTask
Async job keeping indexes up-to-date from domain events.
Rationale
Performance via denormalization.
Consistency from event-driven updates.
Tenant isolation by org_id.
Scalable for tens of thousands of listings.
MVP Implementation
- Index active Spaces (status=active).
- Fields: name, location, price_min/max, bedrooms, tags, amenities.
- Availability flags (next 90 days).
- Reindex triggered by Space, Price, or Booking event.
- Filters: location, price_range, bedrooms, amenities, tags.
- Sorted by price or capacity.
Operational Notes
- Event-driven or batch reindex jobs.
- Use PostgreSQL FTS or Elasticsearch.
- Include (org_id,account_id)in index records.
- Cache popular filters in Redis.
- Monitor indexing latency and search performance.
Analytics, Events & Audit Trails
Overview
Captures every operational, behavioral, and financial change across the system — providing observability, compliance, and analytical insight.
TL;DR
- Event = atomic record of something that happened.
- AuditEvent = signed log of sensitive changes (who, what, when).
- MetricSeries = aggregated time-series metrics.
 Villa MVP → capture CRUD events for Bookings, Spaces, and Payments.
 Future-ready → streaming analytics, ML pipelines, external BI feeds.
Relationships & Cardinality
- Org → Event 1:*
- Org → AuditEvent 1:*
- User → Event 1:*
- Resource → Event 1:*
- Org → MetricSeries 1:*
- Actor-owned data → (Org, Account)
Core Concepts
Event
Generic record of a system or user action.
Fields: org_id, account_id, user_id, resource_type, resource_id, event_type, payload, source, occurred_at, trace_id.
Append-only; never edited.
AuditEvent
Cryptographically verifiable record of sensitive state changes.
Includes before/after snapshots and signature.
Immutable; deletions logged as compensating events.
MetricSeries
Aggregated numeric data (bookings/day, revenue, latency).
Stored by time bucket and dimension (region, channel, account).
Feeds dashboards and BI tools.
EventStream / EventBus
Pub/Sub pipeline for internal and external consumers.
Guarantees at-least-once delivery.
MVP → in-process queue; Future → Kafka / PubSub.
Rationale
End-to-end traceability of system behavior.
AuditEvents for SOC2 / GDPR compliance.
Metrics enable real-time monitoring and decision-making.
Unified pipeline for DevOps and business intelligence.
MVP Implementation
- Record booking.created|confirmed|canceled,space.updated,payment.succeeded.
- Append to eventstable; nightly aggregate intometric_series.
- Audit on updates / deletes to key tables with before|after JSON.
- Sign AuditEvents with HMAC.
- Simple dashboards for bookings, occupancy, revenue.
Operational Notes
- Partition events by occurred_at.
- Index (org_id, resource_type, resource_id, occurred_at).
- Store AuditEvents in WORM media.
- Retention 12–24 months; Metrics daily roll-ups.
- Encrypt at rest; rotate keys.
- Retry failed writes via dead-letter queue.
- Monitor ingestion lag and consumer latency.
System Architecture & Data Infrastructure
Overview
Defines how all domains interconnect — databases, services, queues, caches, and analytics layers — to deliver a scalable and resilient backend.
TL;DR
- Modular, service-oriented architecture around PostgreSQL.
- Multi-tenant schema (org_idpartitioning).
- Redis for cache & queues.
- Central Event Bus for async flows.
- Villa MVP → single cluster, background jobs for sync & iCal.
- Future → sharding, microservices, warehouse sync, data lake archives.
Relationships & Cardinality
- DB Cluster → Org 1:* (soft multitenancy).
- Org → Account / Space / Booking … 1:*
- EventBus → Domain Services 1:*
- Service → Cache 1:*
- Service → DB Pool 1:*
- Analytics Warehouse → Org many-to-many (partitioned per tenant).
Core Concepts
Relational Database (PostgreSQL)
Authoritative store for all structured data.
- Single cluster per environment (core,analytics,jobs).
- Each table includes org_id.
- Uses foreign keys, partial indexes, and GIST ranges (for availability).
- ACID guarantees for bookings & finance; JSONB flexibility for metadata.
Caching Layer
Redis for sessions, computed prices, availability fragments.
CDN (e.g., CloudFront) for media and feeds.
TTL-based invalidation on update events.
Message Queue / Event Bus
Decouples domain logic.
Jobs: imports, reindexing, feeds.
Events: booking.created, payment.succeeded.
Guarantee: at-least-once delivery with dedup by event_id.
Service Layer
Encapsulated APIs per domain:
identity-service, booking-service, pricing-service, finance-service, content-service, channel-service, delegation-service, analytics-service.
Communicate via REST / gRPC with shared auth middleware.
Data Warehouse / Analytics Layer
Event stream → staging → BigQuery/Snowflake.
Used for BI dashboards & forecasting.
MVP = batch ETL; Future = streaming sync.
File Storage & CDN
S3 for objects, CloudFront for distribution.
Signed URLs; lifecycle policies for archival.
Rationale
ACID integrity + logical isolation for tenants.
Stateless services for scalability.
Event-driven foundation for automation and analytics.
Security via encryption, network segmentation, and least-privilege IAM.
MVP Implementation (villa-only)
- Single region (Postgres + Redis + CDN).
- Core services containerized on Kubernetes.
- Enabled domains: Identity, Auth, Supply, Availability, Pricing, Bookings, Payments, Content.
- Async jobs for reindexing and iCal imports.
- Search = Postgres FTS or small Elasticsearch node.
- Observability = OpenTelemetry + ELK stack.
- Security = TLS everywhere, JWT for auth, row-level isolation by org_id.
Future Enhancements
- Horizontal sharding and multi-region replicas.
- Streaming ETL to warehouse / data lake.
- Microservice autoscaling via CI/CD.
- IaC (Terraform) per service.
- API Gateway for rate limiting & metrics.
- Automated compliance checks and daily audits.
Operational Notes
- Versioned migrations (Alembic / Liquibase).
- Enforce FKs, unique constraints, and soft deletes.
- Monitor replication lag and slow queries.
- PITR backups (30-day retention).
- Warm standby region for DR.
- Secret rotation every 90 days.
- Read replicas for analytics.
- Isolated dev/staging/prod environments.
Scalability, Resilience & Lifecycle Management
Overview
Defines how the TVL system scales, adapts, and maintains reliability as data volume and concurrency increase.
Includes scaling patterns, operational resilience, schema lifecycle, and observability practices.
TL;DR
- Scaling: horizontal service scaling + tenant partitioning by org_id.
- Resilience: redundancy, retry queues, and stateless recovery.
- Lifecycle: versioned migrations, feature flags, and schema evolution.
 Villa MVP: single-region, single-cluster core with nightly backups.
 Future-ready: multi-region sharding, rolling upgrades, autoscaling, continuous deployment.
Relationships & Cardinality
- Org → DB Shard →1 (future) — each Org assigned to one shard.
- Service → WorkerPool 1:* — services scale horizontally via replicas.
- JobQueue → Worker 1:* — tasks distributed for concurrency.
- EventBus → Consumer 1:* — each event may have multiple processors.
- Actor-owned data → (Org, Account) ensures tenant isolation.
Core Concepts
Horizontal Scaling
Add service instances to handle higher load.
Stateless containers; sessions persisted via Redis.
Example: booking-service scaled to 20 replicas during high season.
MVP → manual; Future → auto-scaling by CPU/RPS metrics.
Database Partitioning
Distribute tenants across clusters or shards.
Partition by org_id, optionally by region (EU/US/APAC).
MVP → one cluster; Future → Shard Router Service.
Caching & Computed Stores
Relieve read load and speed response.
Redis for ephemeral data; materialized views for analytics; CDN for feeds.
TTL-based or event-driven invalidation.
Job Queues & Background Processing
Retryable, non-blocking workloads (imports, syncs, reindexes).
Redis or RabbitMQ as queue backend.
Jobs idempotent; guarantee at-least-once delivery.
Resilience & Fault Recovery
Patterns:
- Circuit breakers on external calls.
- Graceful degradation of non-critical features.
- Dead-letter queues for failed jobs.
- Heartbeat & health endpoints for liveness probes. MVP: basic retries; Future: distributed tracing & SLA metrics.
Schema & Version Management
Safe, backward-compatible evolution.
- Versioned migrations (Alembic/Liquibase).
- Feature flags for dependent changes.
- Shadow writes for dual-schema rollouts.
 Policy: never destructive in active deployments.
Observability & Monitoring
Metrics: system health, queue depth, latency.
Traces: OpenTelemetry correlation from API → DB.
Logs: structured and searchable.
Tools: Grafana, Prometheus, ELK, or CloudWatch.
Alerts: SLA violations, replication lag, job failures.
MVP: central log aggregation + Slack/Email alerts.
Backups & Disaster Recovery
- Point-in-time recovery via WAL logs.
- Daily full backup to encrypted storage (30-day retention).
- Standby replica auto-promoted on failure.
- Quarterly DR simulations for validation.
Lifecycle Management
Ensures smooth evolution of system & schema.
- Blue/green or rolling deploys.
- Feature flag toggles for gradual rollout.
- Parity across dev/staging/prod.
MVP: manual deploys with migration hooks;
 Future: CI/CD with canary deploys and auto rollback.
Rationale
- Elastic performance: horizontal scaling without redesign.
- Predictable resilience: each layer (DB/cache/queue/service) recovers independently.
- Operational safety: built-in backup, audit, and monitoring pipelines.
- Continuous evolution: migration discipline + feature flag governance.
- Future-proof: designed for multi-region scale and zero-downtime evolution.
MVP Implementation
- Database: single RDS instance; daily backups + replicas.
- Services: Kubernetes pods; manual HPA target.
- Queues: Redis job runner for iCal imports & search reindexing.
- Monitoring: uptime and slow-query logs.
- Resilience: idempotent retries for failed bookings/payments.
- Lifecycle: versioned migrations with manual approval.
- DR: warm standby region, <1-hour recovery objective.
Future Enhancements
- Multi-shard router for org-based DB routing.
- Autoscaling workers (dynamic by queue depth).
- Global failover via DNS routing.
- Zero-downtime migrations with background schema copy.
- Automated rollback + feature flag reverts.
- Network chaos testing for consistency validation.
- Resilience automation via chaos engineering drills.
- Unified dashboards (uptime, latency, throughput).
- Predictive autoscaling before peak seasons.
- Scheduled data-retention validation.
Operational Notes
Metrics to track:
- DB latency, job throughput, cache hit ratio, API error rate.
Alerts:
- Critical: DB unavailability, queue overflow, payout failures.
- Warning: replication lag, stale index, cache degradation.
Release cadence:
- Weekly features; monthly schema sync.
Change management:
- All releases, migrations, and recoveries recorded as AuditEvents.
Security posture:
- Secrets rotated quarterly; static scans pre-deploy.
Uptime targets:
- MVP = 99.5%, Future = 99.9% global.
Cost optimization:
- Non-peak autoscaling down; cold storage for expired data.