Le backend compte 36 modules (bounded contexts), chacun situé dans apps/api/src/modules/<bc>/ avec les sous-dossiers domain/, application/, infrastructure/. La couche HTTP est centralisée dans interface/http/, pas dans les modules.
| Module | Tranch. | Description |
|---|
| tenant | T2 | Racine multi-tenant : Tenant + provisioning + organisation (arbre org_tree_path, EstablishmentBusinessDate) + entitlements (plafonds écrits sous pms_control_plane, anti-élévation) + user-home-scope (ADR-00D82) |
| identity | T1 | Login Argon2id anti-énumération, sessions JWT HS256, MFA TOTP AES-256-GCM, AuthGuard, révocation NATS+Redis, SSO OIDC (account-linking anti-takeover, JIT opt-in), enrôlement TOTP au 1er login |
| authorization | T1 | RBAC PermissionResolver (deny-overrides, scope OrgPath préfixe), assign/revoke (outbox), cache Redis, permission-epoch, rôles builtin (receptionist/housekeeper/manager/maintenance-technician/accountant/tenant-admin), assign/revoke HTTP anti-élévation scope (ADR-00D82) |
| control-plane-audit | A10 | Identité opérateur nominative, chaîne d’audit CP (canonical_control_plane_v1 GELÉ), sessions web opaques + MFA TOTP inconditionnelle + CSRF Origin fail-closed, queries /admin/* |
| Module | Tranch. | Description |
|---|
| reservation | T6 | Contrat logique central (ADR-D21) : machine à états Tentative→Confirmed→CheckedIn→CheckedOut→Closed + Cancelled/NoShow/Walked, journal versions append-only NF203, multi-unité, SnapshotRate immuable à Confirmed, DepositPolicy, BookerRef polymorphe, long-stay (T23), pré-assignation optionnelle d’unité (ADR-00D81), timeline d’audit NF203 |
| stay | T7 | Occurrence physique (ADR-D21) : créé au check-in (atomique Folio I4), room-move (I5), check-out immuable (I3) + release d’unité |
| guest-profile | T4 | Profil + fidélité/ACSI, dédup/fusion, RGPD (anonymize() one-way, consentements append-only, docs chiffrés DEK/tenant MinIO) |
| traveler-registry | T10 | Fichier voyageurs R611-42 (PII chiffrée FieldCipher, rétention 6 mois, purge RGPD Temporal) ; exposé HTTP + saisie au check-in |
| Module | Tranch. | Description |
|---|
| inventory | T3 | Stock par-nuit (inventory_daily, modèle UNIQUE depuis migration 0088) : dispo = total−reserved−ooo ≥ 0, advisory xact lock (ADR-D15), UnitType immuable, Unit générique (chambre/emplacement/mobil-home), OOO manuel, Meilisearch |
| pricing | T5 | RatePlan versionné NF203, RateCalculationService pur, restrictions RM + fences, money-ratio half-up basis-points (ADR-D57), calendrier tarifaire éditable HTTP (saisons, restrictions) |
| allotment | T15 | Contingents groupes/TO (pickup dérivé, cutoff Temporal, hold sous advisory lock, attrition fail-closed NF203) ; exposé HTTP complet (ADR-G3) : 7 endpoints RBAC |
| distribution | T21 | SiteMinder pmsXchange (SOAP/OTA-2003-05) : anti-overbooking dispo nette à chaud, stop-sell, ACL OTA autoritaire, dédup messageUid |
| attribute-catalog | T3 | Catalogue EAV typé (zéro JSONB, ADR-0014) servant inventory + guest |
| Module | Tranch. | Description |
|---|
| folio | T0/T8 | Compte append-only (I1 : void = contre-écriture, Money bigint), clôture/règlement. kind : stay/master_event/reservation_deposit. chargeNature : revenue/disbursement/collected_tax/penalty. businessDate dérivée serveur (ADR-00D78). Taxe de séjour = ligne collected_tax (compte 4471) |
| deposit | T8 | SecurityDeposit (ADR-D41) : authorize/capture/void/refund, caution EDL |
| accounts-receivable | T8/T19 | DebtorAccount city ledger (ADR-D52), allocation, aging, dunning Temporal. VACAF (ADR-D55) : aide CAF = ventilation de paiement, jamais remise |
| fiscal-compliance | T8/Cluster 2 | Invoice numérotée NF203 (chaîne HMAC, FEC/JET-PAF), MandateFiscalProfile fail-closed, chaîne facture d’acompte (ADR-00D73) : ACOMPTE (CGI 269-2-c) vs ARRHES (art. 1590 Cc) |
| compliance-tax | T10 | Taxe de séjour (barème commune/classement/période, effective-dated, inaltérable) + TVA (vat_rate daté, 9 pays EU, résolveur pur) |
| owner-revenue | T25 | Gestion locative HPA : 2 moteurs fiscaux (transparent + commissionnaire CGI 256-V), OwnerStatement append-only NF203, IBAN chiffré |
| Module | Tranch. | Description |
|---|
| housekeeping | T16 | Board gouvernante, tâches HK (transitions idempotentes par état-cible, rejeu offline), OOO réactif → Inventory |
| asset-maintenance | T17a | WorkOrder cycle complet, 4-eyes (resolve ≠ verify), OOO réactif dédupliqué, Asset (XOR unit/common_area/standalone), photos presigned MinIO |
| workforce | T17b | StaffMember/Availability/suggest-staff, assignation WorkOrder |
| property-inspection | T20 | États des lieux opposables : contradictoire signatoryMode, immutabilité scellée + contentHash SHA-256, compteurs camping, branché caution |
| main-courante | T20 | Journal append-only (GRANT INSERT only), horodatage serveur |
| meter | T23 | Compteurs élec/eau/gaz : MeterReading inaltérable après facturation, energyPricingPolicy no_margin défaut fail-safe (ADR-00D61) |
| meal-plan | T15 | Plans restauration postés par le Night Audit |
| ancillary | T8/T15 | Produits/prestations vendables au folio |
| night-audit | T11 | Clôture businessDate (room charges/taxe/meal-plan/installments, no-shows, snapshot NightAuditCompleted), Temporal Schedule par établissement. Étapes : verrou → markNoShows → postRoomCharges → postTourismTax → postMealPlanCharges → postDueInstallments → avance businessDate → ancrage Merkle WORM → snapshot reporting |
| Module | Tranch. | Description |
|---|
| mice-events | T26 | Event/EventSession/EventQuote/Equipment : EXCLUDE GiST horaire (ADR-D42), MasterFolio = folio kind=master_event, survente équipement advisory lock |
| Module | Tranch. | Description |
|---|
| payment | T0 | PSP-agnostique : cycle EMV neutre, PaymentGatewayPort, refs opaques brandées (PCI SAQ A), InMemoryPaymentGateway seul adapter V1, assert-test-only-gateway fail-closed prod |
| cashless | T24 | Wallet = compte de tiers NF203 (419/467) : mouvements append-only, solde = Σ recomputable, miroir OsmoVente via pos-bridge |
| pos-bridge | T22 | ACL OsmoVente (ADR-D23) : CloudEvents HMAC idempotents, dédup messageUid, frontière NF203/NF525, GRANT isolé |
| public-api | T29a | API-key pmsk_live_* (SHA-256 timingSafe) + OAuth2 client-credentials → RBAC chemin unique ; rate-limit à tiers ; webhooks sortants signés HMAC (anti-SSRF, retry/DLQ, delivery log append-only) |
| Module | Tranch. | Description |
|---|
| notification | T18 | Multi-canal (EmailPort/SMSPort, V1 email-only), SmtpEmailAdapter réel, templates tenant-overridables, renderer eta |
| reporting | T27 | Enabling BC read-side CQRS (tables pms.reporting_*) : KPIs occupancy/ADR/RevPAU/LOS/segment projetés depuis NightAuditCompleted. Taxe de séjour = restitution. Pickup + forecast (ADR-G6) |
| audit | T0 | Chaîne HMAC NF203 tenant (canonical_v1 gelé, genesis non-forgeable, advisory lock par tenant, rotation RotatingSecretStore). Ancrage Merkle à chaque Night Audit (ADR-00D79) |
Non comptés comme modules métier, mais essentiels :
platform/persistence/ — Executor/Transactional, withTenantTransaction, outbox relay source, RotatingSecretStore, FieldCipher
platform/config/ — Zod env boot, pgbouncer-guard, rls-role-guard
platform/crypto/ — SecretStorePort KMS-agnostique (ADR-00D74), WebhookSigner
platform/temporal/ — 6 workflows (accès réservé à composition/saga/)
platform/messaging/ — NATS JetStream
platform/health/ — liveness/readiness endpoints
platform/outbox/ — table outbox, relay source
123 fichiers de migration, 0001 → 0124 (0021 sauté). Dernière migration : 0124 (home_scope utilisateurs, ADR-00D82).