Skip to main content

03 — Microservices Catalog

Companion: 01 Product Overview · 02 Enterprise Architecture · 04 Event-Driven Architecture · 05 API Design · Service Template

This catalog enumerates the 22 microservices that make up Ghasi Melmastoon. Service boundaries map 1:1 to bounded contexts (see docs/02-enterprise-architecture.md), and each row points to a deeper bundle under services/<name>/.

Two-layer documentation model

LayerLocationPurposeAudience
Summary catalogdocs/03-microservices/ (this folder, one summary .md per service plus this README)One-screen overview per service: purpose, data owned, key APIs, key events, upstream/downstream. Used to onboard, plan cross-service work, and spot ownership conflicts.Architects, PMs, new engineers, AI coding tools needing fast orientation.
Per-service bundleservices/<name>/ (17 deep docs per service — see SERVICE_TEMPLATE.md)Implementation-grade detail: domain model, application logic, API contracts, event schemas, data model, sync contract, AI integration, security, observability, testing, deployment, failure modes, local dev, readiness, risks, migration.Service owners, implementers, security/SRE reviewers, audit loops.

When the two layers disagree, the deeper bundle is authoritative for implementation detail; the strategic docs (docs/01..19-*.md) are authoritative for cross-cutting decisions. If neither resolves the conflict, raise an ADR under docs/architecture/.

Service catalog (22)

