AI generated
This page is generated from AUDIT.md at the repo root by adb-doc/scripts/sync-audit.js. Edit the source, not this copy.
ADB Monorepo — Audit, Use Cases & Flow Maps
AI generated. This document was drafted by an LLM and should be reviewed before being trusted as load-bearing. The rendered version on the docs site is at
architecture/audit.mdand is regenerated from this file byadb-doc/scripts/sync-audit.js.
Repo: hlc-lifeconnect/adb (monorepo, ex-submodules, consolidated commit 6376e7e). Domain: LifeConnect ADB — real-estate management platform (people, properties, contracts, accounting). Stack: Spring Boot 3.1.3 + WebFlux reactive (Java 18), Angular 19 (legacy) + Cloudflare Workers (new), MongoDB Atlas + S3 + SQS/SNS + Keycloak, deployed via Helm on AKS (primary) / AWS (secondary).
1. Service dependency map
classDiagram
class adb_ui["adb-ui (legacy)"]
class adb_web_ui["adb-web/ui"]
class adb_web_bff["adb-web/bff"]
class proxy["adb/proxy (Nginx)"]
class persons["adb-persons :8081"]
class parts["adb-parts :8085"]
class contracts["adb-contracts :8084"]
class accounting["adb-accounting :8089"]
class files["adb-files :8083"]
class utilities["adb-utilities :8082"]
class aggregates["adb-aggregates :8086"]
class views["adb-views :8092"]
class reports["adb-reports :8090"]
class tickets["adb-tickets (external)"]
adb_ui --> proxy
adb_web_ui --> adb_web_bff
adb_web_bff --> proxy
proxy --> persons
proxy --> parts
proxy --> contracts
proxy --> accounting
proxy --> files
proxy --> utilities
proxy --> aggregates
proxy --> views
proxy --> reports
proxy --> tickets
persons --> files
parts --> persons
parts --> contracts
parts --> utilities
contracts --> persons
contracts --> parts
contracts --> files
contracts --> accounting
contracts --> utilities
accounting --> persons
accounting --> parts
accounting --> contracts
accounting --> files
accounting --> utilities
aggregates --> persons
aggregates --> parts
aggregates --> contracts
aggregates --> files
aggregates --> utilities
aggregates --> tickets
views --> persons
views --> parts
views --> contracts
views --> files
reports --> aggregates
utilities and files are leaves (called by everyone, call no one). views is event-driven only (writes via SQS, reads via HTTP for enrichment). reports is the only consumer of aggregates.
1bis. How it fits together — the 60-second story
- One Maven parent (
adb/) defines the shared spine. Sub-modulesadb-common(incl. theFQDNenum that is the service registry),adb-model,adb-messaging(SNS/SQS abstraction),adb-openapi,adb-actions,adb-action-logs,adb-descriptor,adb-communication,adb-test. Every business service depends on this parent. - Service discovery is DNS, not Eureka.
FQDN.PERSONS = http://adb-personsresolves via KubernetesServicerecords created by Helm charts inadb-charts. No registry runtime. Theadb/README.mdreferences tolc-adb-registry/lc-adb-gatewayon Cloud Foundry are stale. - Authoritative writes live in 6 services: persons, parts, contracts, accounting, files, utilities. Each owns its MongoDB DB; no cross-DB joins.
- Reads are split into 3 patterns: (a) direct service call, (b)
adb-aggregatesHTTP fan-out (stateless, no DB), (c)adb-viewsSQS-fed projections (denormalised, eventual-consistent). - Three communication patterns coexist — synchronous HTTP via
WebClient+FQDN, async via SNS/SQS (adb-messaging), and a legacy RabbitMQ-only path used byadb-graph(Neo4j). The cohabitation is technical debt. - Edge is mid-migration.
adb-ui(Angular 19) still hits the Nginx proxy directly;adb-web(Hono BFF + static Angular on Cloudflare Workers) is being stood up but only/healthzis implemented. - Documentation lives in
adb-doc/(VuePress 2 → Cloudflare Pages). It is the canonical reference and is impressively in sync with code (FQDN enum, ports, charts, proxy routes, listener counts all match what's insrc/). - Docs hosting is mid-migration. The current branch (
docs/cloudflare-pages-architecture-and-services) cutsadb-docover from Bitbucket→EC2/Nginx to Cloudflare Pages. Build is green; thedocs.life-connect.frdomain cutover is still pending.
2. User journeys
2.1 Property manager — a typical day
journey
title Property manager day-to-day
section Login & dashboard
Open ADB UI: 4: User
Authenticate via Keycloak: 3: User, Keycloak
Land on dashboard (views): 5: User
section Onboard a tenant
Create person (tenant): 4: User, persons
Pick the unit from parts: 4: User, parts
Draft rental contract: 3: User, contracts
Generate PDF for signature: 4: contracts, reports
Upload signed scan: 4: User, files
Activate contract: 5: contracts
section Collect rent
SEPA direct debit batch: 5: contracts, accounting
Reconcile bank file: 4: User, accounting
Auto-allocate to invoices: 5: accounting
section Handle a problem
Tenant reports a leak: 3: User, tickets
Open ticket and assign supplier: 4: User, tickets
Track resolution: 4: User, views
section Reporting
Generate CRG report (charges récupérables): 5: User, reports, aggregates
Export accounting to Google Sheets: 4: User, accounting
2.2 Sell a unit
journey
title Sell a unit
section Trigger
Owner notifies sale to agency: 4: Owner, User
User opens part in UI: 4: User
User clicks "Sell": 4: User, parts
section Owner-side
End existing owner contract(s): 5: parts, contracts
Status -> SOLD, fill buyer: 5: contracts
Mono-property flips to condo: 4: contracts
section Tenant-side
Active rental on this part?: 3: contracts
End RC, status HANDED OVER: 5: contracts
section Aftermath
onContractModified events: 5: contracts
views projection updated: 5: views
Accounting closes invoices: 5: accounting
3. Core use case flows
3.1 User login (legacy UI)
sequenceDiagram
actor U as User
participant UI as adb-ui (Angular)
participant KC as Keycloak (realm ADB)
participant GW as adb/proxy (Nginx)
participant Svc as Any backend service
U->>UI: navigate to app
UI->>KC: redirect (Authorization Code + PKCE)
KC-->>U: login form
U->>KC: credentials + MFA
KC-->>UI: code -> JWT (id_token + access_token)
UI->>UI: store JWT, schedule refresh
U->>UI: click "Contracts"
UI->>GW: GET /contracts (Bearer JWT)
GW->>Svc: forward
Svc->>KC: fetch JWKS once at boot
Svc->>Svc: verify JWT signature & claims
Svc-->>UI: 200 JSON
3.2 User login (new BFF on Cloudflare)
sequenceDiagram
actor U as User
participant UI as adb-web/ui (Worker, static)
participant BFF as adb-web/bff (Hono Worker)
participant KC as Keycloak
participant T as Cloudflare Tunnel
participant GW as adb/proxy
participant Svc as Backend service
U->>UI: GET /
UI-->>U: SPA bundle
U->>BFF: GET /api/contracts (Bearer JWT)
BFF->>KC: fetch JWKS (cached in KV)
BFF->>BFF: verify JWT at edge
BFF->>BFF: KV cache lookup
alt cache miss
BFF->>T: forward via tunnel
T->>GW: HTTP internal
GW->>Svc: GET /contracts (Bearer JWT)
Svc-->>GW: 200 JSON
GW-->>T: 200 JSON
T-->>BFF: 200 JSON
BFF->>BFF: write KV cache
end
BFF-->>U: 200 JSON
Status: only /healthz is shipped today — this flow is the migration target.
3.3 Create a rental contract (end-to-end)
sequenceDiagram
actor U as Property manager
participant UI as adb-ui
participant C as adb-contracts
participant P as adb-persons
participant Pa as adb-parts
participant F as adb-files
participant A as adb-accounting
participant Ut as adb-utilities
participant R as adb-reports
participant SNS as SNS/SQS
U->>UI: New rental contract
UI->>C: POST /contracts/rental {tenantId, partIds, start, rent}
C->>P: GET /persons/{tenantId}
P-->>C: tenant payload
C->>Pa: GET /parts?ids=...
Pa-->>C: part details
C->>Ut: GET /catalog (rent-types, INSEE)
Ut-->>C: catalog values
C->>C: state = DRAFT, persist
C-->>UI: 201 contract {id, state: DRAFT}
U->>UI: Finalise offer
UI->>C: POST /contracts/{id}/finalise
C->>C: easyId assigned, state -> READY_TO_SIGN
C->>R: POST /reports/contract-pdf
R->>C: GET template values
R-->>C: PDF bytes
C->>F: POST /files (PDF)
F-->>C: fileId, presigned URL
C-->>UI: ready-to-sign {pdfUrl}
U->>UI: Upload signed scan
UI->>F: PUT presigned URL (S3 direct)
F->>SNS: onFileMetaDataModified
UI->>C: POST /contracts/{id}/sign {scanFileId}
C->>C: state -> SIGNED
C->>SNS: onContractModified
SNS-->>A: SQS contract-modified
SNS-->>views: SQS contract-modified
Note over A: schedules first invoice batch
3.4 Direct debit batch & payment received
sequenceDiagram
participant Cron as adb-contracts scheduler
participant C as adb-contracts
participant Bank as Bank (ISO20022 SEPA)
participant A as adb-accounting
participant SNS as SNS/SQS
participant V as adb-views
actor U as User
Cron->>C: monthly direct-debit run
C->>C: build pain.008 SEPA file
C->>Bank: send SEPA mandate batch
C->>SNS: onDirectDebitProcessed
SNS-->>A: SQS direct-debit-processed
A->>A: state PARKED -> BOOKED (auto)
A->>A: post accounting entries
A->>SNS: onAccountingEntryModified
SNS-->>V: SQS accounting-event-modified
V->>V: update dashboard projection
Note over Bank: a few days later
Bank-->>U: bank statement / camt.054
U->>A: import bank file
A->>A: match payment to invoice (auto-allocate)
alt match found
A->>A: state -> BOOKED, settled=true
else no match
A->>A: state -> ERROR
A->>U: surface for manual fix
end
A->>SNS: onPaymentModified
3.5 Sell a unit
sequenceDiagram
actor U as User
participant UI as adb-ui
participant Pa as adb-parts
participant C as adb-contracts
participant A as adb-accounting
participant SNS as SNS/SQS
participant V as adb-views
U->>UI: Sell part (buyer, date)
UI->>Pa: POST /parts/{id}/sell
Pa->>C: GET owner contracts for part
C-->>Pa: contracts list
Pa->>C: PATCH owner contract endDate, status=SOLD, buyer
alt mono-property
C->>C: also update building owner contract, isCondo=true
end
Pa->>C: GET active rental contracts on part
C-->>Pa: RC list
alt RC active
Pa->>C: PATCH RC endDate, state=HANDED_OVER
C->>SNS: onContractModified
end
C->>A: end-of-contract reconciliation
A->>A: close pending invoices, refund deposit
SNS-->>V: SQS contract-modified, part-modified
V->>V: rebuild property projection
Pa-->>UI: 200 sold
3.6 Upload a document (presigned URL)
sequenceDiagram
actor U as User
participant UI as adb-ui
participant F as adb-files
participant S3 as AWS S3
participant SNS as SNS
U->>UI: choose file
UI->>F: POST /files/presign {name, mime, size, ownerId}
F->>F: persist files{} doc, status=PENDING
F->>S3: generate presigned PUT URL
F-->>UI: {fileId, putUrl, expiresIn}
UI->>S3: PUT putUrl (binary)
S3-->>UI: 200
UI->>F: POST /files/{id}/complete
F->>F: status=READY
F->>SNS: onFileUploaded, onFileMetaDataModified
Browser uploads bypass the JVM entirely — the only thing through adb-files is the metadata round-trip.
3.7 Generate a CRG / property report
sequenceDiagram
actor U as User
participant UI as adb-ui
participant R as adb-reports
participant Ag as adb-aggregates
participant P as adb-persons
participant Pa as adb-parts
participant C as adb-contracts
participant F as adb-files
participant Ut as adb-utilities
participant S3 as S3 templates bucket
U->>UI: Generate CRG for building X
UI->>R: POST /reports/crg {partId, period}
R->>S3: GET FreeMarker template
R->>Ag: GET /aggregates/property/{partId}
par
Ag->>P: GET owners, tenants
Ag->>Pa: GET part tree, charges
Ag->>C: GET active rentals
Ag->>F: GET document refs
Ag->>Ut: GET allocation keys, INSEE
end
Ag-->>R: enriched DTO
R->>R: render FreeMarker -> HTML
R->>R: html2pdf via flying-saucer/iText
R-->>UI: PDF stream
UI-->>U: download
Worth noting: every other report generator goes through aggregates. reports is intentionally synchronous and stateless beyond template metadata.
3.8 Event propagation — onContractModified
sequenceDiagram
participant C as adb-contracts
participant SNS as SNS topic onContractModified
participant Q1 as SQS dev-views-contract-modified
participant Q2 as SQS dev-accounting-contract-modified
participant V as adb-views
participant A as adb-accounting
participant DLQ as DLQ
C->>SNS: publish event
SNS-->>Q1: fanout
SNS-->>Q2: fanout
par views consumer
Q1->>V: deliver
V->>C: GET /contracts/{id} (re-fetch full)
V->>V: rebuild projection
V->>Q1: ack
and accounting consumer
Q2->>A: deliver
A->>A: schedule next call-for-rent
A->>Q2: ack
end
Note over Q1,DLQ: failed messages move to DLQ after retries
adb-views runs 8 such consumers (verified in MessagingFunctions.java): tickets, parts, contracts, accounting events, file metadata, charges, market performance, accounting entries.
4. State machines
4.1 Rental contract
stateDiagram-v2
[*] --> DRAFT: create with tenant + parts
DRAFT --> DRAFT: patch payload
DRAFT --> READY_TO_SIGN: finalise offer (easyId required)
DRAFT --> [*]: delete
READY_TO_SIGN --> READY_TO_SIGN: patch payload
READY_TO_SIGN --> CANCELLED: customer refuses
READY_TO_SIGN --> SIGNED: upload scan
SIGNED --> TERMINATED: tenant gives notice
SIGNED --> HANDED_OVER: part sold while rented
CANCELLED --> [*]
TERMINATED --> [*]
HANDED_OVER --> [*]
4.2 Incoming invoice (supplier)
stateDiagram-v2
[*] --> DRAFT: id allocated, no easyId
DRAFT --> [*]: cancel (deletes ticket + event)
DRAFT --> OPEN: confirm (easyId issued)
OPEN --> OPEN: PATCH (priority, persons, parts)
OPEN --> CLOSED: close
CLOSED --> OPEN: re-open
CLOSED --> ARCHIVED: archive
ARCHIVED --> [*]
4.3 Incoming payment
stateDiagram-v2
[*] --> PARKED: payment ingested (BULK / Excel / UI)
PARKED --> ERROR: processing fails
ERROR --> PARKED: fix
PARKED --> BOOKED: confirm (creates accounting entries)
BOOKED --> REVERSED: reverse (guards: not settled, period open)
BOOKED --> ARCHIVED: archive
REVERSED --> ARCHIVED
ARCHIVED --> [*]
4.4 Ticket (intervention)
stateDiagram-v2
[*] --> DRAFT: ticket + first ticketEvent (creation)
DRAFT --> [*]: cancel
DRAFT --> OPEN: confirm (easyId)
OPEN --> OPEN: PATCH
OPEN --> CLOSED: close
CLOSED --> OPEN: re-open
CLOSED --> ARCHIVED
ARCHIVED --> [*]
5. Data ownership at a glance
erDiagram
PERSON ||--o{ ORGANIZATION : memberOf
PERSON ||--o{ INVITATION : invited
PART ||--o{ PART : children
PART ||--o{ ASSET : holds
PART ||--o{ CHARGE : charges
PART ||--o{ SALE : sales
CONTRACT ||--o{ DIRECT_DEBIT : sepa
CONTRACT }o--|| PERSON : tenantOrOwner
CONTRACT }o--o{ PART : relatedParts
INVOICE }o--|| CONTRACT : billsFor
INVOICE ||--o{ ACCOUNTING_ENTRY : posts
PAYMENT ||--o{ ACCOUNTING_ENTRY : reverses
PAYMENT }o--|| INVOICE : settles
LEDGER_ACCOUNT ||--o{ ACCOUNTING_ENTRY : holds
FILE }o--|| PERSON : owner
FILE }o--o{ CONTRACT : attachedTo
Each box lives in one Mongo DB (named adb-<service>). Cross-DB relations are referential ids only — propagation is HTTP read or SQS event.
6. Module-by-module fiches
Shared spine — adb/ (Maven parent + Nginx proxy)
| Module | Role |
|---|---|
adb-common | FQDN enum, REST client base, error handling, security context util |
adb-model | Shared DTOs / catalog values |
adb-messaging | SNS publisher + SQS listener wrapping (Spring Cloud AWS 3.0.4) |
adb-openapi | Springdoc helpers, OpenAPI generation rules |
adb-actions / adb-action-logs | Cross-cutting user-action audit trail |
adb-descriptor | Catalog metadata system |
adb-communication | Notifications/email plumbing |
adb-test | Shared JUnit/Reactor test harness |
proxy/ | Nginx configs per env (dev, int, stage, preprod, prod). Routes: /persons /parts /contracts /accounting /files /utilities /aggregates /view /reports /tickets /notes→tickets /auth /oauth/. SSL termination + Keycloak forwarding. |
Versioning lockstep: adb.version = 0.3.107-SNAPSHOT propagated to every consumer via dependencyManagement.
Write-path services
adb-persons :8081 — owns people, organisations, invitations, company settings. Only service with admin write access to Keycloak (provisions users via realm-management). Outbound: adb-files (avatar/docs). Emits onPersonModified, onOrganizationModified. Active.
adb-parts :8085 — buildings, lots (parts hierarchy), assets, charges, budgets, sales. Outbound: persons, contracts (sale flow), utilities (allocation keys). Emits onPartModified, onChargeModified, onMarketPerformanceModified. Active.
adb-contracts :8084 — leases (rental, insurance, guarantee, supplier, condo), SEPA mandates (ISO20022), dunning. Spring Statemachine 2.2.3 drives RentalContractStateMachine. PDF via FreeMarker + flying-saucer. Outbound: persons, parts, files, accounting, utilities. Emits onContractModified, onContractUpdated, onDirectDebitProcessed, dunningNoticeSent. Active.
adb-accounting :8089 — biggest backend. Invoices, payments, ledger accounts, accounting entries, fiscal year, CRG (Charges Récupérables Grevant), rental allowance statements. 17 @RestController, ~16 distinct @Document collections. State machines for payment + invoice. BlockHound enabled in cloud profile. Outbound: persons, parts, contracts, files, utilities. Heavy SQS consumer (re-listens own events for projections). Active.
adb-files :8083 — pure leaf. S3 binaries + Mongo metadata, presigned URLs for direct browser upload/download, multipart, PDF concat, tagging. No outbound service calls. Emits onFileUploaded, onFileMetaDataModified. Active.
adb-utilities :8082 — leaf. Catalogs, i18n, configurations, dashboards, allocation keys, INSEE indices (cron 0 0 12 * * *), notifications. No outbound service calls. Emits onIndexPublished. Active.
Read-path services
adb-aggregates :8086 — no DB. Reactive composition of multi-service DTOs over HTTP (persons, parts, contracts, files, utilities, tickets). Exposes adb-aggregates-model as a Maven artefact consumed by adb-reports. Active.
adb-views :8092 — projection store for dashboards. 8 @SqsListener methods in MessagingFunctions.java (verified): tickets, parts, contracts, accounting events, file metadata, charges, market performance. Owns denormalised collections (parts, contracts_entries, accounting_event). Reads enrich via HTTP (persons, parts, contracts, files). BlockHound enabled. Active.
adb-reports :8090 — synchronous PDF generation. FreeMarker + iText. Pulls enriched data from adb-aggregates. Templates stored in dev.templates.life-connect.fr S3 bucket. Active.
Frontend
adb-ui — Angular 19.1.0, RxJS 7.8.1, Material, CKEditor 5, Sentry, MongoDB Charts embed, GTM. ~28 domain HttpClient services. 7 environment configs (dev/int/staging/preprod/prod + dev variants). Auth via keycloak-angular. Hits the Nginx proxy directly. Legacy — being replaced by adb-web.
adb-web — Yarn 4 + Turborepo monorepo. apps/ui (static Angular on Cloudflare Workers) + apps/bff (Hono 4.6 on Workers, Wrangler 4). Shared packages/api-client (OpenAPI-generated), shared-types, ui-components, ui-styles, eslint-config. BFF responsibilities: JWT validation at edge, KV cache, Durable-Objects rate-limit, fan-out via Cloudflare Tunnel to the Nginx proxy. Status: only /healthz shipped. Migration in progress.
Infrastructure & ops
adb-charts — Helm charts (charts/services/templates/*.yaml — 11 service Deployments verified: accounting, aggregates, contracts, files, parts, persons, reports, tickets, ui, utilities, views). Note: the adb-tickets chart ships here even though the service code lives in a separate repo. Plus cert/, filebeat/ (log shipping → Elasticsearch), ingress-route/ (Traefik), security/ (UAA legacy + OAuth scopes), services_prod/ overlay. Terraform under terraform/ for Neo4j. AKS primary, AWS secondary. Multi-env values files.
adb-infrastructure — non-K8s glue. mongodb-atlas/data-scripts/ ≈ 37 migration scripts (Atlas CLI + Realm CLI for triggers/functions). aws/ for EventBridge rules routing external webhooks → SQS. No root Terraform — fragmented CLI/console management.
adb-tests-artillery — Artillery 2.0.18 + Node 23.6.1. Three-stage suite: 01-setup auth → 02-create dataset → 03-apicheck per domain. Direct Mongo cleanup before/after. Google-Sheets-driven test data, Mochawesome reports as Bitbucket pipeline artefacts.
adb-doc — VuePress 2.0.0-rc.20 + Vue 3.5 + Mermaid 11.4. Node >=22 enforced (mermaid → chevrotain v12); packageManager: yarn@1.22.22 pinned to keep classic Yarn inside this Yarn-4 monorepo. Sections: architecture (overview/communication/data/auth), 20 per-service fiches under services/, functional epics, technical epics, product specs, data dictionary. Build: yarn docs:build → docs/.vuepress/dist/. Cloudflare Pages config lives in docs/.vuepress/public/ (_redirects strips trailing slashes; _headers sets cache policy). No wrangler.toml — CF Pages is dashboard-managed, not IaC. docs.life-connect.fr cutover pending; legacy bitbucket-pipelines.yml → EC2/Nginx still present but orphaned.
External / out-of-monorepo
adb-tickets — active, deployed by adb-charts, repo elsewhere. Subsumed adb-notes functionality (R4). Emits onTicketModified, onTicketEventModified.
adb-notes — deprecated. Removed from K8s. /notes route in Nginx + FQDN.NOTES enum entry remain — both should be cleaned up.
adb-graph — incomplete. Neo4j-backed relationship graph; consumes via RabbitMQ only (exchanges adb-persons-x, adb-tickets-x, channels for parts/contracts; DLX adb-graph-dlx). No Helm chart, no /graph upstream resolves to anything live. Status ambiguous.
6bis. Cross-cutting facts worth knowing
- One DB per service, no cross-service joins. Propagation = HTTP read or SQS event.
- Reactive end-to-end: WebClient + Reactor + Spring Data Reactive Mongo. BlockHound is the safety net (cloud profile only, on
adb-viewsandadb-accounting). - JWT stateless at every service via
spring-boot-starter-oauth2-resource-server+ JWKS. No per-request Keycloak hop. - TypeScript clients auto-generated by
swagger-codegen-v3into@life-connect.fr/<service>npm packages, consumed byadb-uiand (via OpenAPI)adb-web/packages/api-client. - Lockstep release: every backend service tracks the same
adb.version. Release process: bump parent → bump each child → release branch per service. - Region: SQS/SNS in
eu-west-1. MongoDB Atlas multi-env (adb-development/adb-integration/adb-production). - CI: Bitbucket Pipelines per repo; deploy to S3 maven repo + npm + Cloud Foundry / K8s depending on age of pipeline.
6ter. Observability & security at a glance
- Logs: Filebeat DaemonSet (
adb-charts/charts/filebeat/) ships pod logs to Elasticsearch (elasticsearch-cloud/elasticsearch-localsecrets). No alternative aggregator. - Metrics: every backend exposes
/<svc>/actuator/{health,info,prometheus}viaspring-boot-starter-actuator+micrometer-registry-prometheus. - Tracing:
micrometer-tracing-bridge-braveis in every backend pom;traceId/spanIdare interleaved into the log pattern. No OpenTelemetry collector wired — traces stay in logs. - Errors: Sentry is on
adb-uionly (@sentry/browser6.11.0,adb-ui/src/app/core/integrations/sentry-error-handler.ts). Not onadb-webBFF, not on any backend. - AuthN:
spring-boot-starter-oauth2-resource-serveris uniform across services. Issuerhttps://<env>-security.life-connect.fr/realms/ADB; JWKS fetched once at boot, then in-process verification. - AuthZ to Keycloak admin: only
adb-personswrites back to Keycloak —ReactiveOAuth2AuthorizedClientManager+ client-credentials registrationlife-connect-adb-admin(adb-persons/.../KeycloakWebClientConfig.java). Admin URI derived by replacing/realms/with/admin/realms/. - Rate limiting / mTLS / IP allowlist: none today. The
adb-webBFF advertises Durable-Objects rate-limit but only/healthzis shipped. - DLQs: each consumer wires
sendToDlq: <env>-<svc>-dlq(e.g.adb-accounting/src/main/resources/application.yml:50). No CloudWatch alarm on DLQ depth — config inadb-infrastructure/aws/doesn't include one.
7. Friction points
adb/README.mdstill namescfapps.ioCloud Foundry endpoints andlc-adb-registry. The live system is K8s-DNS. Stale.- Two messaging worlds coexist: SQS/SNS everywhere except
adb-graph(RabbitMQ). Retire or finish migrating. - Zombies in
FQDN, Nginx, docs:adb-notes,adb-graph,adb-notifications. Cleanup or revive. adb-webBFF is essentially/healthz. Pick one read endpoint and ship it end-to-end through the tunnel as a vertical slice — proves the migration path.- Infra is split across Helm + Atlas CLI + Realm CLI + EventBridge + Cloudflare consoles. No single review surface.
- Lockstep
adb.version = 0.3.107-SNAPSHOTcouples release cadence across all services. adb-viewsis the consistency pivot. A silently failing listener = drifting dashboards. DLQ depth alerting is non-negotiable — and as of today, not in place (queues exist, CloudWatch alarms don't).adb-dochas no global "AI generated" admonition mechanism. The default theme has no layout override or shared component for it, so every page needing the banner has to add it manually. Today this relies entirely on author discipline.- CF Pages docs site is dashboard-managed (no
wrangler.toml, no Terraform). Adds another fragmented surface to the list in §7.5.
8. Where to read further
adb-doc/docs/architecture/{overview,communication,data,auth}.md— definitive arch docs.adb-doc/docs/services/<name>.md— per-service fiches.adb-doc/docs/functional-epics/stateMachine/— formal state machines.adb-doc/docs/functional-epics/process/— business processes (create, sell, review, RC-renewal).adb/adb-common/.../FQDN.java— service registry of record.adb/proxy/default.conf— actual gateway routing.adb-charts/charts/services/templates/— what is actually deployed.