📘 User Service Sub – Interface Contract¶
1. 🎯 Tổng quan¶
Mục đích¶
Cung cấp đặc tả chi tiết cho các API được exposed bởi user-service/sub, phục vụ frontend và các client thuộc tenant. Các API này chủ yếu mang tính read-only, sử dụng dữ liệu đồng bộ từ user-service/master.
Đối tượng sử dụng¶
- Frontend Webapp nội bộ cho tenant
- Gateway Service (thực thi RBAC)
Nguyên tắc chung¶
- Sub không xử lý xác thực/ủy quyền trực tiếp, chỉ nhận JWT header từ Gateway
- Các API luôn trả về theo chuẩn ADR-012 Response Structure
- Các lỗi sử dụng theo ADR-011 Error Format
2. 📜 API Summary Table¶
| Method | Path | Mô tả | RBAC Permission |
|---|---|---|---|
| GET | /users |
Danh sách user trong tenant | tenant.read_users |
| GET | /users/me |
Thông tin người dùng hiện tại | – |
| GET | /users/me/permissions |
Danh sách quyền của user | – |
| GET | /roles |
Role templates đã đồng bộ | tenant.view_rbac_config |
| GET | /permissions |
Permission templates đã đồng bộ | tenant.view_rbac_config |
3. 🔍 Chi tiết từng API¶
GET /users¶
Trả về danh sách người dùng trong tenant hiện tại.
- RBAC Required:
tenant.read_users - Query Params:
page: integer (default: 1)limit: integer (default: 20)search: optional, tìm theo tên hoặc email-
Response:
-
Status Codes:
-
200 OK: Thành công 401 Unauthorized: Thiếu JWT hoặc không hợp lệ403 Forbidden: Không đủ quyền truy cập500 Internal Server Error: Lỗi hệ thống
GET /users/me¶
Trả về thông tin user hiện tại (theo JWT).
- RBAC: không yêu cầu
- Headers:
Authorization: Bearer <JWT> - Response: như
UserLocal -
Status Codes:
-
200 OK 401 Unauthorized500 Internal Server Error
GET /users/me/permissions¶
Trả về danh sách quyền người dùng hiện tại đã được expand.
- RBAC: không yêu cầu
- Response:
{
"data": [
"student.view",
"attendance.mark"
],
"meta": {
"request_id": "req-xyz",
"timestamp": "2025-06-01T11:00:00Z"
}
}
-
Status Codes:
-
200 OK 401 Unauthorized500 Internal Server Error
GET /roles¶
Trả về danh sách role template đã được đồng bộ.
- RBAC Required:
tenant.view_rbac_config - Response:
{
"data": [
{
"role_code": "teacher",
"name": "Giáo viên",
"description": "Vai trò cho giáo viên"
}
],
"meta": { ... }
}
-
Status Codes:
-
200 OK 401 Unauthorized403 Forbidden500 Internal Server Error
GET /permissions¶
Trả về danh sách permission template đã được đồng bộ.
- RBAC Required:
tenant.view_rbac_config - Response:
{
"data": [
{
"code": "student.view",
"resource": "student",
"action": "view",
"description": "Xem hồ sơ học sinh"
}
],
"meta": { ... }
}
-
Status Codes:
-
200 OK 401 Unauthorized403 Forbidden500 Internal Server Error
4. 📑 Phụ lục: Error Codes, ENUM và Permission Code¶
📚 Chuẩn hóa mã lỗi (Error Codes)¶
Tất cả các mã lỗi (error.code) trong response phải tuân thủ theo chuẩn định danh namespace được mô tả tại:
Yêu cầu bắt buộc:
-
Mã lỗi phải viết theo dạng snake_case, có namespace phân tách rõ ràng, ví dụ:
-
user_sub.user_not_found auth.invalid_tokencommon.validation_failed-
Mỗi response lỗi (401, 403, 404, 422...) phải trả về đối tượng
ErrorEnvelope, gồm 2 phần: -
error– chứacode,message,details meta– chứatrace_id,timestamp
Gợi ý thực hành:
- Không dùng các mã lỗi chung chung như
"BAD_REQUEST","NOT_FOUND","FORBIDDEN" - Luôn khai báo ví dụ cụ thể (ví dụ trong
components/examples/hoặc inline OpenAPI) để giúp dev hiểu nhanh - Tái sử dụng error namespace có sẵn từ
error-codes.mdhoặc khai báo namespace mới nếu cần
✅ ENUM: status (UserLocal)¶
activeinvitedsuspendeddeleted
✅ ENUM: auth_provider¶
localgoogleotp
✅ Permission Codes sử dụng¶
tenant.read_userstenant.view_rbac_config