ServiceBounded ContextDomain TypePrimary StorageOwnerPhaseSummaryBundle
iam-serviceIdentity & AccessGenericPostgres (per-service schema, RLS) + Redis (sessions)PlatformPhase 0JWT issuance, refresh, RBAC/ABAC, OIDC/SAML SSO, MFA, device binding for desktop, audit log of authn events.iam-service.md · bundle
tenant-serviceTenant & OrgSupportingPostgres (per-service schema, RLS)PlatformPhase 0Tenants, properties roll-up, org units, memberships, tenant settings (currency, locale, tax rules), plan/feature flags.tenant-service.md · bundle
property-servicePropertyCorePostgres + Cloud Storage (geo + media refs)PMSPhase 0Properties, room types, individual rooms (lifecycle clean/dirty/OOO/OOS), amenities, geo-location, photos.property-service.md · bundle
reservation-serviceReservationsCorePostgres (write model) + Pub/Sub (events)PMSPhase 0Booking and Reservation aggregates, hold → confirm → check-in → check-out state machine, walk-ins, group bookings, cancellation policy enforcement, saga orchestrator with inventory + payment + lock.reservation-service.md · bundle
pricing-servicePricing & RatesCorePostgres + Memorystore (rate cache)RevenuePhase 1RatePlan aggregates (BAR, weekly, government, corporate, non-refundable), seasonal/derived/yield rules, AI-suggested dynamic pricing (HITL), price quotes with TTL.pricing-service.md · bundle
inventory-serviceInventory & AvailabilityCorePostgres (per (property, roomType, date) row) + Redis (hot allocation cache)PMSPhase 0Allocation per (property, roomType, date), holds, stop-sell, min/max LOS, oversell guard. Authoritative source of "is a unit available".inventory-service.md · bundle
housekeeping-serviceHousekeepingCorePostgres + desktop SQLite (offline replication)OperationsPhase 1Cleaning task lifecycle, room turnover queue, drag-and-drop board, AI scheduling assistant, offline updates with conflict policy.housekeeping-service.md · bundle
maintenance-serviceMaintenanceSupportingPostgres + desktop SQLiteOperationsPhase 1Maintenance tickets, severity, SLA, technician assignment, room-blocking interactions with inventory.maintenance-service.md · bundle
billing-serviceBilling & FolioCorePostgres (folio/ledger) + Cloud Storage (invoices)FinancePhase 0Folio ledger, charges/payments/taxes/refunds, invoice generation, dunning, multi-currency, tax-jurisdiction rules, offline draft invoices on desktop.billing-service.md · bundle
payment-gateway-servicePaymentsGenericPostgres (intents) + Secret Manager (vendor secrets)PaymentsPhase 0Pluggable gateway: PayPal, Visa/Debit, cash-on-arrival reconciliation, MFS adapters; PaymentIntent state machine, idempotent webhooks, signature verification.payment-gateway-service.md · bundle
staff-serviceStaff & ShiftsSupportingPostgres + desktop SQLiteHR/OpsPhase 1Staff members, roles, shifts, basic time-tracking, role-to-IAM mapping, availability for housekeeping/maintenance assignment.staff-service.md · bundle
notification-serviceCommunicationGenericPostgres + Pub/SubPlatformPhase 0Multi-channel delivery (email/SMS/push), templates with i18n + RTL/LTR variants, delivery attempts, bounce handling, recipient preferences.notification-service.md · bundle
reporting-serviceReportingSupportingPostgres (read model) + Cloud Storage (exports)AnalyticsPhase 1Operational reports (occupancy, ADR, RevPAR, housekeeping throughput), scheduled exports, offline-cacheable recent reports on desktop.reporting-service.md · bundle
analytics-serviceAnalyticsSupportingBigQuery (aggregations) + Postgres (metric defs)AnalyticsPhase 2Event-sourced aggregations, dashboards, cohort definitions, KPI surfacing for the backoffice dashboard.analytics-service.md · bundle
ai-orchestrator-serviceAICorePostgres (prompts/audit) + pgvector (embeddings) + Vertex AI / ONNXAI PlatformPhase 1Single port for all AI calls (LLM, embedding, vision, TTS, moderation), routes Vertex AI cloud vs ONNX Runtime edge (desktop), enforces AIProvenance, HITL flows, budgets, safety verdicts.ai-orchestrator-service.md · bundle
theme-config-serviceTheming & ConfigSupportingPostgres + Cloud Storage (theme assets) + Memorystore (theme cache)Frontend PlatformPhase 0Tenant themes, design tokens, layout presets, content blocks, RTL/LTR contracts, served to web/mobile booking surfaces and the desktop shell.theme-config-service.md · bundle
file-storage-serviceStorageGenericCloud Storage + Postgres (metadata)PlatformPhase 0Tenant-scoped object storage for media, invoices, theme assets, ID documents; signed URLs, virus scan, retention.file-storage-service.md · bundle
lock-integration-serviceLock & KeyCorePostgres + Secret Manager (vendor secrets)OperationsPhase 1Pluggable vendor adapters (TTLock, Salto, Assa Abloy, generic Wiegand/RFID), KeyCredential lifecycle (issue/update/revoke), lock-device pairing, offline encoder fallback.lock-integration-service.md · bundle
search-aggregation-serviceDiscoveryCorePostgres (canonical) + OpenSearch / Elasticsearch (read index) + pgvectorDiscoveryPhase 1Cross-tenant searchable index over published listings, geo + filters + semantic ranking, powers the consumer meta layer. Only service authorized to read across tenants (and only over published, non-PII fields).search-aggregation-service.md · bundle
bff-consumer-serviceBFF (Meta)Supporting(no own DB; aggregates) + MemorystoreFrontend PlatformPhase 1BFF for the consumer meta layer (web + mobile): aggregates search-aggregation-service, theme-config-service, property-service for list/map views and discovery.bff-consumer-service.md · bundle
bff-tenant-booking-serviceBFF (Booking)Supporting(no own DB; aggregates) + MemorystoreFrontend PlatformPhase 0BFF for the tenant-branded booking experience (web + mobile): aggregates theme-config-service, pricing-service, inventory-service, reservation-service, payment-gateway-service for the booking flow.bff-tenant-booking-service.md · bundle
bff-backoffice-serviceBFF (Desktop)Supporting(no own DB; aggregates) + MemorystoreFrontend PlatformPhase 0BFF for the Electron desktop backoffice: aggregates PMS services for dashboards, exposes the `/sync/v1/pullpushprotocol, fans out tohousekeeping-service, lock-integration-service, billing-service`, etc.

Domain type legend:

  • Core — competitive differentiator; built in-house, evolves fastest, deepest test investment. (10 services: property, reservation, pricing, inventory, housekeeping, billing, ai-orchestrator, lock-integration, search-aggregation. Note: 9 listed; the 10th depends on phasing of analytics — currently classified Supporting.)
  • Supporting — necessary, pattern-driven, lower invention surface.
  • Generic — commodity capability; could be replaced by a SaaS, kept in-house for tenant isolation, cost, and offline behavior.

