📘 User Service Master – Service Design Document¶
1. Mục đích (Scope)¶
User Service Master chịu trách nhiệm quản lý định danh người dùng toàn cục (users_global), danh sách tenant (tenants) và việc gán người dùng vào tenant cụ thể (user_tenant_assignments). Ngoài ra, service này cũng cung cấp các template RBAC toàn cục (global_roles_templates, global_permissions_templates) để các Sub User Service có thể đồng bộ và khởi tạo RBAC cục bộ cho từng tenant.
Service này là nền tảng cốt lõi cho toàn bộ hệ thống phân quyền đa tenant, đảm bảo tính nhất quán trong quản lý người dùng và hỗ trợ các luồng xác thực từ Auth Master/Sub.
🚫 Không chịu trách nhiệm (Out of Scope)¶
User Service Master không chịu trách nhiệm đối với các chức năng sau:
- ❌ Quản lý RBAC chi tiết ở cấp tenant (bao gồm roles, permissions, và user-role mapping cục bộ) – đây là trách nhiệm của Sub User Service tương ứng.
- ❌ Thực hiện xác thực người dùng (Google OAuth2, OTP, Local login) – do Auth Service Master/Sub xử lý.
- ❌ Lưu trữ hoặc xử lý các dữ liệu nghiệp vụ chi tiết của từng tenant (ví dụ: học sinh, giáo viên, lớp học, học phí...) – các adapter CRM/SIS/LMS đảm nhiệm phần này.
- ❌ Cung cấp các giao diện frontend – ví dụ Superadmin Webapp chỉ gọi API từ Gateway, chứ không truy cập trực tiếp vào service này.
2. Trách nhiệm chính (Responsibilities)¶
- Quản lý bảng định danh người dùng toàn hệ thống (
users_global) - Cho phép tạo, cập nhật, tra cứu thông tin người dùng toàn cục
- Quản lý danh sách tenant đang hoạt động và trạng thái
- Gán quyền người dùng vào các tenant cụ thể (
user_tenant_assignments) - Cung cấp bộ template
rolesvàpermissionsdùng để seed xuống các tenant - Phát sự kiện
user_created,tenant_user_assigned,rbac_template_updatedphục vụ Sub Services
3. Luồng nghiệp vụ chính (Business Flows)¶
🔹 Đăng nhập Google OAuth2 (qua Auth Master)¶
- Auth Master xác thực thành công user Google → gọi
GET /users-global/by-email - Nếu chưa tồn tại → gọi
POST /users-globalđể tạo mới - Gọi
GET /user-tenant-assignments?user_id=...để lấy danh sách tenant người dùng thuộc về - Người dùng chọn tenant → chuyển qua luồng Auth tiếp theo
🔹 Gán người dùng vào tenant¶
- Admin hệ thống (qua Superadmin Webapp) có thể gán người dùng vào 1 hoặc nhiều tenant
- Gọi
POST /user-tenant-assignments - Phát sự kiện
tenant_user_assignedđể Sub User Service tạo bản ghi cục bộ
🔄 Luồng 1: Superadmin gán người dùng vào tenant¶
sequenceDiagram
participant FE as Superadmin Webapp
participant GW as API Gateway
participant USM as User Service Master
participant DB as PostgreSQL (users_global + user_tenant_assignments)
participant PUB as Google Pub/Sub
FE->>GW: POST /user-tenant-assignments
GW->>USM: POST /user-tenant-assignments
USM->>DB: Ghi user_id, tenant_id, role_codes vào bảng user_tenant_assignments
USM-->>PUB: Phát sự kiện tenant_user_assigned (chứa user_id, tenant_id, role_codes)
USM-->>GW: 200 OK (status: success)
GW-->>FE: Hiển thị kết quả gán thành công
📝 Giải thích chi tiết:
- Superadmin gửi yêu cầu gán người dùng (
user_id) vào mộttenant_id, kèm danh sáchrole_codes. - API Gateway định tuyến request tới User Service Master.
- User Service Master ghi thông tin vào bảng
user_tenant_assignments. - Sau khi ghi thành công, service phát một sự kiện
tenant_user_assignedlên Pub/Sub, giúp Sub User Service của tenant tương ứng có thể đồng bộ RBAC. - Kết quả trả về cho frontend xác nhận hành động đã thành công.
🔁 Trường hợp lỗi tiềm ẩn:
user_idkhông tồn tại trongusers_global→ 404.tenant_idkhông hợp lệ hoặc không tồn tại → 400.- Lỗi logic: người dùng đã được gán vào tenant đó → 409 Conflict.
🔐 Luồng 2: Đăng nhập Google OAuth2 – yêu cầu từ Auth Master¶
sequenceDiagram
participant FE as Frontend (Superadmin Webapp)
participant AuthM as Auth Service Master
participant UserM as User Service Master
FE->>AuthM: Đăng nhập Google (OAuth2)
AuthM->>Google: Trao đổi token
Google-->>AuthM: Trả về user info (email, name,...)
AuthM->>UserM: GET /users-global/by-email?email=...
alt Không tìm thấy
AuthM->>UserM: POST /users-global (tạo user)
end
AuthM->>UserM: GET /user-tenant-assignments?user_id=...
UserM-->>AuthM: Trả về danh sách tenant đã gán
AuthM-->>FE: Trả về danh sách tenant để chọn
➡️ Sau bước này, AuthM sẽ tiếp tục gọi Sub User Service tương ứng để lấy RBAC và phát hành JWT.
🧩 Luồng 3: Tạo/Cập nhật RBAC Template¶
sequenceDiagram
participant FE as Superadmin Webapp
participant Gateway as API Gateway
participant UserM as User Service Master
participant PubSub as GCP Pub/Sub
FE->>Gateway: POST /rbac/templates (role/permission)
Gateway->>UserM: POST /rbac/templates
UserM->>DB: Tạo hoặc cập nhật bảng templates
UserM->>PubSub: Publish event rbac_template_updated
PubSub-->>SubUser: Trigger đồng bộ template
➡️ Các Sub User Service có thể tự đồng bộ hoặc hiển thị gợi ý cập nhật template.
👤 Luồng 4: Sub Auth Service tạo user local mới và cấp user_id_global¶
sequenceDiagram
participant AuthT as Sub Auth Service
participant Gateway as API Gateway
participant UserM as User Service Master
AuthT->>Gateway: POST /users-global (tạo user local)
Gateway->>UserM: POST /users-global
UserM->>DB: Tạo user (auth_provider = 'local')
UserM-->>Gateway: Trả về user_id_global
Gateway-->>AuthT: Trả về user_id_global
➡️ AuthT sau đó sẽ gán user vào tenant của mình và phát hành JWT theo chuẩn đa tenant.
4. Mô hình dữ liệu¶
Các bảng chính do User Service Master quản lý bao gồm:
users_global: danh sách người dùng toàn cục, gắn với auth_provider.tenants: thông tin từng tenant (trường thành viên).user_tenant_assignments: liên kết người dùng với từng tenant cụ thể.global_roles_templates: danh sách template vai trò toàn cục.global_permissions_templates: danh sách template quyền toàn cục.
🧩 Sơ đồ ERD tổng quan¶
erDiagram
USERS_GLOBAL {
UUID user_id PK
TEXT full_name
TEXT email
TEXT auth_provider
}
TENANTS {
TEXT tenant_id PK
TEXT tenant_name
TEXT status
}
USER_TENANT_ASSIGNMENTS {
UUID id PK
UUID user_id_global FK
TEXT tenant_id FK
TEXT role_codes
BOOLEAN is_active
}
GLOBAL_ROLES_TEMPLATES {
UUID template_id PK
TEXT template_code
TEXT description
}
GLOBAL_PERMISSIONS_TEMPLATES {
UUID template_id PK
TEXT permission_code
TEXT action
TEXT resource
TEXT default_condition
}
USERS_GLOBAL ||--o{ USER_TENANT_ASSIGNMENTS : has
TENANTS ||--o{ USER_TENANT_ASSIGNMENTS : includes
GLOBAL_ROLES_TEMPLATES ||--o{ GLOBAL_PERMISSIONS_TEMPLATES : defines
📝 Ghi chú quan trọng cho sơ đồ ERD:
USER_TENANT_ASSIGNMENTS.role_codes: Là một mảng TEXT. Mermaid không hỗ trợ kiểuTEXT[], nên được ghi làTEXTcho đơn giản.GLOBAL_PERMISSIONS_TEMPLATES.default_condition: Là một trường JSONB dùng để định nghĩa điều kiện RBAC. Mermaid chỉ hỗ trợTEXT, nên cần hiểuTEXT default_conditionở đây là biểu diễn của JSONB.email,template_code,permission_code: Có ràng buộcUNIQUEtrong thiết kế thực tế – không thể hiện trong sơ đồ Mermaid nhưng được định nghĩa trong migration script hoặc tài liệudata-model.md.
👉 Xem chi tiết định nghĩa bảng tại: data-model.md
5. API¶
User Service Master cung cấp các API phục vụ cho:
- Superadmin Webapp: quản lý định danh người dùng và RBAC toàn cục.
- Auth Service Master/Sub: tra cứu, tạo người dùng toàn cục.
- Sub User Service: đồng bộ danh sách assignment, template RBAC.
Chi tiết định nghĩa tham khảo tại interface-contract.md và openapi.yaml.
📚 Bảng tóm tắt API chính¶
| Method | Path | Mô tả ngắn | Yêu cầu quyền |
|---|---|---|---|
| GET | /users-global/by-email |
Tra cứu người dùng toàn cục theo email | Authenticated (Google) |
| POST | /users-global |
Tạo người dùng toàn cục mới | Authenticated (Google, OTP) |
| GET | /tenants |
Liệt kê danh sách các tenant hiện có | Superadmin |
| GET | /user-tenant-assignments |
Tra cứu các tenant mà người dùng thuộc về | Auth Service / Admin Tenant |
| POST | /user-tenant-assignments |
Gán người dùng vào tenant cụ thể | Superadmin |
| GET | /global-roles-templates |
Tra cứu template vai trò toàn cục | Superadmin |
| POST | /global-roles-templates |
Tạo mới template vai trò toàn cục | Superadmin |
| GET | /global-permissions-templates |
Tra cứu template quyền toàn cục | Superadmin |
| POST | /global-permissions-templates |
Tạo mới template quyền toàn cục | Superadmin |
6. Sự kiện phát ra (Events)¶
User Service Master phát các sự kiện lên Google Cloud Pub/Sub để:
- Thông báo cho các Sub User Services về thay đổi RBAC.
- Cho phép các service khác đồng bộ định danh người dùng và cấu hình tenant.
📢 Danh sách sự kiện¶
1. tenant_user_assigned¶
Khi một người dùng được gán vào một tenant mới.
{
"event_id": "evt_7a3a8b40",
"event_type": "tenant_user_assigned",
"user_id_global": "usr_12345678",
"tenant_id": "vas-truong-a",
"role_codes": ["teacher", "homeroom"],
"assignment_status": "active",
"timestamp": "2025-06-01T08:30:00Z"
}
- Consumer: Sub User Service của tenant tương ứng
- Tác dụng: Tự động tạo
users_in_tenantvà mapping role cho user trong tenant đó - Yêu cầu idempotency: Sub Service phải kiểm tra
event_idhoặcuser_id + tenant_idđã xử lý hay chưa.
2. rbac_template_updated¶
Khi một template vai trò hoặc quyền toàn cục được cập nhật.
{
"event_id": "evt_5baf6c2d",
"event_type": "rbac_template_updated",
"template_type": "permission",
"template_id": "perm_tpl_001",
"action": "create_or_update",
"updated_by": "superadmin@vas.edu.vn",
"timestamp": "2025-06-01T09:00:00Z"
}
- Consumer: Sub User Services có nhu cầu đồng bộ template
- Tác dụng: Cho phép Sub Service quyết định có nên cập nhật local template không (hoặc gợi ý cho admin cập nhật thủ công)
- Gợi ý thực thi: Có thể lưu lại trong bảng
rbac_template_sync_logtại Sub Service để kiểm soát phiên bản.
7. 🔐 Bảo mật & Phân quyền¶
user-service/master xử lý thông tin định danh toàn cục (Global User Identity), do đó yêu cầu chính sách bảo mật và kiểm soát phân quyền chặt chẽ theo kiến trúc RBAC phân tầng (xem chi tiết tại rbac-deep-dive.md).
🛡️ 7.1. Authentication (Xác thực)¶
- Tất cả các endpoint đều yêu cầu JWT access token hợp lệ, do
auth-service/mastercấp phát. - Token được xác thực tại API Gateway, sử dụng public key từ
JWKSendpoint. - Service không decode token mà dựa vào gateway để inject
X-User-ID,X-User-Role,X-Tenant-ID.
🧩 7.2. Authorization (Phân quyền động)¶
- Hệ thống áp dụng RBAC 3 tầng:
global,tenant, vàscoped-role. - Mỗi endpoint định nghĩa
x-required-permission, ví dụ:
- Các permission được mapping theo bảng sau:
| Permission | Mô tả |
|---|---|
user.read:any |
Truy cập thông tin bất kỳ user nào |
user.read:self |
Truy cập chỉ thông tin của chính mình |
user.create |
Tạo user mới toàn cục |
user.update:any |
Sửa thông tin user bất kỳ |
user.update:self |
Sửa thông tin của chính mình |
🔐 7.3. Bảo vệ dữ liệu nhạy cảm¶
-
Trường
password,token,email_verified_atđều được bảo vệ: -
passwordchỉ ghi, không bao giờ trả về (gắnwriteOnly: true) - Email được xác minh ở
auth/master, không lưu lại tronguser/master -
Các trường có thể bị giới hạn truy cập tuỳ theo vai trò:
-
internal_noteschỉ hiện vớiadmin, không hiện vớiself
🔁 7.4. Audit Logging¶
-
Mọi thao tác ghi (
POST,PATCH,DELETE) đều emit sự kiện audit: -
user.created,user.updated,user.merged - Log audit được gửi qua Pub/Sub →
audit-logging-service, tuân thủ ADR-008
🔒 7.5. Internal Auth¶
- Các call nội bộ (ví dụ: từ
auth-service/master) sử dụngSERVICE_AUTH_TOKENvà được kiểm tra tại gateway. - Những API không dành cho public (seed role, fetch global profile) có gắn:
🚫 7.6. Rate Limiting & Abuse Prevention¶
- Gateway cấu hình limit mặc định:
100 req/min/user - Các endpoint nhạy cảm (tìm theo email, tạo user) có thể gắn limit riêng.
8. ⚙️ Cấu hình & Triển khai¶
🔧 Biến môi trường¶
Service sử dụng cấu hình từ file .env (hoặc settings/.env.<env>.template) theo chuẩn hóa từ ADR-005: Env Config. Một số biến chính:
| Tên biến | Mô tả | Ví dụ |
|---|---|---|
ENVIRONMENT |
Môi trường chạy (local, staging, production) |
staging |
SERVICE_PORT |
Cổng chạy service | 8000 |
DATABASE_URL |
Kết nối PostgreSQL | postgresql://user:pass@host/db |
REDIS_URL |
Kết nối Redis (cache session/token) | redis://localhost:6379/0 |
SERVICE_AUTH_TOKEN |
Token dùng để gọi nội bộ giữa các service (Auth Master → User Master) | secret-key |
JWT_PUBLIC_KEY |
Public key để validate access token (dạng PEM) | – |
GOOGLE_CLOUD_PROJECT |
Project ID dùng cho Pub/Sub (nếu bật audit) | dxvas-dev |
LOG_LEVEL |
Mức log (DEBUG, INFO, ...) |
INFO |
👉 Toàn bộ các biến được liệt kê và version hóa tại: settings/.env.template.
🛠 Cấu trúc thư mục cấu hình¶
settings/
├── .env.template # Biến môi trường chuẩn (dùng cho mọi môi trường)
├── env.staging.yaml # Override cho môi trường staging
├── env.production.yaml # Override cho môi trường production
└── secrets.yaml # Chỉ chứa key nhạy cảm, inject từ Vault/SecretManager
- Toàn bộ file
yamlđều được load tự động bởi module config chuẩn trongdx-core. - Secrets như
JWT_PRIVATE_KEYKHÔNG được ghi trực tiếp vào.env, mà được mount vào volume hoặc lấy từ SecretManager (theo ADR-003: Secrets).
🚀 CI/CD & Triển khai¶
Tuân thủ ADR-001: CI/CD Pipeline:
| Thành phần | Công cụ | Ghi chú |
|---|---|---|
| Build & test | GitHub Actions | test.yaml, lint.yaml trong .github/workflows/ |
| Build image | Docker, Poetry | Image tối ưu từ python:slim, không include dev deps |
| Scan bảo mật | trivy, semgrep |
Tích hợp vào CI |
| Deploy | ArgoCD | Tự động rollout nếu merge vào main |
| Observability | OpenTelemetry, Grafana, Sentry | Default gắn theo dx-core |
| Migration | Alembic, trigger qua Argo Job | Tách step migrate và deploy rõ ràng |
📌 Để chạy service cục bộ:
9. 🧪 Chiến lược Test¶
Việc kiểm thử user-service/master được tổ chức theo chiến lược kiểm thử đa tầng, đảm bảo chất lượng từ mức độ logic nội bộ đến tích hợp liên service, đồng thời có thể chạy hiệu quả trong CI/CD pipeline.
✅ 9.1. Unit Test¶
-
Phạm vi:
-
Xử lý logic nghiệp vụ: tạo user, validate dữ liệu, phân quyền động
- Format hóa response và mã lỗi theo ADR-012
- Công cụ:
pytest + pytest-mock - Mỗi PR mới đều bắt buộc chạy qua test suite này trong GitHub Actions (
test.yaml) - Yêu cầu coverage ≥ 85%
✅ 9.2. Contract Test (Consumer-Driven)¶
Tuân thủ ADR-010: Contract Testing
- Kiểm thử tương thích giữa
user-service/mastervà các consumer (ví dụ:auth/master,api-gateway) - Dùng
pact-python, publish pact file lênpact-broker - CI sẽ fail nếu producer làm gãy contract
-
Bắt buộc có contract test cho các API:
-
GET /users-global/{id} POST /users-globalGET /users-global/by-email
✅ 9.3. Integration Test (Service level)¶
- Spin-up toàn bộ stack (PostgreSQL, Redis, user-service) trong Docker Compose
- Chạy các test query + mutation logic đầy đủ (bao gồm validate RBAC, phân quyền)
- Dùng
httpxhoặcpytest-httpxđể test end-to-end response format - Đảm bảo emit đúng các sự kiện (
user.created,user.duplicated,user.updated) qua Pub/Sub mock
✅ 9.4. Load & Performance Test (Tùy chọn)¶
- Dùng
locusthoặck6để test throughput của các API truy xuất hàng loạt (pagination, filter) - Ước lượng ngưỡng tối ưu: 1000 req/s với latency P95 < 200ms
- Giúp tune indexing, limit-offset, caching Redis user_id → full profile
✅ 9.5. Security Test¶
pytestvới các case đặc biệt: không có token, token sai scope, sai tenant- Kết hợp
semgrepđể phát hiện hardcoded secrets, lỗi injection - Test
user.read:selfvsuser.read:anyđể xác minh phân quyền động
🧪 Báo cáo & Tích hợp CI¶
- Test chạy qua
make test,make test-contract,make test-int - Kết quả publish lên
coverage.xml,junit.xml, tích hợp GitHub Checks - Pact Broker:
https://pact.dxvas.vn - Allure Report: Tùy chọn publish khi chạy full test suite
🧠 Mọi kịch bản test cần bao gồm trường hợp thành công, lỗi logic, và lỗi hệ thống (timeout, lỗi DB, lỗi Pub/Sub...).
10. 📈 Quan sát & Giám sát¶
Hệ thống quan sát (observability) của user-service/master giúp đảm bảo khả năng phát hiện lỗi sớm, đo lường sức khỏe hệ thống và hỗ trợ phân tích hành vi người dùng phục vụ vận hành đa tenant hiệu quả.
📊 10.1. Logging¶
- Chuẩn log JSON theo
dx-core, định dạng:{ timestamp, level, service, trace_id, span_id, user_id, tenant_id, msg, extra... } - Tích hợp OpenTelemetry để đính kèm
trace_id,span_idtheo chuẩn OTEL. -
Log được gửi về:
-
Dev:
stdout→ Loki/Grafana - Prod: GCP Logging hoặc OpenObserve
| Level | Mục đích |
|---|---|
INFO |
Thao tác thông thường |
WARN |
Thao tác sai, không làm crash |
ERROR |
Exception, database lỗi, sự cố nghiêm trọng |
DEBUG |
Gỡ lỗi (chỉ bật khi local/dev) |
📈 10.2. Metrics¶
- Sử dụng
Prometheusexporter thông quadx-core.metrics. - Một số metrics quan trọng:
| Metric | Loại | Nhãn | Ghi chú |
|---|---|---|---|
http_requests_total |
Counter | path, method, status | Tổng số request |
http_request_duration_seconds |
Histogram | path, method | Độ trễ |
user_create_success_total |
Counter | tenant_id | Tạo user thành công |
user_lookup_by_email_miss_total |
Counter | – | Không tìm thấy user theo email |
db_query_duration_seconds |
Histogram | model, operation | Theo dõi hiệu năng DB |
🔐 10.3. Audit Logging¶
Tuân thủ ADR-008:
-
Emit các sự kiện audit dạng Pub/Sub:
-
user.created user.updateduser.duplicated- Mỗi event bao gồm:
actor_id,target_user_id,tenant_id,action,changes -
Được forward sang
audit-logging-serviceđể lưu DB riêng (GCP BigQuery hoặc PostgreSQL phân vùng) -
Tất cả các thao tác thay đổi dữ liệu liên quan đến người dùng và tenant đều được ghi lại thông qua Audit Logging Service, bao gồm:
user.created,user.updated,user.deleteduser_tenant_assignment.createdtenant.created,tenant.status_changedrole_template.updated,permission_template.updated
-
Log bao gồm:
actor_id,tenant_id,action,target_table,before,after,timestamp- Request
X-Request-IDđể truy vết qua toàn hệ thống
💰 10.4. Cost Observability (Billing)¶
Áp dụng ADR-020:
- Tự động emit sự kiện
usage.user.queryvàusage.user.create - Hỗ trợ billing theo số lần truy cập dữ liệu
global usercủa mỗi tenant - Các service khác (như SIS, CRM) có thể tích hợp các sự kiện này để ước lượng chi phí
🧪 10.5. Health Check & Alert¶
- Endpoint:
GET /healthz(có thể bổ sung/readyz) -
Tích hợp:
-
Argo Rollout → kiểm tra trước khi scale
- GCP Cloud Monitoring → alert theo latency và error rate
11. 🚀 Độ tin cậy & Phục hồi¶
user-service/master đóng vai trò then chốt trong hệ thống định danh toàn cục, do đó được thiết kế với mục tiêu khả dụng cao (HA), đảm bảo không mất dữ liệu và không gián đoạn khi cập nhật.
🧱 11.1. Triển khai không gián đoạn (Zero Downtime)¶
Tuân thủ ADR-014: Zero Downtime:
- Sử dụng chiến lược rollout
blue-greenhoặccanaryqua Argo Rollouts. - Endpoint
GET /healthz+ probe readiness kiểm tra DB + Redis + Pub/Sub. - Thực hiện shadow traffic test trước khi 100% chuyển route.
⚙️ 11.2. Chính sách triển khai¶
Theo ADR-015: Deployment Strategy và ADR-018: Release Approval:
-
Mọi release đều yêu cầu:
-
Pass CI (
unit,contract,integration) - Được duyệt bởi reviewer kỹ thuật
- Gắn tag version (
v2.x.x) - Tự động deploy nếu PR merge vào
mainvà có tag.
♻️ 11.3. Auto Scaling¶
Tuân thủ ADR-016: Auto Scaling:
-
Sử dụng HPA (Horizontal Pod Autoscaler) theo:
-
CPU: ≥ 70%
- Request QPS: ≥ 500 req/s
- Giới hạn min 2 replica, max 10 (có thể override theo tenant load)
💾 11.4. Dự phòng dữ liệu & recovery¶
- Toàn bộ dữ liệu lưu tại PostgreSQL phân vùng theo tenant_id.
- Backup qua Cloud SQL export định kỳ (6 giờ/lần).
- Mỗi thay đổi người dùng đều phát
user.updated→ có thể sync vào hệ thống phụ như CRM/LMS/SIS để đảm bảo redundancy.
⚡ 11.5. Retry & Timeouts¶
- Giao tiếp nội bộ giữa services có timeout 3s + retry 2 lần (exponential backoff).
-
Nếu
user.masterkhông phản hồi: -
Gateway trả lỗi
503với mãuser.service_unavailable - Ghi log + emit alert
🔄 11.6. Rollback & Observability¶
- Nếu rollout lỗi (readiness probe fail > 20s), tự động rollback về version trước.
- Tích hợp OpenTelemetry để debug lỗi multi-hop: từ gateway → auth → user.
12. ⚡️ Hiệu năng & Khả năng mở rộng¶
user-service/master được thiết kế để phục vụ truy vấn user toàn cục đa tenant, với khả năng scale linh hoạt và đáp ứng hàng triệu bản ghi. Mọi thành phần từ lưu trữ, cache đến API đều được tối ưu để đảm bảo throughput cao, latency thấp và hỗ trợ mở rộng theo chiều ngang.
⚡ 12.1. Truy vấn tối ưu & indexing¶
-
Các API thường xuyên sử dụng như:
-
GET /users-global/by-email GET /users-global/by-phoneGET /users-global/{id}đều được tối ưu thông qua index phức hợp (email, tenant_id,phone_number, tenant_id).- Cơ chế filter sử dụng
tenant_idnhư điều kiện bắt buộc để đảm bảo query nhanh và cách ly dữ liệu.
🧠 12.2. Caching thông minh¶
- Redis layer để cache các bản ghi người dùng phổ biến (dựa vào LRU hoặc Top-K queries).
- TTL mặc định: 15 phút. Có cơ chế invalidate khi có
user.updated. -
Dữ liệu cache:
-
user_id → profile email/phone → user_id- Cơ chế warming cache khi khởi động để tăng cold-start performance.
🚀 12.3. Hỗ trợ phân trang lớn (deep pagination)¶
- Dùng cơ chế seek-based pagination (trang theo
created_athoặcuser_id) để tránh hiệu năng kém khi offset lớn. - Default limit: 20. Max limit: 1000.
- Có hỗ trợ cả offset pagination cho use-case quản trị viên.
⚙️ 12.4. Horizontal Scaling¶
- Service stateless → có thể scale theo replica (tuân thủ ADR-016)
-
Redis + PostgreSQL có thể tách cụm theo workload:
-
Redis: scale theo số lượng hot user
- Postgres: có thể sharding theo
tenant_idnếu vượt quá ngưỡng
📉 12.5. Theo dõi hiệu năng¶
-
Metrics Prometheus:
-
http_request_duration_seconds user.lookup_latency_p95db_user_query_duration_seconds-
Cảnh báo nếu:
-
P95 > 200mstrong 5 phút cache_miss_rate > 30%trong 10 phút
🧪 12.6. Benchmark & Load test¶
-
Dùng
k6để test với 1 triệu user, 1000 req/s trong 10 phút: -
P95 < 150ms,success_rate > 99.9% -
Test profile:
-
90%
GET - 8%
POST - 2%
PATCH
13. 🧩 Kiến trúc Service¶
user-service/master là một thành phần core multi-tenant, chịu trách nhiệm quản lý danh tính toàn cục cho người dùng trên toàn hệ thống VAS, bao gồm: ID định danh, tài khoản gốc, và thông tin liên kết giữa người dùng với các tenant. Service này hoạt động độc lập với các sub-service tenant-specific, và là nguồn dữ liệu gốc phục vụ auth-service/master, token-service và hệ thống SMS mới tích hợp.
🧭 13.1. Sơ đồ kiến trúc cập nhật (tuân CR-04)¶
flowchart TD
subgraph Core Services
GATEWAY[API Gateway]
AUTH_MASTER[Auth Service - Master]
USER_MASTER[User Service - Master]
TOKEN[Token Service]
AUDIT[Audit Logging Service]
end
subgraph Data Layer
PG_GLOBAL[(PostgreSQL - Global)]
REDIS[(Redis)]
end
subgraph Tenant System
SMS[(School Management System)]
end
GATEWAY -->|JWT + RBAC + X-Tenant-ID| AUTH_MASTER
GATEWAY -->|RBAC + Route| USER_MASTER
AUTH_MASTER -->|Lookup user| USER_MASTER
USER_MASTER -->|Read/write| PG_GLOBAL
USER_MASTER -->|Cache email/user_id| REDIS
USER_MASTER -->|Emit user.created/updated| PUBSUB[(Pub/Sub)]
USER_MASTER --> AUDIT
PUBSUB --> SMS
🧩 13.2. Thành phần chính¶
| Thành phần | Vai trò |
|---|---|
FastAPI |
Framework triển khai HTTP API |
PostgreSQL (global) |
Lưu trữ chính thông tin người dùng toàn cục |
Redis |
Tăng tốc truy xuất email → user_id, user_id → profile |
Pub/Sub |
Phát sự kiện cho các hệ thống downstream như SMS |
Audit Logging |
Ghi nhận thay đổi user phục vụ kiểm tra và compliance |
⚙️ 13.3. Cấu trúc thư mục¶
user-service/
├── main.py # Entry point chính
├── api/ # Router FastAPI
│ ├── global_users.py # Định nghĩa endpoint /users-global/*
├── models/ # ORM models
├── schemas/ # Request/response schemas
├── services/ # Business logic: user creation, update, conflict detection
├── events/ # Emit Pub/Sub events
├── core/ # Cấu hình, middleware, utils
└── tests/ # Kiểm thử unit & integration
🔄 13.4. Giao tiếp & tích hợp¶
| Dịch vụ | Mục đích |
|---|---|
auth-service/master |
Xác thực người dùng, gọi GET /users-global/by-email |
token-service |
Cung cấp JWT token với user_id toàn cục |
API Gateway |
Áp dụng RBAC & inject các header (X-User-ID, X-Permissions, X-Tenant-ID) |
SMS (Tenant) |
Tiêu thụ sự kiện user.created, user.updated để sync user profile |
audit-logging-service |
Nhận log từ mọi hành động cập nhật, tạo user |
📣 13.5. Các sự kiện phát ra¶
Tuân chuẩn định danh sự kiện từ [ADR-030: Event Schema Governance]:
| Sự kiện | Khi nào phát | Payload |
|---|---|---|
user.created |
Khi tạo user mới toàn cục | { user_id, email, created_by, timestamp } |
user.updated |
Khi cập nhật thông tin người dùng | { user_id, fields_changed, updated_by } |
user.duplicated |
Khi phát hiện trùng thông tin định danh | { conflict_user_ids, resolution_strategy } |
14. Tài liệu liên quan¶
| Tên tài liệu | Mô tả ngắn gọn |
|---|---|
| rbac-deep-dive.md | Mô tả chi tiết kiến trúc RBAC, các bảng liên quan và sơ đồ quyền |
| adr-007-rbac.md | Quyết định thiết kế kiến trúc RBAC phân tầng theo mô hình Master-Sub |
| adr-006-auth-strategy.md | Mô tả chiến lược xác thực, JWT và vai trò của User Service Master/Sub |
| Data Model | Chi tiết các bảng CSDL được quản lý bởi User Service Master |
| Interface Contract | Hợp đồng API định nghĩa rõ input/output, auth, mã lỗi của các endpoint |
| OpenAPI | File đặc tả OpenAPI kỹ thuật dùng để tạo SDK/Client/Docs tự động |
| system-diagrams.md | Sơ đồ kiến trúc tổng thể hệ thống, các service và dòng tương tác |
| README.md | Tài liệu kiến trúc tổng quan, mục tiêu tổng thể và các nguyên lý thiết kế |