Operations
1. Deployment
| Thuộc tính | Giá trị |
|---|---|
| Image | registry/nx-seller-finance:<tag> |
| Container Port | 3000 |
| External Port | 31040 |
| Snowflake ID | 4 |
| Replicas (mặc định) | 1 (dev) / 2+ (staging+) |
| Resources (req/lim) | 200m / 1 CPU, 512Mi / 2Gi memory |
| HPA target | CPU 70% (khi scale) |
| Migration mode | job RUN_MODE=migrate trước rollout; on-boot cho dev |
| Live probe | GET /v1/api/finance/healthz |
| Ready probe | GET /v1/api/finance/readyz |
Scale consumer vượt 1 replica sẽ trải các partition trên
SVC-00040-FINANCE_CONSUMER_GROUP. Hạch toán vẫn đúng dưới concurrency vì mỗi dòng tài khoản được khóaFOR UPDATEtrong khi post phiếu.
Traefik routing labels
yaml
labels:
- "traefik.enable=true"
- "traefik.http.routers.finance.rule=PathPrefix(`/v1/api/finance`)"
- "traefik.http.services.finance.loadbalancer.server.port=3000"Hạ tầng bắt buộc
| Dependency | Tại sao |
|---|---|
| PostgreSQL | Datastore chính (schema finance) |
| Kafka brokers | Bắt buộc — component throw khi boot nếu APP_ENV_KAFKA_BROKERS rỗng |
| Redis | Cache authorization + WebSocket emitter pub/sub |
@nx/identity reachable | JWKS verify trên mỗi JWT |
@nx/commerce + Debezium | Luồng merchant CDC điều khiển đối soát tài khoản |
2. Observability
| Signal | Nguồn | Nơi xem |
|---|---|---|
| Logs | stdout (IGNIS structured logger, định dạng key: %s) | kubectl logs deploy/finance / Loki |
| Health | GET /v1/api/finance/healthz, GET /readyz | Gateway portal |
| OpenAPI live spec | GET /v1/api/finance/doc/openapi.json | Gateway portal explorer |
| Metrics | Traefik gateway (Prometheus scrape) | Grafana — gateway dashboard |
Trường log quan trọng
| Trường | Nguồn | Ghi chú |
|---|---|---|
requestId | header X-Request-Id | Propagate cross-service |
merchantId | request scope / event | Khóa tenant |
voucherNumber / voucherId | FinanceVoucherService | Vết audit hạch toán |
topic / partition / offset | log consume Kafka | Tọa độ replay |
accountId / postingSequence | toán balance | Alert toàn vẹn |
Truy vấn log hữu ích
| Câu hỏi | Query |
|---|---|
| Lỗi post phiếu | level=error AND FinanceWorkerService |
| Sự kiện thanh toán bị skip (không có account trên payload) | SKIP voucher AND finance.source.id |
| Replay idempotent (redeliver) | finance.voucher.idempotent_replay |
| Tài khoản âm | finance.account.went_negative |
| Thiếu tài khoản kiểm soát | INVENTORY/COGS control account missing |
3. Security
| Mối quan tâm | Biện pháp |
|---|---|
| AuthN | JWT (ES256, JWKS kéo từ identity); VerifierApplication |
| AuthZ | Casbin; list/count tài khoản giới hạn ở merchant mà user có GROUP policy; route single-entity gọi assertMerchantAccess (404 xuyên tenant, không phải 403) |
| Bí mật credential | PaymentIntegration.credential encrypted at rest; FinanceIntegrationService mask trong response |
| Secrets | K8s Secret mount làm env (APP_ENV_DB_URL, SASL password, v.v.) |
| TLS | Kết thúc tại Nginx → Traefik → service plaintext nội bộ cluster |
| Network policy | Cilium — chỉ cho phép gateway + Kafka + Postgres + Redis + identity |
| Soft-delete | deletedAt trên mọi entity finance; phiếu đã issue được void (đảo), không bao giờ xóa |
| Toàn vẹn hạch toán | Khóa FOR UPDATE theo từng tài khoản + postingSequence đơn điệu + DB partial unique index |
4. Runbook
4.1 Lớp Alert
| Alert | Trigger | Check | Fix | Escalate |
|---|---|---|---|---|
FinanceHighErrorRate | 5xx >5% trong 5m | kubectl logs deploy/finance | grep level=error | xác định route lỗi; rollback deploy gần đây | on-call backend |
FinanceConsumerLag | lag group tăng | broker consumer-group lag | check lỗi handler (offset không commit = vòng lặp redeliver) | on-call SRE |
FinancePostingFailure | lỗi FinanceWorkerService | grep handler + voucher | giải quyết gốc rễ; redeliver replay sau khi fix | on-call backend |
FinanceMissingControlAccount | log control account missing | xác nhận merchant CDC đã chạy | re-emit merchant CDC hoặc tạo thủ công tài khoản INVENTORY/COGS | on-call backend |
FinanceAccountNegative | cảnh báo went_negative | review hạch toán cho tài khoản đó | đối soát qua phiếu ADJUSTMENT (overdraft được phép, không chặn) | finance ops |
4.2 Thao tác thường gặp
| Thao tác | Lệnh |
|---|---|
| Tail log | kubectl logs -n <ns> -f deploy/finance |
| Chạy migration thủ công | kubectl exec -it deploy/finance -- bun run migrate |
| Replay một Kafka topic | reset offset SVC-00040-FINANCE_CONSUMER_GROUP; idempotency dedup các replay |
| Inspect ledger của một phiếu | SELECT * FROM finance."FinanceTransaction" WHERE finance_voucher_id = '<id>' ORDER BY line_number |
| Đối soát một balance | phát hành một phiếu ADJUSTMENT thủ công (reason correction / cash_count) — không bao giờ UPDATE balance trực tiếp |
4.3 Kịch bản phục hồi
| Kịch bản | Recovery |
|---|---|
| Handler crash giữa post | Hạch toán là một DB transaction → rollback; offset không commit → redeliver, replay sạch |
| Kafka redeliver trùng | tryIdempotentReplay trả về phiếu hiện có; không post đôi |
Sự kiện thanh toán không có attempt.finance.source.id | INFO-skip theo thiết kế (không chọn account) — điều tra payload phía sale, không phải finance |
| Hạch toán sai | void phiếu (post bút toán đảo cân bằng); phiếu COGS / INVENTORY_ADJUSTMENT không void được — sửa bằng một ADJUSTMENT mới |
| Merchant thiếu tài khoản mặc định | xác nhận CDC giao `op c |
5. Cross-Service Runbook
Với sự cố trải nhiều service, xem runbook/ trung tâm:
- Thanh toán bán hàng đã post nhưng không có phiếu finance — TBD
- Thiếu COGS tồn kho cho mặt hàng đã bán — TBD
6. Trang liên quan
- Configuration
- API Events — Kafka topic để replay
- Integration — mạng service anh em
- Decisions