Context map (ASCII)

The diagram below shows the dominant relationships. Every cross-service edge is one of: Customer/Supplier (CS), Conformist (CF), Anti-Corruption Layer (ACL), Open Host Service (OHS), Published Language (PL), or Shared Kernel (SK) on the TenantId value object.

┌──────────────────┐
│ tenant-service │ (SK: TenantId VO)
└────────┬─────────┘

┌──────────────────┼──────────────────┐
│ │ │
┌────────▼────────┐ │ ┌────────▼─────────┐
│ iam-service │─────────┴─────────│ theme-config-svc │
│ (CF via JWT) │ │ (CS, OHS) │
└────────┬────────┘ └────────┬─────────┘
│ │
│ ┌───────────────────┐ │
├─────▶ property-service │◀──────────┤
│ └─────────┬─────────┘ │
│ │ CS │
│ ┌─────────▼─────────┐ │
│ │ inventory-service │ │
│ └─────────┬─────────┘ │
│ │ CS │
│ ┌─────────▼──────────────┐ │
├─────▶ pricing-service │ │
│ └─────────┬──────────────┘ │
│ │ CS │
│ ┌─────────▼──────────────────┐ │
│ │ reservation-service │──┤ (saga orchestrator)
│ │ (Core; saga w/ inv+pay+lock)│ │
│ └────┬─────┬─────┬───────┬───┘ │
│ │ CS │ CS │ CS │ CS │
│ │ │ │ │ │
┌─────────▼───┐ ┌───▼──┐ ┌▼────┐│ ┌─────▼────────────────┐
│ notification│◀─┤bill- │ │pay- ││ │ lock-integration-svc │
│ -service │ │ ing │ │ment │ │ (ACL: TTLock/Salto/ │
└──────┬──────┘ └──┬───┘ │gtwy │ │ Assa Abloy/Wiegand) │
│ │ │ svc │ └──────────────────────┘
│ │ └─────┘ ▲
│ │ │ CS
│ │ ┌──────────────────┤
│ │ │ │
┌──────────────▼──┐ ┌──────▼────────┐ │ ┌──────────────┴─────────┐
│ housekeeping- │ │ reporting-svc │ │ │ ai-orchestrator-svc │
│ service │ └──────┬────────┘ │ │ (OHS + PL: AIClient, │
└────────┬────────┘ │ CS │ │ AIProvenance VO) │
│ CS │ │ └────────────▲───────────┘
┌────────▼────────┐ ┌──────▼────────┐ │ │ OHS
│ maintenance-svc │ │ analytics-svc │ │ │
└─────────────────┘ └───────────────┘ │ ┌────────────┴───────────┐
│ │ Every content / ops │
┌────────────────────┐ ┌─────────────┐ │ │ context calls AI here │
│ search-aggregation │ │ file-storage│ │ └────────────────────────┘
│ -service (Core) │ │ -service │ │
└─────────┬──────────┘ └──────┬──────┘ │
│ OHS │ │
│ (cross-tenant │ │
│ read-only) │ │
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────────┐
│ bff-consumer-svc │ │ bff-tenant- │ │ bff-backoffice-svc │
│ (web + mobile │ │ booking-service │ │ (Electron desktop; │
│ meta layer) │ │ (web + mobile │ │ exposes /sync/v1/ │
└──────────────────┘ │ per-tenant) │ │ pull|push) │
└──────────────────┘ └──────────────────────┘

External vendors → ACL inside the owning service:
• PayPal / card processors / MFS → payment-gateway-service
• TTLock / Salto / Assa Abloy / Wiegand → lock-integration-service
• OIDC / SAML IdPs → iam-service
• LLM / embedding / TTS providers → ai-orchestrator-service
• Email / SMS / push providers → notification-service

