Integration
Ledger has no synchronous HTTP calls to sister services. All cross-service data is read directly through
@nx/corerepositories (shared schema, same database). It depends on@nx/assetfor file storage and on identity only for JWT verification.
1. Sister Services
Direction:→calls /←called by /↔bidir.
| Sister | Direction | Surface | Contract | Auth | Failure Mode | Idempotency |
|---|---|---|---|---|---|---|
@nx/identity | → | JWKS verification per request | VerifierApplication | JWKS (ES256) | 401 on invalid/expired JWT | — |
@nx/asset | → | MetaLinkService + S3 upload/download | in-process (@nx/core repo + BunS3Helper) | — | upload error → job REJECTED | orphaned-link cleanup pre/post run |
@nx/finance | ← | DB read: FinanceTransactionRepository | shared schema | — | empty result → empty ledger | read-only |
@nx/sale | ← | DB read: SaleOrderRepository | shared schema | — | — | read-only |
@nx/commerce | ← | DB read: MerchantRepository, TaxInfoRepository, VnProvince/VnWard | shared schema | — | missing merchant → validation error | read-only |
Cross-package reads are S1a-HKD only (real data). S2a–S2e currently use fixture JSON via
LedgerDataFixtureService(placeholder pending real integration).
2. External Systems
| System | Direction | Surface | Auth | Failure Mode |
|---|---|---|---|---|
| Kafka | ↔ | produce + consume ledger.generate | SASL SCRAM-SHA-512 (toggle APP_ENV_KAFKA_SASL_ENABLE) | broker down → enqueue throws → job REJECTED (ENQUEUE_FAILED) |
| S3 / Minio | → | encrypted PDF/XLSX put/get (BunS3Helper) | access/secret keys | upload error → job REJECTED |
| Redis | → | auth cache + WS pubsub | password | WS emit best-effort |
| Typst | in-proc | NodeCompiler PDF render | — | compile error → fresh compiler, then rethrow |
3. Critical Cross-Service Flows
3.1 S1a-HKD data fetch (real data)
| Step | Detail |
|---|---|
| 1 | Facade LedgerDataFetcherService routes by type to S1aHkdDataFetcherService |
| 5 | Worker validates with SCHEMA_MAP['S1a-HKD'].safeParse; parse failure → REJECTED |
3.2 File upload via @nx/asset
| Step | Detail |
|---|---|
| 2 | originalName must be a flat filename — BunS3Helper.isValidName() rejects /; path is built in normalizeNameFn |
| 4 | Download reverses: getLedgerFromS3Decrypted → decrypt → stream to client |
4. Contract Stability
| Surface | Stability | Versioning |
|---|---|---|
HTTP /v1/api/ledger/* | stable | URL /v1/ |
Kafka ledger.generate | stable (internal self-loop) | payload fields additive |
S3 key layout ledgers/{period}/{merchantId}/{version}/ | stable | — |
| S2a–S2e data source | beta — fixture placeholder, real fetch pending | — |