13 KiB
CTO Audit Report — GoodGo POS System
Date: 2026-03-20 Auditor: CTO (Agent cbfd1a9f) Scope: Architecture decisions, service boundaries, tech debt, cross-service dependencies Branch: master (
d0211e5)
Executive Summary
Platform đang trong giai đoạn late-MVP với 15/24 services production-ready và POS flow đã hoạt động end-to-end (xác nhận qua deployment report 2026-03-13). Wave 1-3 fixes (202 files) đã giải quyết phần lớn P0 security và runtime bugs. Tuy nhiên, 5 vấn đề critical mới được phát hiện cần fix trước khi deploy staging: debug endpoints không có auth, SQL injection, BFF CORS wildcard, 4 mkt-* services chưa vào Docker Compose, và cross-service messaging chưa thực sự triển khai.
Critical Issues
C1 — Debug Endpoints [AllowAnonymous] trong Production Code
File: services/merchant-service-net/src/MerchantService.API/Controllers/StaffController.cs:249-390
Severity: BLOCKER — bất kỳ ai cũng có thể gọi vào production
5 endpoints không có authentication:
POST /api/v1/staff/debug/seed— tạo staff data tùy ý (line 249)POST /api/v1/staff/debug/update-userid— ghi đè userId của bất kỳ staff nào qua reflection (line 340)POST /api/v1/staff/debug/update-merchant— ghi đè merchantId của bất kỳ merchant nào (line 360)
Đây là privilege escalation / data tampering vulnerability cực kỳ nghiêm trọng. Các endpoint này phải được xóa hoàn toàn khỏi production code hoặc chỉ chạy trong Development environment.
Fix: Xóa ngay các method này hoặc wrap với if (env.IsDevelopment()) và thêm [Authorize(Roles = "SuperAdmin")].
C2 — SQL Injection trong StaffController
File: services/merchant-service-net/src/MerchantService.API/Controllers/StaffController.cs:307,367
Severity: HIGH — tham số từ query string được nối trực tiếp vào SQL
// Line 307 — merchant.Id là Guid (safe), nhưng pattern nguy hiểm
cmd.CommandText = $"SELECT id FROM shops WHERE merchant_id = '{merchant.Id}' LIMIT 1";
// Line 367 — userId và merchantId đến từ [FromQuery] — SQL INJECTION RISK
cmd.CommandText = $"UPDATE merchants SET user_id = '{userId}' WHERE id = '{merchantId}'";
Dù Guid tự sanitize, pattern string interpolation trong SQL là vi phạm security baseline. Bất kỳ refactor nào đổi type sang string sẽ tức thì trở thành lỗ hổng.
Fix: Dùng parameterized queries (cmd.Parameters.AddWithValue()).
C3 — BFF CORS Wildcard AllowAnyOrigin()
File: apps/web-client-tpos-net/src/WebClientTpos.Server/Program.cs:74-78
Severity: HIGH — cho phép bất kỳ domain nào gọi BFF API
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
Đây là điểm vào duy nhất của frontend. Nếu BFF có endpoint nhạy cảm, bất kỳ website nào cũng có thể khai thác CSRF.
Fix: Thay bằng whitelist cụ thể theo environment (localhost:3001, goodgo.vn, admin.goodgo.vn).
C4 — 4 mkt-* Services Không Có Trong Docker Compose (Port 5000 Conflict)
File: deployments/local/docker-compose.yml
Severity: HIGH — 4 services không thể chạy local hoặc staging
Services mkt-facebook, mkt-whatsapp, mkt-x, mkt-zalo đều thiếu trong docker-compose.yml. Lý do đã được ghi nhận trong ROADMAP nhưng chưa được giải quyết: tất cả 4 services được cấu hình với port 5000 (xung đột). Thực tế các services này cũng thiếu Traefik routes.
Fix: Gán ports 5021-5024, thêm vào docker-compose và Traefik. DevOps issue đang ở TODO trong ROADMAP Week 9-10.
C5 — Cross-Service Messaging Chưa Được Triển Khai
Severity: HIGH — tất cả IntegrationEvents/EventHandlers/ đều rỗng
Audit thư mục IntegrationEvents/EventHandlers trên 10 services: không có file .cs nào. Tất cả là thư mục rỗng. Đây có nghĩa là RabbitMQ được khai báo trong docker-compose nhưng không có service nào thực sự publish/consume messages qua event bus.
Điều này ảnh hưởng trực tiếp đến:
- Order → Kitchen deduction (đang dùng HTTP + Polly theo ROADMAP, nhưng đây là tight coupling)
- Promotion voucher redemption events (no consumer)
- Membership level changes (no consumer)
Hiện tại hệ thống hoạt động vì business flows quan trọng dùng HTTP trực tiếp. Nhưng đây là tech debt sẽ gây vấn đề khi scale.
Fix: Implement IEventBus abstraction với RabbitMQ backend, bắt đầu từ OrderCreatedIntegrationEvent → inventory deduction.
Warnings
W1 — TenantMiddleware Dùng String Interpolation trong SQL SET
Files: TenantMiddleware.cs trong 5 services (order, inventory, wallet, catalog, fnb-engine)
cmd.CommandText = $"SET LOCAL app.current_shop_id = '{shopId.ToString("D")}'";
Guid.ToString("D") an toàn trong thực tế vì Guid không chứa ký tự nguy hiểm. Nhưng cần chuẩn hóa sang NpgsqlCommand.AddParameter() để tuân thủ secure coding standards.
W2 — Test Coverage Cực Thấp (~15%)
Chỉ 1 trong 24 services (IAM) có CI pipeline chạy tests. Thống kê unit test files:
- IAM: 32 test files ✓
- FnB Engine: 16 test files ✓ (96 tests theo ROADMAP)
- Order: 5 test files
- Wallet: 8 test files
- Merchant: 3 test files
- 22 services còn lại: không có CI test pipeline
Target roadmap là 50% coverage trước Phase 3. Với tốc độ hiện tại sẽ không đạt được.
W3 — booking-service Thiếu K8s Staging Manifest
File: deployments/staging/kubernetes/ — không có booking-service.yaml
Booking service có trong docker-compose, có Traefik route (partial — thiếu /api/v1/schedules), có K8s production manifest, nhưng thiếu staging. Mọi staging deployment sẽ không include booking/spa flow.
W4 — 13 Traefik Routes Bị Thiếu
Services có code nhưng không có Traefik route trong infra/traefik/dynamic/routes.yml:
chat-service(SignalR hub cũng thiếu)social-servicemining-servicemission-servicepromotion-serviceads-manager-serviceads-serving-serviceads-billing-serviceads-tracking-serviceads-analytics-servicemkt-facebook-servicemkt-whatsapp-servicemkt-zalo-service
Hiện tại các service này chỉ accessible trực tiếp qua port (bypassing Traefik security middleware).
W5 — Fire-and-Forget Task trong mkt-whatsapp WebhooksController
File: services/mkt-whatsapp-service-net/src/WhatsAppService.API/Controllers/WebhooksController.cs:88
_ = Task.Run(async () => await ProcessWebhookAsync(payload));
Đây là unobserved task — lỗi trong ProcessWebhookAsync sẽ bị nuốt im lặng. Dùng hosted service hoặc background job queue thay thế.
W6 — Docker Images Dùng :latest Tag
File: deployments/local/docker-compose.yml
Tất cả service images đang dùng goodgo/*:latest. Vi phạm 12-factor app (reproducibility). Production K8s manifest nên dùng immutable commit SHA tags.
W7 — Promotion & Mission Services Chưa Đủ Handlers
Mặc dù Wave 2 đã add handlers theo ROADMAP:
promotion-service: vẫn thiếuExchangeVoucherCommand,PurchaseVoucherCommandhandlers theo CTO_FIX_TRACKERinventory-service: chỉ cóDeductInventoryCommand— thiếuAddStock,AdjustInventory,GetInventoryReportmission-service:GetUserMissionProgressQuerytheo tracker chưa rõ trạng thái
ROADMAP Phase 3 Week 9-10 đặt priority P0 cho các items này — cần xác nhận lại trạng thái thực tế.
W8 — Test Credentials Hardcoded trong ROADMAP.md
File: ROADMAP.md Section IX
hongochai10@icloud.com | Velik@2026 | Admin/Owner
tranvanb@goodgo.vn | Staff@2026 | Staff/Cashier
ROADMAP.md là file check vào git. Credentials không nên ở đây ngay cả cho dev/staging. Dùng .env.example hoặc secret manager.
Improvements
I1 — Implement IEventBus / RabbitMQ Integration
Hiện tại RabbitMQ được provisioned trong docker-compose nhưng không có service nào dùng. Đây là cơ hội lớn để decouple cross-service communication:
- Tạo shared
IEventBusinterface trongpackages/(hoặc NuGet package) - RabbitMQ implementation với idempotency (outbox pattern)
- Start với
OrderItemServedDomainEvent→ inventory deduction thay vì HTTP call
I2 — API Gateway Security Hardening
Traefik middlewares.yml đang ổn nhưng thiếu:
- SSL redirect bị disable (
sslRedirect: false) — phải enable trên staging/production - Missing routes cho 13 services bypass security middleware hoàn toàn
api-ratelimit(100/min) chưa được apply cho các services chưa có route
I3 — CI Pipeline Expansion
Chỉ có ci-iam-service.yml. Cần thêm ít nhất:
ci-merchant-service.yml(critical — có seed endpoints nhạy cảm)ci-order-service.yml(critical — order flow)ci-fnb-engine.yml(có 96 tests, nên chạy trong CI)ci-wallet-service.yml(payment critical path)
I4 — Seed Endpoint Removal / Environment Guard
Ngoài security fix cho C1, recommend tách seed logic ra:
- Script riêng trong
scripts/db/seed.sh - Database seeder class chỉ chạy khi
env.IsDevelopment() && args.Contains("--seed") - Không bao giờ expose seed logic qua HTTP endpoint
I5 — Reflection-Based Field Setter Anti-Pattern
File: StaffController.cs:352
var field = typeof(MerchantStaff).GetField("_userId", BindingFlags.NonPublic | BindingFlags.Instance);
field?.SetValue(staff, userId);
Đây là violation của DDD encapsulation. Cần thêm domain method staff.AssignUserId(Guid userId) trong aggregate root.
Action Items (Prioritized)
| Priority | Item | Owner | Effort |
|---|---|---|---|
| P0 | [C1] Xóa / guard debug endpoints (StaffController.cs:249-390) |
Backend Dev | 30 min |
| P0 | [C2] Fix SQL injection — parameterized queries (StaffController.cs:307,367) |
Backend Dev | 30 min |
| P0 | [C3] Fix BFF CORS — thay AllowAnyOrigin() bằng whitelist |
Backend Dev | 15 min |
| P0 | [C4] Fix port conflict + add mkt-* services to Docker Compose (ports 5021-5024) | DevOps | 2h |
| P1 | [W3] Tạo booking-service K8s staging manifest | DevOps | 1h |
| P1 | [W4] Add 13 Traefik routes (chat, social, mining, ads-, mkt-, promotion, mission) | DevOps | 2h |
| P1 | [W7] Fix promotion/mission/inventory service handlers | Backend Dev | 1-2 days |
| P1 | [C5] Implement IEventBus skeleton + first integration event | Backend Dev | 3-5 days |
| P2 | [W1] Fix TenantMiddleware SQL string interpolation (5 services) | Backend Dev | 1h |
| P2 | [W5] Fix fire-and-forget in mkt-whatsapp | Backend Dev | 30 min |
| P2 | [W6] Thay :latest bằng commit SHA trong CI/CD |
DevOps | 1h |
| P2 | [W8] Xóa credentials khỏi ROADMAP.md | CTO | 5 min |
| P2 | [I3] Thêm CI pipelines cho merchant, order, fnb, wallet | DevOps | 2h |
| P3 | [I4] Tách seed logic ra scripts | Backend Dev | 2h |
| P3 | [I5] Add AssignUserId() domain method thay reflection |
Backend Dev | 30 min |
| P3 | Enable SSL redirect trong Traefik (staging/prod) | DevOps | 15 min |
Architectural Assessment
What's Working Well
- Clean Architecture + CQRS được tuân thủ nhất quán trong 15 production-ready services
- MediatR pipeline (Logging → Validation → Transaction → Handler) hoạt động đúng
- Multi-tenancy via EF Core global filters + PostgreSQL RLS — defense-in-depth tốt
- IAM service với Duende IdentityServer là foundation vững chắc
- BFF pattern với YARP là đúng hướng — tránh expose microservices trực tiếp
- FnB Engine là service chất lượng cao nhất (96 tests, full DDD, SignalR hub)
- Observability stack (Prometheus + Grafana + Loki) đã sẵn sàng
What Needs Attention
- Event-driven messaging chưa triển khai — RabbitMQ hiện là dead weight
- Auth boundary giữa BFF và microservices cần review: BFF dùng
AuthForwardingHandlerđể forward JWT, nhưng BFF CORS wildcard tạo ra điểm yếu - Service decomposition cho ads services (5 services) có vẻ over-engineered cho MVP — ads-serving, ads-billing, ads-analytics, ads-tracking có minimal business logic và không đủ handlers
Report generated by CTO Agent | Run ID: 3d2b7974 | Commit: d0211e5