Saga participants (key cross-service flows)

  • Booking sagareservation-service orchestrates: inventory-service (hold) → pricing-service (final quote) → payment-gateway-service (intent + capture) → reservation-service (confirm) → lock-integration-service (issue key on check-in) → notification-service (confirmation, pre-arrival, key delivery). Compensation: release hold, refund payment, revoke key.
  • Cancellation sagareservation-servicebilling-service (refund eligibility) → payment-gateway-service (refund) → inventory-service (release allocation) → lock-integration-service (revoke key if issued) → notification-service (cancellation notice).
  • Check-in/check-outreservation-servicelock-integration-service (issue/revoke key) → housekeeping-service (queue turnover on check-out) → billing-service (close folio) → notification-service (post-stay).
  • Listing publish sagaproperty-servicetheme-config-service (resolve theme) → pricing-service (active rate plans) → search-aggregation-service (index) → bff-consumer-service (cache invalidation).
  • AI HITL flow — any service → ai-orchestrator-service (proposal + provenance + safety verdict) → human review in backoffice → <originating-service> (commit with decisionId).

Tenant isolation invariant

  • Every service except search-aggregation-service scopes every read and write to a single TenantId resolved from the JWT and the X-Tenant-Id request header (cross-checked).
  • search-aggregation-service is the only service authorized to read across tenants, and only over an explicit projection of fields marked cross_tenant_searchable: true in services/search-aggregation-service/DATA_MODEL.md. PII, payment data, key credentials, and operational secrets are never indexed.
  • BFFs do not widen the tenant scope; they only fan out within the authenticated tenant (or, for the consumer meta BFF, only call the cross-tenant search service).

Online vs offline footprint

ServiceBackend (Cloud Run)Replicates to desktop SQLite
iam-serviceyessession + device binding only
tenant-serviceyestenant settings snapshot (read-only)
property-serviceyesyes (rooms, room types, amenities)
reservation-serviceyesyes (active reservations + history within window)
pricing-serviceyesrate plan snapshot
inventory-serviceyeshot window (today + N days)
housekeeping-serviceyesyes (full task board)
maintenance-serviceyesyes
billing-serviceyesdrafts + open folios
payment-gateway-serviceyesno (online-only; cash-on-arrival captured offline then synced)
staff-serviceyesshift schedule snapshot
notification-serviceyesno (queued for later send)
reporting-serviceyesrecently-viewed reports cache
analytics-serviceyesno
ai-orchestrator-serviceyeslocal ONNX models for offline inference
theme-config-serviceyestheme snapshot
file-storage-serviceyesthumbnails + critical assets
lock-integration-serviceyesyes (key state snapshot; fallback encoder queue)
search-aggregation-serviceyesno (cloud-only)
bff-consumer-serviceyesno
bff-tenant-booking-serviceyesno
bff-backoffice-serviceyeshosts the /sync/v1/pull|push endpoints

Conflict policies for every replicated aggregate are declared in each service's SYNC_CONTRACT.md and summarized in docs/02-enterprise-architecture.md.

How to add a new service

  1. Confirm the bounded context. A service maps 1:1 to a context. If the context already exists in the table above, do not split it. If a genuinely new context is needed, add it to docs/02-enterprise-architecture.md first.
  2. Get user approval. A new service is a strategic addition; the user must approve it before any artifact is committed.
  3. Add the catalog row to the table above (this file). Pick a Domain Type, Primary Storage, Owner, and Phase. Write a one-paragraph Summary.
  4. Add a summary file in this folder: docs/03-microservices/<name>.md. Mirror the section headings of the existing summaries (purpose, responsibilities, data owned, key APIs, key events, upstream/downstream, NFRs).
  5. Create the 17-doc bundle under services/<name>/ per docs/standards/SERVICE_TEMPLATE.md. Stubs are acceptable initially, but every file must exist.
  6. Reserve an ID prefix in docs/standards/NAMING.md for any aggregate the service introduces.
  7. Register error codes in docs/standards/ERROR_CODES.md for any new failure surface.
  8. Update the context map above to reflect upstream/downstream and saga participation.
  9. Open an ADR under docs/architecture/ describing the rationale, alternatives considered, and consequences.
  10. Only after the spec set is approved, scaffold the code in the application monorepo via the future /scaffold-service <name> command. Tests tenant-isolation.spec.ts, outbox.spec.ts, inbox.spec.ts must pass before any feature work.

The full readiness gate is in docs/standards/SERVICE_TEMPLATE.md and the per-PR checklist is in docs/standards/DEFINITION_OF_DONE.md.