Skip to content

Operations

1. Deployment

PropertyValue
Dev port1190 ⚠️ (siblings use 310x0)
Local nginx upstreaminvoice_upstream → 127.0.0.1:31140 (packages/gateway/local/nginx.conf)
Base path/v1/api (no per-service segment)
Run modesapi, worker (BullMQ issuance + claim-expiry), migrate
Migrationbun run migrate:dev (seeds VN admin data, configs, webhooks, permissions)
Snowflake ID range⚠️ unset (APP_ENV_..._WORKER_ID not configured)
Service codeSVC-00150-INVOICE (in core ServiceCodes); Kafka id defaults to SVC-00150-INVOICE_CONSUMER

⚠️ Pre-production reconciliation (from package AGENTS): assign a unique SVC code, a snowflake worker id, and a 310x0 port; resolve the SVC-00050 collision with inventory before any production deploy.

Build & run

bash
bun run rebuild      # clean + build (deps: core, iiapi, t-van, mq-pay)
bun run lint:fix     # ESLint + Prettier
bun run server:dev   # run with .env.development
bun run migrate:dev  # migrations / seeds

2. Observability

SignalSourceWhere to look
Logsstdout (structured key-value)kubectl logs <pod> / Loki
Issuance auditinvoice.InvoiceAuditTracingper-invoice event trail (eventType/outcome/before-after)
HealthIGNIS default health routegateway portal

Key log markers

MarkerMeaning
[handlePaymentSuccess]payment-driven issuance decision
[handleMerchantCDC] op=u tax unchanged, SKIPCDC diff short-circuit
[enqueueIssuance] ... partition: %spartition routing
[_handleIssuanceFailure] Scheduling retrytransient retry with backoff
[DLQ] invoice-issuancejob attempts exhausted → invoice FAILED + audit

3. Security

ConcernMitigation
AuthNJWT (ES256, JWKS from identity); VerifierApplication
AuthZPermission-gated controllers + AuthorizationService (merchant-level)
Provider credentialsAES-256-GCM, key = exactly 32 bytes / 64 hex (APP_ENV_INVOICE_CREDENTIALS_KEY)
Webhook trustTwo HMAC secrets: WEBHOOK_SECRET (merchant→platform), WEBHOOK_INTERNAL_SECRET (iiapi/commerce→platform, HMAC-SHA256 verified)
Buyer claim tokenrandom UUID, partial-unique, time-boxed (claimDeadline)
Secretsenv / Configuration table (encrypted); never in code
Soft-deletedeletedAt — no hard-delete by default

4. Runbook

4.1 Alert classes

AlertTriggerCheckFixEscalate
Issuance failures spikeInvoiceAuditTracing FAILED rate ↑logs [_handleIssuanceFailure] / provider 4xxinspect provider response payload; fix config/credentialsinvoice-team
BullMQ DLQ growth[DLQ] invoice-issuance logsRedis queue depth per partitionre-enqueue after fixing root causeon-call SRE
CDC TaxInfo driftFE shows stale merchant taxcompare metadata.tax vs TaxInfotrigger merchant update (re-CDC); verify diff logicinvoice-team
Webhook rejects401 on /webhookssignature mismatchrotate/realign WEBHOOK_* secretinvoice-team

4.2 Common operations

OperationHow
Tail logskubectl logs -n <ns> -f deploy/invoice
Inspect invoice statequery invoice.Invoice + InvoiceIssuance + InvoiceAuditTracing by sourceId
Replay a stuck issuancere-enqueue via issuance flow (jobId = orderId); idempotent on active invoice
Re-sync merchant taxre-emit/replay Merchant CDC; op=u diff-skips if unchanged
Inspect partition for an orderpartition = getPartitionByKey(orderId) (hashCode mod 3)

4.3 Known gotchas / tech debt

ItemDetail
No single transactionInvoice + InvoiceRequest creation not atomic (payment-success can precede request)
Config snapshot immutableprovider config copied at invoice creation; mid-lifecycle config edits do not apply
Service identity driftunset code/worker-id/port (see Deployment ⚠️)

Cross-service incidents: see /runbook/.

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.