{"openapi":"3.1.0","info":{"title":"CHC User API","description":"User Portal API — multi-tenant scoped.\n\n**Tenant resolve protocol cho FE:** gắn header `X-T-Slug: <tenant-slug>` vào MỌI request khi FE deploy khác origin với BE (vd FE `app.chc-service.shop` call BE `api.chc-service.shop`). Fallback subdomain `Host` header khi cùng wildcard DNS. Pre-auth (login/forgot) BUỘC phải có 1 trong 2 — nếu không sẽ 404 `tenant_not_found`. Post-auth tiếp tục gắn header để tenant-scoped DB session work.","version":"0.1.0"},"paths":{"/api/user/_ping":{"get":{"tags":["user"],"summary":"User namespace ping","operationId":"user_ping_api_user__ping_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response User Ping Api User  Ping Get"}}}}},"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/auth/login":{"post":{"tags":["auth"],"summary":"User Login","operationId":"user_login_api_user_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"400":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"401":{"description":"Error response — codes: invalid_credentials, missing_bearer, token_revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}},"examples":{"invalid_credentials":{"summary":"invalid_credentials","value":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}}},"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found, lookup_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}},"examples":{"tenant_not_found":{"summary":"tenant_not_found","value":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}},"lookup_not_found":{"summary":"lookup_not_found","value":{"error":{"code":"lookup_not_found","message":"Không tìm thấy bản ghi"}}}}}}},"409":{"description":"Error response — codes: account_locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"account_locked","message":"Tài khoản đã bị khoá tạm thời do đăng nhập sai nhiều lần"}}}}},"410":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"422":{"description":"Error response — codes: onboarding_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/auth/logout":{"post":{"tags":["auth"],"summary":"User Logout","operationId":"user_logout_api_user_auth_logout_post","responses":{"204":{"description":"Successful Response"},"400":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"401":{"description":"Error response — codes: invalid_credentials, missing_bearer, token_revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}},"examples":{"invalid_credentials":{"summary":"invalid_credentials","value":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}}},"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found, lookup_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}},"examples":{"tenant_not_found":{"summary":"tenant_not_found","value":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}},"lookup_not_found":{"summary":"lookup_not_found","value":{"error":{"code":"lookup_not_found","message":"Không tìm thấy bản ghi"}}}}}}},"409":{"description":"Error response — codes: account_locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"account_locked","message":"Tài khoản đã bị khoá tạm thời do đăng nhập sai nhiều lần"}}}}},"410":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"422":{"description":"Error response — codes: onboarding_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/auth/refresh":{"post":{"tags":["auth"],"summary":"User Refresh","operationId":"user_refresh_api_user_auth_refresh_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshResponse"}}}},"400":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"401":{"description":"Error response — codes: invalid_credentials, missing_bearer, token_revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}},"examples":{"invalid_credentials":{"summary":"invalid_credentials","value":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}}},"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found, lookup_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}},"examples":{"tenant_not_found":{"summary":"tenant_not_found","value":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}},"lookup_not_found":{"summary":"lookup_not_found","value":{"error":{"code":"lookup_not_found","message":"Không tìm thấy bản ghi"}}}}}}},"409":{"description":"Error response — codes: account_locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"account_locked","message":"Tài khoản đã bị khoá tạm thời do đăng nhập sai nhiều lần"}}}}},"410":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"422":{"description":"Error response — codes: onboarding_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/auth/forgot":{"post":{"tags":["auth"],"summary":"User Forgot","operationId":"user_forgot_api_user_auth_forgot_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotRequest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericAccepted"}}}},"400":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"401":{"description":"Error response — codes: invalid_credentials, missing_bearer, token_revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}},"examples":{"invalid_credentials":{"summary":"invalid_credentials","value":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}}},"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found, lookup_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}},"examples":{"tenant_not_found":{"summary":"tenant_not_found","value":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}},"lookup_not_found":{"summary":"lookup_not_found","value":{"error":{"code":"lookup_not_found","message":"Không tìm thấy bản ghi"}}}}}}},"409":{"description":"Error response — codes: account_locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"account_locked","message":"Tài khoản đã bị khoá tạm thời do đăng nhập sai nhiều lần"}}}}},"410":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"422":{"description":"Error response — codes: onboarding_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/auth/reset":{"post":{"tags":["auth"],"summary":"User Reset","operationId":"user_reset_api_user_auth_reset_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"400":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"401":{"description":"Error response — codes: invalid_credentials, missing_bearer, token_revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}},"examples":{"invalid_credentials":{"summary":"invalid_credentials","value":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}}},"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found, lookup_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}},"examples":{"tenant_not_found":{"summary":"tenant_not_found","value":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}},"lookup_not_found":{"summary":"lookup_not_found","value":{"error":{"code":"lookup_not_found","message":"Không tìm thấy bản ghi"}}}}}}},"409":{"description":"Error response — codes: account_locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"account_locked","message":"Tài khoản đã bị khoá tạm thời do đăng nhập sai nhiều lần"}}}}},"410":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"422":{"description":"Error response — codes: onboarding_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/auth/change-password":{"post":{"tags":["auth"],"summary":"User Change Password","operationId":"user_change_password_api_user_auth_change_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"400":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"401":{"description":"Error response — codes: invalid_credentials, missing_bearer, token_revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}},"examples":{"invalid_credentials":{"summary":"invalid_credentials","value":{"error":{"code":"invalid_credentials","message":"Email hoặc mật khẩu không đúng"}}},"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found, lookup_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}},"examples":{"tenant_not_found":{"summary":"tenant_not_found","value":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}},"lookup_not_found":{"summary":"lookup_not_found","value":{"error":{"code":"lookup_not_found","message":"Không tìm thấy bản ghi"}}}}}}},"409":{"description":"Error response — codes: account_locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"account_locked","message":"Tài khoản đã bị khoá tạm thời do đăng nhập sai nhiều lần"}}}}},"410":{"description":"Error response — codes: reset_token_invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"reset_token_invalid","message":"Đường dẫn đặt lại mật khẩu không hợp lệ hoặc đã hết hạn"}}}}},"422":{"description":"Error response — codes: onboarding_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/settings/profile":{"get":{"tags":["settings"],"summary":"User Settings Profile Read","operationId":"user_settings_profile_read_api_user_settings_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]},"put":{"tags":["settings"],"summary":"User Settings Profile Update","operationId":"user_settings_profile_update_api_user_settings_profile_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/settings/language":{"put":{"tags":["settings"],"summary":"User Settings Language Update","operationId":"user_settings_language_update_api_user_settings_language_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageUpdate"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/settings/company":{"get":{"tags":["settings"],"summary":"User Settings Company Read","operationId":"user_settings_company_read_api_user_settings_company_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]},"put":{"tags":["settings"],"summary":"User Settings Company Update","operationId":"user_settings_company_update_api_user_settings_company_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/profile":{"get":{"tags":["profile"],"summary":"User Profile Full Read","operationId":"user_profile_full_read_api_user_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileFullResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]},"put":{"tags":["profile"],"summary":"User Profile Full Update","operationId":"user_profile_full_update_api_user_profile_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileFullUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileFullResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/onboarding/state":{"get":{"tags":["onboarding"],"summary":"User Onboarding State","operationId":"user_onboarding_state_api_user_onboarding_state_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingState"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/onboarding/company":{"post":{"tags":["onboarding"],"summary":"User Onboarding Company","operationId":"user_onboarding_company_api_user_onboarding_company_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyStep"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StepResult"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/onboarding/contact":{"post":{"tags":["onboarding"],"summary":"User Onboarding Contact","operationId":"user_onboarding_contact_api_user_onboarding_contact_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactStep"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StepResult"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/onboarding/complete":{"post":{"tags":["onboarding"],"summary":"User Onboarding Complete","operationId":"user_onboarding_complete_api_user_onboarding_complete_post","responses":{"204":{"description":"Successful Response"},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/requests":{"get":{"tags":["requests"],"summary":"User Request List","operationId":"user_request_list_api_user_requests_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"display_status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/DisplayStatus"},{"type":"null"}],"title":"Display Status"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Search"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestListResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/requests/status-counts":{"get":{"tags":["requests"],"summary":"User Request Status Counts","operationId":"user_request_status_counts_api_user_requests_status_counts_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Search"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserStatusCountsResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/requests/{request_id}/confirm":{"post":{"tags":["requests"],"summary":"User Request Confirm","operationId":"user_request_confirm_api_user_requests__request_id__confirm_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Request Id"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/requests/{request_id}/cancel":{"post":{"tags":["requests"],"summary":"User Request Cancel","operationId":"user_request_cancel_api_user_requests__request_id__cancel_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Request Id"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestSummary"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/requests/{request_id}/rate":{"post":{"tags":["requests"],"summary":"User Request Rate","operationId":"user_request_rate_api_user_requests__request_id__rate_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Request Id"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response User Request Rate Api User Requests  Request Id  Rate Post"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/requests/{request_id}/dismiss-rating-reminder":{"post":{"tags":["requests"],"summary":"User Request Dismiss Rating Reminder","operationId":"user_request_dismiss_rating_reminder_api_user_requests__request_id__dismiss_rating_reminder_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Request Id"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/requests/{request_id}/files/{kind}":{"get":{"tags":["requests"],"summary":"User Request File Download","operationId":"user_request_file_download_api_user_requests__request_id__files__kind__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Request Id"}},{"name":"kind","in":"path","required":true,"schema":{"$ref":"#/components/schemas/UserFileKind"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDownloadResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/requests/{request_id}":{"get":{"tags":["requests"],"summary":"User Request Detail","operationId":"user_request_detail_api_user_requests__request_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Request Id"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestDetail"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/etariff/quota":{"get":{"tags":["etariff"],"summary":"User Etariff Quota Status","operationId":"user_etariff_quota_status_api_user_etariff_quota_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaStatusResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/etariff/manual":{"post":{"tags":["etariff"],"summary":"Submit Manual lookup (async; FE polls status)","description":"Submit a 1-row E-Tariff classification. Returns **202 Accepted** immediately with `{lookup_id, status='pending'}`; the AI chain (15-120s) runs in a Celery worker.\n\n**FE flow:**\n1. `POST /api/user/etariff/manual` → 202 + `lookup_id`\n2. Poll `GET /api/user/etariff/manual/{lookup_id}` every 2-3s\n3. Stop polling when `status` is `completed` (read `result_json`) or `failed` (read `error_message`).\n\n**Errors:** `429 quota_exceeded` (BR-020 daily cap), `429 too_many_concurrent_lookups` (D12 per-tenant in-flight cap).","operationId":"user_etariff_manual_lookup_api_user_etariff_manual_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualLookupBody"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualLookupResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}},"/api/user/etariff/manual/{lookup_id}":{"get":{"tags":["etariff"],"summary":"Poll Manual lookup status","description":"Polling endpoint for an async Manual lookup created via `POST /api/user/etariff/manual`.\n\n**Lifecycle:**\n- `pending` — row inserted, Celery task queued.\n- `processing` — worker picked up, AI chain in flight.\n- `completed` — `result_json` populated with the 4-tab UI contract (FSD §5.7).\n- `failed` — chain hard-failed; `error_message` set, quota auto-rolled-back.\n\n**RBAC:** owner-scope (BR-030). Cross-user / cross-tenant / batch-mode rows return **404 lookup_not_found** (no leak).","operationId":"user_etariff_manual_status_api_user_etariff_manual__lookup_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lookup_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lookup Id"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualLookupStatusResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/etariff/history":{"get":{"tags":["etariff"],"summary":"User Etariff History","operationId":"user_etariff_history_api_user_etariff_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"mode","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EtariffMode"},{"type":"null"}],"title":"Mode"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/etariff/batch/{job_id}/confirm":{"post":{"tags":["etariff"],"summary":"Confirm Batch upload + trigger Celery worker","description":"**Step 3 of 4 in the Batch flow.** The `{job_id}` path parameter is the SAME UUID server returned as `draft_id` in **Step 1** (NOT minted by FE, NOT a new value).\n\n**Full Batch flow:**\n1. `POST /api/uploads/presigned-url` body `{ kind: 'etariff_batch', filename, mime, size_bytes }` → response `{ upload_url, expires_at, max_size_bytes, public_url: null, draft_id }`. **FE MUST reuse `draft_id` as the `{job_id}` path param in step 3.** *(Lives in the `/api/uploads/*` namespace — see `/docs/uploads`.)*\n2. `PUT {upload_url}` — FE uploads XLSX directly to S3 via the signed URL (TTL ~10 min).\n3. **`POST /api/user/etariff/batch/{job_id}/confirm`** *(this endpoint, `{job_id}` = step-1 `draft_id`)* → BE validates the uploaded file, INSERTs `EtariffBatchJob`, enqueues the Celery worker. Returns `{ job_id, status: 'pending', total_rows, will_process_rows }`.\n4. Poll `GET /api/user/etariff/batch/{job_id}` until terminal.\n\n**Errors:** `410 draft_expired_or_missing` (TTL 10 min expired OR FE passed a `{job_id}` that was never the server-issued `draft_id`), `403 upload_session_mismatch` (cross-user / cross-tenant `draft_id` reuse), `422 file_not_uploaded` / `excel_parse_error` / `excel_empty_rows` / `batch_rows_exceed_mvp_cap_20` / `quota_exhausted_no_processing_capacity`.","operationId":"user_etariff_batch_confirm_api_user_etariff_batch__job_id__confirm_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchConfirmResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/etariff/batch/{job_id}":{"get":{"tags":["etariff"],"summary":"Poll Batch job status + per-row items","description":"**Step 4 of 4 in the Batch flow.** Returns aggregate job status + IC-M-008 `items[]` array (one entry per row of the uploaded XLSX).\n\n**Job status lifecycle:** `pending` → `processing` → `completed` / `partial` / `failed`.\n\n**Per-row `items[].status`:** `pending` (worker yet to process), `completed` (4-tab `result_json`), `failed` (`error` populated, quota rolled back), `skipped_quota` (BR-021 — daily quota exhausted mid-job).\n\n**RBAC:** owner-scope (BR-030). Cross-user / cross-tenant returns **404 batch_job_not_found**.\n\nGet `job_id` from **Step 1** (`POST /api/uploads/presigned-url` kind=`etariff_batch`) — see `POST /api/user/etariff/batch/{job_id}/confirm` for the full flow.","operationId":"user_etariff_batch_status_api_user_etariff_batch__job_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}},{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchStatusResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}}}}}},"/api/user/dashboard":{"get":{"tags":["dashboard"],"summary":"User Dashboard","operationId":"user_dashboard_api_user_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDashboardResponse"}}}},"401":{"description":"Error response — codes: missing_bearer, token_revoked, user_inactive_or_missing, tenant_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}},"examples":{"missing_bearer":{"summary":"missing_bearer","value":{"error":{"code":"missing_bearer","message":"Thiếu thông tin xác thực"}}},"token_revoked":{"summary":"token_revoked","value":{"error":{"code":"token_revoked","message":"Phiên đăng nhập đã hết hạn, vui lòng đăng nhập lại"}}},"user_inactive_or_missing":{"summary":"user_inactive_or_missing","value":{"error":{"code":"user_inactive_or_missing","message":"Tài khoản không tồn tại hoặc đã bị vô hiệu hoá"}}},"tenant_disabled":{"summary":"tenant_disabled","value":{"error":{"code":"tenant_disabled","message":"Tenant đã bị vô hiệu hoá"}}}}}}},"403":{"description":"Error response — codes: insufficient_role, role_not_user, onboarding_required, password_change_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}},"examples":{"insufficient_role":{"summary":"insufficient_role","value":{"error":{"code":"insufficient_role","message":"Bạn không có quyền truy cập"}}},"role_not_user":{"summary":"role_not_user","value":{"error":{"code":"role_not_user","message":"Vai trò không phải user"}}},"onboarding_required":{"summary":"onboarding_required","value":{"error":{"code":"onboarding_required","message":"Vui lòng hoàn tất khởi tạo tài khoản trước"}}},"password_change_required":{"summary":"password_change_required","value":{"error":{"code":"password_change_required","message":"Vui lòng đổi mật khẩu trước khi tiếp tục"}}}}}}},"404":{"description":"Error response — codes: tenant_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"tenant_not_found","message":"Không tìm thấy tenant"}}}}}},"security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-T-Slug","in":"header","required":false,"description":"**Tenant slug** (vd `acme-corp`). FE **phải** gắn header này khi BE và FE khác origin (vd FE deploy `app.chc-service.shop` call BE `api.chc-service.shop`) — `Host` header lúc đó là `api.*` (reserved) không resolve được tenant.\n\n**Priority resolve tenant phía BE:**\n1. `X-T-Slug` header (cross-origin, dev local)\n2. `Host` header subdomain extraction (wildcard DNS `*.chc-service.shop` prod)\n\n**Format:** `^[a-z0-9][a-z0-9-]*$`, max 63 ký tự. Malformed → silent fallback Host. Header value không có DB row → tenant=None → endpoint trả 404 `tenant_not_found` (user/uploads namespace) hoặc default platform branding (public namespace).\n\n**Optional khi** FE và BE cùng wildcard subdomain (`acme.chc-service.shop` call `acme.chc-service.shop/api/...`) — Host tự work.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","maxLength":63,"example":"acme-corp"}}]}}},"components":{"schemas":{"AdditionalInfoEntry":{"properties":{"label":{"type":"string","maxLength":100,"minLength":1,"title":"Label","description":"Custom field label shown to user (G-C-003 dynamic field).","examples":["Xuất xứ"]},"value":{"type":"string","maxLength":1000,"minLength":1,"title":"Value","description":"Custom field value paired with `label`.","examples":["Việt Nam"]}},"additionalProperties":false,"type":"object","required":["label","value"],"title":"AdditionalInfoEntry"},"BatchConfirmResponse":{"properties":{"job_id":{"type":"string","format":"uuid","title":"Job Id"},"status":{"type":"string","title":"Status"},"total_rows":{"type":"integer","title":"Total Rows"},"will_process_rows":{"type":"integer","title":"Will Process Rows"}},"type":"object","required":["job_id","status","total_rows","will_process_rows"],"title":"BatchConfirmResponse","example":{"job_id":"bb0e8400-e29b-41d4-a716-446655440006","status":"pending","total_rows":50,"will_process_rows":50}},"BatchItem":{"properties":{"row_index":{"type":"integer","title":"Row Index"},"input_json":{"additionalProperties":true,"type":"object","title":"Input Json"},"result_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Result Json"},"ai_provider_request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Provider Request Id"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"status":{"$ref":"#/components/schemas/BatchItemStatus"}},"type":"object","required":["row_index","input_json","status"],"title":"BatchItem","description":"Per-row Batch item — ``result_json`` shares 4-tab shape with manual.","example":{"ai_provider_request_id":"stub-abc123def456","input_json":{"commodity_description":"Máy giặt gia dụng inverter","commodity_name":"Máy giặt cửa trước 9kg","function_use":"Giặt quần áo gia đình","material_composition":"Thép sơn tĩnh điện + nhựa ABS"},"result_json":{"ai_conclusion":{"analysis_summary":"Máy chiếu DLP gia đình 4K UHD có bản chất là máy chiếu video thuộc heading 8528, Section XVI, Chapter 85. Các mã thuộc nhóm thiết bị ghi âm, ghi hình, máy biến áp hoặc đồ chơi đều không phù hợp với chức năng chính của sản phẩm. Trong danh sách, mã 8528.52 là phù hợp nhất để phân loại mặt hàng này.","product_name":"Máy chiếu DLP gia đình","recommended_hs_code":"8528.52","results":[{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.95,"hs_code":"8528.52","hs_code_description":"Màn hình và máy chiếu, không kết hợp với thiết bị thu truyền hình; máy chiếu video","number_of_occurrences":5,"reason":"Mã 8528.52 thuộc nhóm 8528 bao gồm màn hình và máy chiếu, không kết hợp với thiết bị thu truyền hình; loại có khả năng kết nối trực tiếp và được thiết kế chủ yếu để sử dụng với máy xử lý dữ liệu tự động. Máy chiếu DLP gia đình là thiết bị chiếu hình ảnh video, đúng bản chất là “video projector” thuộc heading 8528. Sản phẩm có cổng HDMI, xử lý hình ảnh 4K và chức năng trình chiếu, hoàn toàn phù hợp với phạm vi máy chiếu của nhóm này. Đây là nhóm mã HS phổ biến và phù hợp nhất cho máy chiếu video gia đình.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.9,"hs_code":"8528.69","hs_code_description":"Máy chiếu khác","number_of_occurrences":1,"reason":"Mã 8528.69 thuộc phân nhóm máy chiếu khác trong heading 8528. Máy chiếu DLP gia đình 4K UHD là thiết bị chiếu video kỹ thuật số, phù hợp trực tiếp với mô tả này. Sản phẩm không phải màn hình đơn thuần mà là máy chiếu hình ảnh lên bề mặt ngoài. Do đó đây là mã rất phù hợp, chỉ xếp sau 8528.52 nếu xét phân nhóm chi tiết hơn theo cấu hình kết nối.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.85,"hs_code":"8528","hs_code_description":"Màn hình và máy chiếu, có hoặc không kết hợp với thiết bị thu truyền hình","number_of_occurrences":1,"reason":"Nhóm 8528 bao gồm màn hình và máy chiếu, có hoặc không kết hợp thiết bị thu truyền hình. Máy chiếu DLP gia đình thuộc đúng phạm vi chung của heading này về mặt chức năng và bản chất hàng hóa. Tuy nhiên, đây chỉ là mã 4 số (heading) chưa thể hiện phân nhóm cụ thể theo yêu cầu phân loại chi tiết. Do đó phù hợp cao nhưng chưa phải mã đầy đủ tối ưu để khai báo.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.05,"hs_code":"8504.31.30","hs_code_description":"Máy biến áp khác, công suất không quá 1 kVA","number_of_occurrences":1,"reason":"Mã 8504.31.30 thuộc nhóm máy biến áp công suất không quá 1 kVA. Máy chiếu DLP không phải là máy biến áp mà là thiết bị điện tử dùng để xử lý và chiếu hình ảnh. Mặc dù bên trong có thể có bộ nguồn hoặc biến áp, nhưng theo GRI 1 và chú giải phần XVI, không phân loại theo bộ phận phụ mà theo chức năng chính của toàn bộ thiết bị. Vì vậy mã này hoàn toàn không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.05,"hs_code":"8521.90.11","hs_code_description":"Thiết bị ghi hoặc tái tạo video khác","number_of_occurrences":1,"reason":"Mã 8521.90.11 thuộc nhóm thiết bị ghi hoặc tái tạo video khác (ví dụ đầu đĩa DVD, Blu-ray). Máy chiếu có thể tích hợp Android TV nhưng không phải thiết bị ghi/tái tạo video độc lập mà là thiết bị hiển thị. Theo nguyên tắc phân loại theo chức năng chính, sản phẩm không thuộc heading 8521. Do đó mức độ phù hợp rất thấp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.05,"hs_code":"8521.90.91","hs_code_description":"Thiết bị ghi hoặc tái tạo video khác, loại khác","number_of_occurrences":1,"reason":"Tương tự các mã 8521 khác, 8521.90.91 áp dụng cho thiết bị ghi hoặc tái tạo video. Máy chiếu DLP không thực hiện chức năng ghi hoặc phát lại nội dung từ phương tiện lưu trữ theo nghĩa của heading này. Chức năng chính vẫn là chiếu hình ảnh nhận từ nguồn tín hiệu. Vì vậy mã này không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.02,"hs_code":"8519.81.71","hs_code_description":"Thiết bị ghi hoặc tái tạo âm thanh khác","number_of_occurrences":1,"reason":"Mã 8519.81.71 thuộc nhóm thiết bị ghi hoặc tái tạo âm thanh (ví dụ đầu đĩa, thiết bị phát nhạc). Máy chiếu DLP có thể có loa tích hợp nhưng chức năng chính không phải ghi hoặc phát âm thanh độc lập. Bản chất hàng hóa là thiết bị chiếu hình ảnh video, không phải thiết bị âm thanh chuyên dụng. Do đó mã này không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.01,"hs_code":"8521.10.10","hs_code_description":"Thiết bị ghi hoặc tái tạo video dùng băng từ","number_of_occurrences":1,"reason":"Mã 8521.10.10 thuộc nhóm thiết bị ghi hoặc tái tạo video sử dụng băng từ (ví dụ đầu video cassette). Máy chiếu DLP không có chức năng ghi hoặc phát lại từ băng từ hay phương tiện lưu trữ độc lập như mô tả. Chức năng chính là nhận tín hiệu và chiếu hình ảnh lên màn chiếu. Vì vậy mã này hoàn toàn không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 95 - Đồ chơi, dụng cụ thể thao và các sản phẩm giải trí","compatibility_score":0.0,"hs_code":"9503.00.80","hs_code_description":"Đồ chơi khác","number_of_occurrences":1,"reason":"Mã 9503.00.80 thuộc nhóm đồ chơi và các sản phẩm giải trí cho trẻ em. Máy chiếu DLP gia đình là thiết bị điện tử cao cấp dùng cho giải trí và trình chiếu, không phải đồ chơi. Về bản chất kỹ thuật, cấu tạo và giá trị, sản phẩm thuộc nhóm thiết bị điện tử nghe nhìn chứ không phải hàng hóa thuộc Chương 95. Vì vậy hoàn toàn không phù hợp.","section_info":"Section XX - Hàng hóa và sản phẩm khác"}],"total_hs_codes_analyzed":9},"sen_ahtn":[{"content_of_citation":"\"THIẾT BỊ GHI HOẶC TÁI TẠO VIDEO, LOẠI DÙNG CHO ĐIỆN ẢNH HOẶC PHÁT THANH TRUYỀN HÌNH... được thiết kế chuyên dụng cho công nghệ phát thanh truyền hình hoặc điện ảnh, không dùng cho gia dụng.\"","metadata":{"chapter":"85","heading":"85.21","source_pages":[393,394],"title":"Thiết bị ghi hoặc tái tạo video dùng cho điện ảnh hoặc phát thanh truyền hình"},"reason":"Có liên quan đến thiết bị xử lý/tái tạo video thuộc Chương 85, tuy nhiên mô tả chỉ áp dụng cho thiết bị ghi hoặc tái tạo video chuyên dụng cho điện ảnh hoặc phát thanh truyền hình, không phải máy chiếu gia đình.","subheading_ids":["8521.90.11","8521.90.91","8521.10.10"]},{"content_of_citation":"\"MÁY BIẾN ÁP QUÉT VỀ... được sử dụng trong thiết bị thu truyền hình để cung cấp điện áp hồi lưu...\"","metadata":{"chapter":"85","heading":"85.04","source_pages":[385,386],"title":"Máy biến áp quét về (biến áp tần số quét ngược)"},"reason":"Là mã cho biến áp quét về dùng trong thiết bị thu truyền hình. Máy chiếu DLP có linh kiện điện tử và mạch xử lý nhưng bản chất không phải là biến áp hay linh kiện rời.","subheading_ids":["8504.31.30"]},{"content_of_citation":"\"THIẾT BỊ TÁI TẠO ÂM THANH KHÁC, KIỂU CASSETTE, LOẠI DÙNG CHO ĐIỆN ẢNH HOẶC PHÁT THANH...\"","metadata":{"chapter":"85","heading":"85.19","source_pages":[392,393],"title":"Thiết bị tái tạo âm thanh kiểu cassette dùng cho điện ảnh hoặc phát thanh"},"reason":"Là thiết bị tái tạo âm thanh kiểu cassette chuyên dùng cho điện ảnh hoặc phát thanh; không phù hợp vì sản phẩm là máy chiếu hình ảnh, không phải thiết bị âm thanh cassette.","subheading_ids":["8519.81.71"]},{"content_of_citation":"\"THIẾT BỊ GIÁO DỤC ĐIỆN TỬ TƯƠNG TÁC CẦM TAY ĐƯỢC THIẾT KẾ CHỦ YẾU CHO TRẺ EM...\"","metadata":{"chapter":"95","heading":"95.03","source_pages":[438,439,440],"title":"Thiết bị giáo dục điện tử tương tác cầm tay cho trẻ em"},"reason":"Là thiết bị giáo dục điện tử cầm tay cho trẻ em; không phù hợp vì máy chiếu DLP là thiết bị trình chiếu gia đình, không phải đồ chơi hay thiết bị giáo dục tương tác cầm tay.","subheading_ids":["9503.00.80"]}],"wco_compendium":[{"content_of_citation":"“Colour monitor comprising ... TFT LCD ... combined in the same housing with control circuitry... one HDMI connector... Resolution ... Application of GIRs 1 and 6.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[351]},"reason":"Sản phẩm là máy chiếu (projector) dùng để hiển thị hình ảnh 4K UHD, thuộc nhóm thiết bị hiển thị hình ảnh của Chương 85, nhóm 8528. Mặc dù các tiền lệ 8528.52 mô tả màn hình TFT LCD, nhưng chúng cùng bản chất là thiết bị hiển thị hình ảnh màu, có cổng HDMI và mạch điều khiển tích hợp. Máy chiếu DLP có chức năng tương tự là nhận tín hiệu HDMI và hiển thị hình ảnh.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor ... capable of directly connecting ... via one VGA or two HDMI connectors... Resolution : 1920 x 1080.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[352]},"reason":"Tiền lệ mô tả màn hình màu có khả năng kết nối HDMI/VGA và hiển thị độ phân giải cao. Máy chiếu DLP 4K UHD (3840x2160), 3000 lumens, HDMI 2.1, Wi‑Fi 6 có bản chất là thiết bị hiển thị hình ảnh màu từ nguồn tín hiệu số, tương đồng về chức năng nhận và xử lý tín hiệu hình ảnh.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor comprising ... TFT LCD active-matrix panel combined in the same housing with control circuitry... DVI-D ... VGA ... Resolution (max) ... Application of GIRs 1 and 6.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[347,573,574,691,692]},"reason":"Các tiền lệ 8528.52 đều nhấn mạnh bản chất là thiết bị hiển thị màu tích hợp mạch điều khiển và các cổng tín hiệu số. Máy chiếu DLP sử dụng chip DLP + bo mạch xử lý hình ảnh + cổng HDMI 2.1, phù hợp với nhóm thiết bị hiển thị hình ảnh thuộc 8528.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor ... one HDMI (High-Definition Multimedia Interface) connector... Supports High-bandwidth Digital Content Protection (HDCP)... Resolution (max) : 1920 x 1200.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[351]},"reason":"Tiền lệ mô tả màn hình có HDMI, Audio-In, hỗ trợ HDCP – là các tính năng nhận tín hiệu đa phương tiện tương tự máy chiếu gia đình. Máy chiếu có Android TV và Wi‑Fi 6 mở rộng chức năng nhưng không làm thay đổi bản chất là thiết bị hiển thị hình ảnh.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor ... Resolution (max) : 1280 x 1024 ... Brightness : 250 cd/m2; Contrast ratio : 1000:1... Application of GIRs 1 and 6.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[349]},"reason":"Tiền lệ 8528.52 mô tả màn hình màu với thông số độ sáng, độ phân giải và mạch điều khiển tích hợp. Máy chiếu DLP 4K UHD có thông số độ phân giải cao hơn và độ sáng 3000 lumens, nhưng vẫn cùng bản chất là thiết bị hiển thị hình ảnh màu thuộc nhóm 8528.","subheading_ids":["8528.52"]}],"wco_hs_notes":{"cache_hit":false,"chapter_classification":{"chapter_id":"85","chapter_title":"Chương 85: Máy điện và thiết bị điện và các bộ phận của chúng; máy ghi và tái tạo âm thanh, máy ghi và tái tạo hình ảnh và âm thanh truyền hình, bộ phận và phụ kiện của các loại máy trên","content_of_explanatory_notes":"Chú giải 6(D) Chương 84 quy định rằng nhóm 84.71 không bao gồm “màn hình và máy chiếu, không kết hợp thiết bị thu truyền hình”, ngay cả khi đáp ứng các điều kiện của máy xử lý dữ liệu tự động. Khái quát chung Chương 85 nêu rõ Chương này bao gồm tất cả các máy móc và thiết bị điện, ngoại trừ các loại đã được mô tả tại Chương 84; đồng thời bao gồm các thiết bị ghi hoặc tái tạo hình ảnh và các thiết bị điện hoạt động phụ thuộc vào đặc tính của điện.","file_name":"Section XVI - Chapter 85","file_path":"Section XVI/Chapter 85","gri_usage":["1"],"reason":"Trước hết, loại trừ Chương 84 vì theo Chú giải 6(D) Chương 84, “màn hình và máy chiếu, không kết hợp thiết bị thu truyền hình” không thuộc nhóm 84.71 ngay cả khi đáp ứng điều kiện của máy xử lý dữ liệu tự động. Sản phẩm là máy chiếu DLP hoàn chỉnh, hoạt động bằng điện, có chức năng chính là chiếu hình ảnh 4K UHD, do đó bản chất là thiết bị điện theo chức năng (Loại B – hàng hóa theo công dụng). Theo GRI 1, việc phân loại phải dựa trên nội dung tiêu đề Chương và các Chú giải pháp lý liên quan. Chương 85 bao gồm tất cả các máy móc và thiết bị điện, trừ những loại đã được mô tả cụ thể tại Chương 84. Vì máy chiếu không thuộc các nhóm chức năng cơ khí của Chương 84 và bị loại khỏi 84.71 theo Chú giải 6(D), nên phù hợp với phạm vi Chương 85. Do đó, xét theo tiêu đề và chú giải pháp lý, Chương 85 là chương phù hợp nhất cho sản phẩm này.","source_pages":[3,7,8]},"heading_classification":{"content_of_explanatory_notes":"Khái quát chung của nhóm 85.28 nêu rõ nhóm này bao gồm: (1) Màn hình và máy chiếu, không gắn với thiết bị thu sóng truyền hình; (2) Máy thu truyền hình có hoặc không gắn thiết bị khác. Phần (C) quy định “Máy chiếu cho phép các hình ảnh được tái tạo… chiếu trên một bề mặt bên ngoài” và có thể dựa trên các công nghệ như LCD, DMD (Digital Micromirror Device – nền tảng của DLP) hoặc công nghệ tương tự. Điều này phù hợp trực tiếp với máy chiếu DLP 4K UHD dùng để chiếu hình ảnh ra màn chiếu trong gia đình.","gri_usage":["1"],"heading_id":"85.28","heading_title":"Màn hình và máy chiếu, không gắn với thiết bị thu dùng trong truyền hình; thiết bị thu dùng trong truyền hình, có hoặc không gắn với máy thu thanh sóng vô tuyến hoặc thiết bị ghi hoặc tái tạo âm thanh hoặc hình ảnh.","reason":"Sản phẩm được mô tả là “Máy chiếu DLP gia đình – Home Cinema 4K UHD”, có chức năng chiếu phim và trình chiếu trong gia đình. Xét về bản chất, đây là một thiết bị hoàn chỉnh hoạt động bằng điện, có chức năng chính là chiếu hình ảnh ra bề mặt bên ngoài thông qua công nghệ DLP, đèn LED và hệ thống xử lý hình ảnh – tức là một máy chiếu video. Theo GRI 1, việc phân loại được thực hiện dựa trên nội dung của các Heading và Chú giải liên quan. Đối chiếu các nhóm trong Chương 85, nhóm 85.28 mô tả rõ “Màn hình và máy chiếu, không gắn với thiết bị thu dùng trong truyền hình”, phù hợp trực tiếp với chức năng cốt lõi của hàng hóa. Sản phẩm không phải là thiết bị ghi hoặc tái tạo video (loại trừ nhóm 85.21), cũng không phải thiết bị phát sóng hay camera (loại trừ nhóm 85.25). Không có Chú giải loại trừ nào của nhóm 85.28 áp dụng cho máy chiếu gia đình độc lập như mô tả. Do đó, nhóm 85.28 là nhóm phù hợp và mô tả chính xác nhất bản chất hàng hóa.","source_pages":[1,2,3,4]},"pre_classification":{"candidate_section_ids":["XVI","XVIII","VII"],"reasoning":"Rerank scores: ['0.6646', '0.5212', '0.3013']"},"section_classification":{"content_of_explanatory_notes":"Phần XVI bao gồm tất cả các loại máy móc hoặc thiết bị cơ khí hoặc điện, trừ khi được nêu đặc biệt trong các Phần khác. Theo Chú giải 1 Phần XVI, Phần này không bao gồm các sản phẩm đã được quy định cụ thể tại các Phần khác như Phần XVII, XVIII, Chương 90, 91… Khái quát chung cũng nêu rõ máy móc chưa hoàn chỉnh hoặc tháo rời vẫn được phân loại như máy hoàn chỉnh nếu có đặc trưng cơ bản của máy đó. Phần này bao gồm thiết bị điện và các thiết bị ghi, tái tạo hình ảnh và âm thanh truyền hình.","file_name":"N/A","file_path":"N/A","gri_usage":["1"],"product_analysis":"- <strong>Bản chất hàng hoá:</strong> Là một thiết bị điện tử hoàn chỉnh (máy chiếu DLP) dùng để trình chiếu hình ảnh 4K UHD, thuộc nhóm máy móc – thiết bị điện.\n- <strong>Loại hàng hoá liên quan:</strong> Là thiết bị trình chiếu hình ảnh (video projector) sử dụng công nghệ DLP, tích hợp chip xử lý hình ảnh, đèn LED, cổng HDMI, Wi‑Fi và hệ điều hành Android TV.\n- <strong>Công dụng chung:</strong> Không phải là bộ phận có công dụng chung; đây là một máy hoàn chỉnh có chức năng xác định là chiếu phim và trình chiếu hình ảnh trong gia đình.\n- <strong>Tình trạng hàng hoá:</strong> Hàng hóa hoàn chỉnh, đã lắp ráp đầy đủ các bộ phận cấu thành (chip DLP, bo mạch, ống kính, nguồn sáng LED) và sẵn sàng sử dụng.","reason":"Trước hết, loại trừ Section VII vì mặc dù sản phẩm có vỏ nhựa ABS, nhưng Chú giải loại trừ của Chương 39 nêu rõ không bao gồm các mặt hàng thuộc Phần XVI (máy và thiết bị cơ khí hoặc điện). Máy chiếu là một thiết bị điện tử hoàn chỉnh, không phải sản phẩm được phân loại theo vật liệu cấu thành, do đó không phù hợp với bản chất của Section VII. Tiếp theo, xem xét Section XVIII (Chương 90) về dụng cụ quang học; tuy nhiên, Chương 90 chủ yếu bao gồm các thiết bị có tính chính xác cao dùng cho mục đích khoa học, kỹ thuật, đo lường hoặc y tế, trong khi máy chiếu gia đình là thiết bị điện tử nghe nhìn phục vụ giải trí. Theo GRI 1, việc phân loại phải dựa trên nội dung tiêu đề Phần và các Chú giải pháp lý liên quan; Section XVI bao quát “thiết bị điện; thiết bị ghi và tái tạo hình ảnh, âm thanh truyền hình”, phù hợp trực tiếp với chức năng chiếu hình ảnh 4K UHD qua HDMI, Wi-Fi, Android TV. Máy chiếu DLP là một thiết bị điện hoàn chỉnh, tích hợp chip DLP, bo mạch xử lý hình ảnh và nguồn sáng LED để thực hiện chức năng hiển thị hình ảnh. Ngoài ra, Chú giải Phần XVI cũng quy định máy hoàn chỉnh hoặc tháo rời vẫn phân loại như máy hoàn chỉnh, càng củng cố việc xếp vào Phần này. Do đó, Section XVI là Phần phù hợp nhất với bản chất và chức năng cốt lõi của sản phẩm.","section_id":"XVI","section_title":"MÁY VÀ CÁC TRANG THIẾT BỊ CƠ KHÍ; THIẾT BỊ ĐIỆN; CÁC BỘ PHẬN CỦA CHÚNG; THIẾT BỊ GHI VÀ TÁI TẠO ÂM THANH, THIẾT BỊ GHI VÀ TÁI TẠO HÌNH ẢNH, ÂM THANH TRUYỀN HÌNH VÀ CÁC BỘ PHẬN VÀ PHỤ KIỆN CỦA CÁC THIẾT BỊ TRÊN","source_pages":[3,4]},"subheading_classification":{"content_of_explanatory_notes":"Phần (C) MÁY CHIẾU nêu rõ: Máy chiếu cho phép các hình ảnh được tái tạo bình thường trên màn ảnh của máy thu truyền hình hoặc của màn hình monitor được chiếu trên một bề mặt bên ngoài; chúng có thể dựa trên công nghệ CRT hoặc màn hình dẹt (ví dụ DMD, LCD, plasma). Ngoài ra, Khái quát chung cũng quy định rằng nếu màn hình hoặc máy chiếu có tích hợp bộ dò tín hiệu truyền hình thì được xem như thiết bị thu dùng trong truyền hình.","gri_usage":["1","6"],"reason":"Theo GRI 1, sản phẩm được xác định thuộc Nhóm 85.28 vì đây là máy chiếu sử dụng công nghệ DLP (DMD) để tái tạo và chiếu hình ảnh lên bề mặt bên ngoài, đúng với mô tả tại phần (C) MÁY CHIẾU trong Khái quát chung. Sản phẩm không phải là màn hình (monitor) vì không hiển thị trực tiếp trên một màn hình tích hợp, và cũng không phải là thiết bị thu dùng cho truyền hình do không có thông tin về bộ dò kênh (tuner) thu tín hiệu truyền hình. Áp dụng GRI 6 để phân loại ở cấp phân nhóm, trước hết tại cấp 1 gạch (-), hàng hóa phù hợp với phân nhóm “- Máy chiếu”. Tiếp theo, ở cấp 2 gạch (--), cần xem xét tiêu chí “có khả năng kết nối trực tiếp và được thiết kế để dùng cho máy xử lý dữ liệu tự động thuộc nhóm 84.71”. Mặc dù máy có cổng HDMI và Wi‑Fi, mô tả cho thấy đây là máy chiếu Home Cinema dùng chiếu phim gia đình với Android TV tích hợp, không được thiết kế chuyên dùng cho hệ thống máy xử lý dữ liệu tự động. Do đó, không đáp ứng tiêu chí của phân nhóm 8528.62. Vì vậy, phân nhóm phù hợp nhất là 8528.69 – Loại khác.","source_pages":[1,3],"subheading_id":"8528.69","subheading_title":"-- Loại khác."},"task_id":"8f40ee6a-f7cb-4fa3-acc8-e60b5d5590be"}},"row_index":1,"status":"completed"}},"BatchItemStatus":{"type":"string","enum":["pending","completed","failed","skipped_quota"],"title":"BatchItemStatus"},"BatchStatusResponse":{"properties":{"job_id":{"type":"string","format":"uuid","title":"Job Id"},"status":{"type":"string","title":"Status"},"total_rows":{"type":"integer","title":"Total Rows"},"processed_rows":{"type":"integer","title":"Processed Rows"},"items":{"items":{"$ref":"#/components/schemas/BatchItem"},"type":"array","title":"Items"}},"type":"object","required":["job_id","status","total_rows","processed_rows","items"],"title":"BatchStatusResponse","example":{"items":[{"ai_provider_request_id":"stub-abc123def456","input_json":{"commodity_description":"Máy giặt gia dụng inverter","commodity_name":"Máy giặt cửa trước 9kg"},"result_json":{"ai_conclusion":{"analysis_summary":"Máy chiếu DLP gia đình 4K UHD có bản chất là máy chiếu video thuộc heading 8528, Section XVI, Chapter 85. Các mã thuộc nhóm thiết bị ghi âm, ghi hình, máy biến áp hoặc đồ chơi đều không phù hợp với chức năng chính của sản phẩm. Trong danh sách, mã 8528.52 là phù hợp nhất để phân loại mặt hàng này.","product_name":"Máy chiếu DLP gia đình","recommended_hs_code":"8528.52","results":[{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.95,"hs_code":"8528.52","hs_code_description":"Màn hình và máy chiếu, không kết hợp với thiết bị thu truyền hình; máy chiếu video","number_of_occurrences":5,"reason":"Mã 8528.52 thuộc nhóm 8528 bao gồm màn hình và máy chiếu, không kết hợp với thiết bị thu truyền hình; loại có khả năng kết nối trực tiếp và được thiết kế chủ yếu để sử dụng với máy xử lý dữ liệu tự động. Máy chiếu DLP gia đình là thiết bị chiếu hình ảnh video, đúng bản chất là “video projector” thuộc heading 8528. Sản phẩm có cổng HDMI, xử lý hình ảnh 4K và chức năng trình chiếu, hoàn toàn phù hợp với phạm vi máy chiếu của nhóm này. Đây là nhóm mã HS phổ biến và phù hợp nhất cho máy chiếu video gia đình.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.9,"hs_code":"8528.69","hs_code_description":"Máy chiếu khác","number_of_occurrences":1,"reason":"Mã 8528.69 thuộc phân nhóm máy chiếu khác trong heading 8528. Máy chiếu DLP gia đình 4K UHD là thiết bị chiếu video kỹ thuật số, phù hợp trực tiếp với mô tả này. Sản phẩm không phải màn hình đơn thuần mà là máy chiếu hình ảnh lên bề mặt ngoài. Do đó đây là mã rất phù hợp, chỉ xếp sau 8528.52 nếu xét phân nhóm chi tiết hơn theo cấu hình kết nối.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.85,"hs_code":"8528","hs_code_description":"Màn hình và máy chiếu, có hoặc không kết hợp với thiết bị thu truyền hình","number_of_occurrences":1,"reason":"Nhóm 8528 bao gồm màn hình và máy chiếu, có hoặc không kết hợp thiết bị thu truyền hình. Máy chiếu DLP gia đình thuộc đúng phạm vi chung của heading này về mặt chức năng và bản chất hàng hóa. Tuy nhiên, đây chỉ là mã 4 số (heading) chưa thể hiện phân nhóm cụ thể theo yêu cầu phân loại chi tiết. Do đó phù hợp cao nhưng chưa phải mã đầy đủ tối ưu để khai báo.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.05,"hs_code":"8504.31.30","hs_code_description":"Máy biến áp khác, công suất không quá 1 kVA","number_of_occurrences":1,"reason":"Mã 8504.31.30 thuộc nhóm máy biến áp công suất không quá 1 kVA. Máy chiếu DLP không phải là máy biến áp mà là thiết bị điện tử dùng để xử lý và chiếu hình ảnh. Mặc dù bên trong có thể có bộ nguồn hoặc biến áp, nhưng theo GRI 1 và chú giải phần XVI, không phân loại theo bộ phận phụ mà theo chức năng chính của toàn bộ thiết bị. Vì vậy mã này hoàn toàn không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.05,"hs_code":"8521.90.11","hs_code_description":"Thiết bị ghi hoặc tái tạo video khác","number_of_occurrences":1,"reason":"Mã 8521.90.11 thuộc nhóm thiết bị ghi hoặc tái tạo video khác (ví dụ đầu đĩa DVD, Blu-ray). Máy chiếu có thể tích hợp Android TV nhưng không phải thiết bị ghi/tái tạo video độc lập mà là thiết bị hiển thị. Theo nguyên tắc phân loại theo chức năng chính, sản phẩm không thuộc heading 8521. Do đó mức độ phù hợp rất thấp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.05,"hs_code":"8521.90.91","hs_code_description":"Thiết bị ghi hoặc tái tạo video khác, loại khác","number_of_occurrences":1,"reason":"Tương tự các mã 8521 khác, 8521.90.91 áp dụng cho thiết bị ghi hoặc tái tạo video. Máy chiếu DLP không thực hiện chức năng ghi hoặc phát lại nội dung từ phương tiện lưu trữ theo nghĩa của heading này. Chức năng chính vẫn là chiếu hình ảnh nhận từ nguồn tín hiệu. Vì vậy mã này không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.02,"hs_code":"8519.81.71","hs_code_description":"Thiết bị ghi hoặc tái tạo âm thanh khác","number_of_occurrences":1,"reason":"Mã 8519.81.71 thuộc nhóm thiết bị ghi hoặc tái tạo âm thanh (ví dụ đầu đĩa, thiết bị phát nhạc). Máy chiếu DLP có thể có loa tích hợp nhưng chức năng chính không phải ghi hoặc phát âm thanh độc lập. Bản chất hàng hóa là thiết bị chiếu hình ảnh video, không phải thiết bị âm thanh chuyên dụng. Do đó mã này không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.01,"hs_code":"8521.10.10","hs_code_description":"Thiết bị ghi hoặc tái tạo video dùng băng từ","number_of_occurrences":1,"reason":"Mã 8521.10.10 thuộc nhóm thiết bị ghi hoặc tái tạo video sử dụng băng từ (ví dụ đầu video cassette). Máy chiếu DLP không có chức năng ghi hoặc phát lại từ băng từ hay phương tiện lưu trữ độc lập như mô tả. Chức năng chính là nhận tín hiệu và chiếu hình ảnh lên màn chiếu. Vì vậy mã này hoàn toàn không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 95 - Đồ chơi, dụng cụ thể thao và các sản phẩm giải trí","compatibility_score":0.0,"hs_code":"9503.00.80","hs_code_description":"Đồ chơi khác","number_of_occurrences":1,"reason":"Mã 9503.00.80 thuộc nhóm đồ chơi và các sản phẩm giải trí cho trẻ em. Máy chiếu DLP gia đình là thiết bị điện tử cao cấp dùng cho giải trí và trình chiếu, không phải đồ chơi. Về bản chất kỹ thuật, cấu tạo và giá trị, sản phẩm thuộc nhóm thiết bị điện tử nghe nhìn chứ không phải hàng hóa thuộc Chương 95. Vì vậy hoàn toàn không phù hợp.","section_info":"Section XX - Hàng hóa và sản phẩm khác"}],"total_hs_codes_analyzed":9},"sen_ahtn":[{"content_of_citation":"\"THIẾT BỊ GHI HOẶC TÁI TẠO VIDEO, LOẠI DÙNG CHO ĐIỆN ẢNH HOẶC PHÁT THANH TRUYỀN HÌNH... được thiết kế chuyên dụng cho công nghệ phát thanh truyền hình hoặc điện ảnh, không dùng cho gia dụng.\"","metadata":{"chapter":"85","heading":"85.21","source_pages":[393,394],"title":"Thiết bị ghi hoặc tái tạo video dùng cho điện ảnh hoặc phát thanh truyền hình"},"reason":"Có liên quan đến thiết bị xử lý/tái tạo video thuộc Chương 85, tuy nhiên mô tả chỉ áp dụng cho thiết bị ghi hoặc tái tạo video chuyên dụng cho điện ảnh hoặc phát thanh truyền hình, không phải máy chiếu gia đình.","subheading_ids":["8521.90.11","8521.90.91","8521.10.10"]},{"content_of_citation":"\"MÁY BIẾN ÁP QUÉT VỀ... được sử dụng trong thiết bị thu truyền hình để cung cấp điện áp hồi lưu...\"","metadata":{"chapter":"85","heading":"85.04","source_pages":[385,386],"title":"Máy biến áp quét về (biến áp tần số quét ngược)"},"reason":"Là mã cho biến áp quét về dùng trong thiết bị thu truyền hình. Máy chiếu DLP có linh kiện điện tử và mạch xử lý nhưng bản chất không phải là biến áp hay linh kiện rời.","subheading_ids":["8504.31.30"]},{"content_of_citation":"\"THIẾT BỊ TÁI TẠO ÂM THANH KHÁC, KIỂU CASSETTE, LOẠI DÙNG CHO ĐIỆN ẢNH HOẶC PHÁT THANH...\"","metadata":{"chapter":"85","heading":"85.19","source_pages":[392,393],"title":"Thiết bị tái tạo âm thanh kiểu cassette dùng cho điện ảnh hoặc phát thanh"},"reason":"Là thiết bị tái tạo âm thanh kiểu cassette chuyên dùng cho điện ảnh hoặc phát thanh; không phù hợp vì sản phẩm là máy chiếu hình ảnh, không phải thiết bị âm thanh cassette.","subheading_ids":["8519.81.71"]},{"content_of_citation":"\"THIẾT BỊ GIÁO DỤC ĐIỆN TỬ TƯƠNG TÁC CẦM TAY ĐƯỢC THIẾT KẾ CHỦ YẾU CHO TRẺ EM...\"","metadata":{"chapter":"95","heading":"95.03","source_pages":[438,439,440],"title":"Thiết bị giáo dục điện tử tương tác cầm tay cho trẻ em"},"reason":"Là thiết bị giáo dục điện tử cầm tay cho trẻ em; không phù hợp vì máy chiếu DLP là thiết bị trình chiếu gia đình, không phải đồ chơi hay thiết bị giáo dục tương tác cầm tay.","subheading_ids":["9503.00.80"]}],"wco_compendium":[{"content_of_citation":"“Colour monitor comprising ... TFT LCD ... combined in the same housing with control circuitry... one HDMI connector... Resolution ... Application of GIRs 1 and 6.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[351]},"reason":"Sản phẩm là máy chiếu (projector) dùng để hiển thị hình ảnh 4K UHD, thuộc nhóm thiết bị hiển thị hình ảnh của Chương 85, nhóm 8528. Mặc dù các tiền lệ 8528.52 mô tả màn hình TFT LCD, nhưng chúng cùng bản chất là thiết bị hiển thị hình ảnh màu, có cổng HDMI và mạch điều khiển tích hợp. Máy chiếu DLP có chức năng tương tự là nhận tín hiệu HDMI và hiển thị hình ảnh.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor ... capable of directly connecting ... via one VGA or two HDMI connectors... Resolution : 1920 x 1080.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[352]},"reason":"Tiền lệ mô tả màn hình màu có khả năng kết nối HDMI/VGA và hiển thị độ phân giải cao. Máy chiếu DLP 4K UHD (3840x2160), 3000 lumens, HDMI 2.1, Wi‑Fi 6 có bản chất là thiết bị hiển thị hình ảnh màu từ nguồn tín hiệu số, tương đồng về chức năng nhận và xử lý tín hiệu hình ảnh.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor comprising ... TFT LCD active-matrix panel combined in the same housing with control circuitry... DVI-D ... VGA ... Resolution (max) ... Application of GIRs 1 and 6.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[347,573,574,691,692]},"reason":"Các tiền lệ 8528.52 đều nhấn mạnh bản chất là thiết bị hiển thị màu tích hợp mạch điều khiển và các cổng tín hiệu số. Máy chiếu DLP sử dụng chip DLP + bo mạch xử lý hình ảnh + cổng HDMI 2.1, phù hợp với nhóm thiết bị hiển thị hình ảnh thuộc 8528.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor ... one HDMI (High-Definition Multimedia Interface) connector... Supports High-bandwidth Digital Content Protection (HDCP)... Resolution (max) : 1920 x 1200.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[351]},"reason":"Tiền lệ mô tả màn hình có HDMI, Audio-In, hỗ trợ HDCP – là các tính năng nhận tín hiệu đa phương tiện tương tự máy chiếu gia đình. Máy chiếu có Android TV và Wi‑Fi 6 mở rộng chức năng nhưng không làm thay đổi bản chất là thiết bị hiển thị hình ảnh.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor ... Resolution (max) : 1280 x 1024 ... Brightness : 250 cd/m2; Contrast ratio : 1000:1... Application of GIRs 1 and 6.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[349]},"reason":"Tiền lệ 8528.52 mô tả màn hình màu với thông số độ sáng, độ phân giải và mạch điều khiển tích hợp. Máy chiếu DLP 4K UHD có thông số độ phân giải cao hơn và độ sáng 3000 lumens, nhưng vẫn cùng bản chất là thiết bị hiển thị hình ảnh màu thuộc nhóm 8528.","subheading_ids":["8528.52"]}],"wco_hs_notes":{"cache_hit":false,"chapter_classification":{"chapter_id":"85","chapter_title":"Chương 85: Máy điện và thiết bị điện và các bộ phận của chúng; máy ghi và tái tạo âm thanh, máy ghi và tái tạo hình ảnh và âm thanh truyền hình, bộ phận và phụ kiện của các loại máy trên","content_of_explanatory_notes":"Chú giải 6(D) Chương 84 quy định rằng nhóm 84.71 không bao gồm “màn hình và máy chiếu, không kết hợp thiết bị thu truyền hình”, ngay cả khi đáp ứng các điều kiện của máy xử lý dữ liệu tự động. Khái quát chung Chương 85 nêu rõ Chương này bao gồm tất cả các máy móc và thiết bị điện, ngoại trừ các loại đã được mô tả tại Chương 84; đồng thời bao gồm các thiết bị ghi hoặc tái tạo hình ảnh và các thiết bị điện hoạt động phụ thuộc vào đặc tính của điện.","file_name":"Section XVI - Chapter 85","file_path":"Section XVI/Chapter 85","gri_usage":["1"],"reason":"Trước hết, loại trừ Chương 84 vì theo Chú giải 6(D) Chương 84, “màn hình và máy chiếu, không kết hợp thiết bị thu truyền hình” không thuộc nhóm 84.71 ngay cả khi đáp ứng điều kiện của máy xử lý dữ liệu tự động. Sản phẩm là máy chiếu DLP hoàn chỉnh, hoạt động bằng điện, có chức năng chính là chiếu hình ảnh 4K UHD, do đó bản chất là thiết bị điện theo chức năng (Loại B – hàng hóa theo công dụng). Theo GRI 1, việc phân loại phải dựa trên nội dung tiêu đề Chương và các Chú giải pháp lý liên quan. Chương 85 bao gồm tất cả các máy móc và thiết bị điện, trừ những loại đã được mô tả cụ thể tại Chương 84. Vì máy chiếu không thuộc các nhóm chức năng cơ khí của Chương 84 và bị loại khỏi 84.71 theo Chú giải 6(D), nên phù hợp với phạm vi Chương 85. Do đó, xét theo tiêu đề và chú giải pháp lý, Chương 85 là chương phù hợp nhất cho sản phẩm này.","source_pages":[3,7,8]},"heading_classification":{"content_of_explanatory_notes":"Khái quát chung của nhóm 85.28 nêu rõ nhóm này bao gồm: (1) Màn hình và máy chiếu, không gắn với thiết bị thu sóng truyền hình; (2) Máy thu truyền hình có hoặc không gắn thiết bị khác. Phần (C) quy định “Máy chiếu cho phép các hình ảnh được tái tạo… chiếu trên một bề mặt bên ngoài” và có thể dựa trên các công nghệ như LCD, DMD (Digital Micromirror Device – nền tảng của DLP) hoặc công nghệ tương tự. Điều này phù hợp trực tiếp với máy chiếu DLP 4K UHD dùng để chiếu hình ảnh ra màn chiếu trong gia đình.","gri_usage":["1"],"heading_id":"85.28","heading_title":"Màn hình và máy chiếu, không gắn với thiết bị thu dùng trong truyền hình; thiết bị thu dùng trong truyền hình, có hoặc không gắn với máy thu thanh sóng vô tuyến hoặc thiết bị ghi hoặc tái tạo âm thanh hoặc hình ảnh.","reason":"Sản phẩm được mô tả là “Máy chiếu DLP gia đình – Home Cinema 4K UHD”, có chức năng chiếu phim và trình chiếu trong gia đình. Xét về bản chất, đây là một thiết bị hoàn chỉnh hoạt động bằng điện, có chức năng chính là chiếu hình ảnh ra bề mặt bên ngoài thông qua công nghệ DLP, đèn LED và hệ thống xử lý hình ảnh – tức là một máy chiếu video. Theo GRI 1, việc phân loại được thực hiện dựa trên nội dung của các Heading và Chú giải liên quan. Đối chiếu các nhóm trong Chương 85, nhóm 85.28 mô tả rõ “Màn hình và máy chiếu, không gắn với thiết bị thu dùng trong truyền hình”, phù hợp trực tiếp với chức năng cốt lõi của hàng hóa. Sản phẩm không phải là thiết bị ghi hoặc tái tạo video (loại trừ nhóm 85.21), cũng không phải thiết bị phát sóng hay camera (loại trừ nhóm 85.25). Không có Chú giải loại trừ nào của nhóm 85.28 áp dụng cho máy chiếu gia đình độc lập như mô tả. Do đó, nhóm 85.28 là nhóm phù hợp và mô tả chính xác nhất bản chất hàng hóa.","source_pages":[1,2,3,4]},"pre_classification":{"candidate_section_ids":["XVI","XVIII","VII"],"reasoning":"Rerank scores: ['0.6646', '0.5212', '0.3013']"},"section_classification":{"content_of_explanatory_notes":"Phần XVI bao gồm tất cả các loại máy móc hoặc thiết bị cơ khí hoặc điện, trừ khi được nêu đặc biệt trong các Phần khác. Theo Chú giải 1 Phần XVI, Phần này không bao gồm các sản phẩm đã được quy định cụ thể tại các Phần khác như Phần XVII, XVIII, Chương 90, 91… Khái quát chung cũng nêu rõ máy móc chưa hoàn chỉnh hoặc tháo rời vẫn được phân loại như máy hoàn chỉnh nếu có đặc trưng cơ bản của máy đó. Phần này bao gồm thiết bị điện và các thiết bị ghi, tái tạo hình ảnh và âm thanh truyền hình.","file_name":"N/A","file_path":"N/A","gri_usage":["1"],"product_analysis":"- <strong>Bản chất hàng hoá:</strong> Là một thiết bị điện tử hoàn chỉnh (máy chiếu DLP) dùng để trình chiếu hình ảnh 4K UHD, thuộc nhóm máy móc – thiết bị điện.\n- <strong>Loại hàng hoá liên quan:</strong> Là thiết bị trình chiếu hình ảnh (video projector) sử dụng công nghệ DLP, tích hợp chip xử lý hình ảnh, đèn LED, cổng HDMI, Wi‑Fi và hệ điều hành Android TV.\n- <strong>Công dụng chung:</strong> Không phải là bộ phận có công dụng chung; đây là một máy hoàn chỉnh có chức năng xác định là chiếu phim và trình chiếu hình ảnh trong gia đình.\n- <strong>Tình trạng hàng hoá:</strong> Hàng hóa hoàn chỉnh, đã lắp ráp đầy đủ các bộ phận cấu thành (chip DLP, bo mạch, ống kính, nguồn sáng LED) và sẵn sàng sử dụng.","reason":"Trước hết, loại trừ Section VII vì mặc dù sản phẩm có vỏ nhựa ABS, nhưng Chú giải loại trừ của Chương 39 nêu rõ không bao gồm các mặt hàng thuộc Phần XVI (máy và thiết bị cơ khí hoặc điện). Máy chiếu là một thiết bị điện tử hoàn chỉnh, không phải sản phẩm được phân loại theo vật liệu cấu thành, do đó không phù hợp với bản chất của Section VII. Tiếp theo, xem xét Section XVIII (Chương 90) về dụng cụ quang học; tuy nhiên, Chương 90 chủ yếu bao gồm các thiết bị có tính chính xác cao dùng cho mục đích khoa học, kỹ thuật, đo lường hoặc y tế, trong khi máy chiếu gia đình là thiết bị điện tử nghe nhìn phục vụ giải trí. Theo GRI 1, việc phân loại phải dựa trên nội dung tiêu đề Phần và các Chú giải pháp lý liên quan; Section XVI bao quát “thiết bị điện; thiết bị ghi và tái tạo hình ảnh, âm thanh truyền hình”, phù hợp trực tiếp với chức năng chiếu hình ảnh 4K UHD qua HDMI, Wi-Fi, Android TV. Máy chiếu DLP là một thiết bị điện hoàn chỉnh, tích hợp chip DLP, bo mạch xử lý hình ảnh và nguồn sáng LED để thực hiện chức năng hiển thị hình ảnh. Ngoài ra, Chú giải Phần XVI cũng quy định máy hoàn chỉnh hoặc tháo rời vẫn phân loại như máy hoàn chỉnh, càng củng cố việc xếp vào Phần này. Do đó, Section XVI là Phần phù hợp nhất với bản chất và chức năng cốt lõi của sản phẩm.","section_id":"XVI","section_title":"MÁY VÀ CÁC TRANG THIẾT BỊ CƠ KHÍ; THIẾT BỊ ĐIỆN; CÁC BỘ PHẬN CỦA CHÚNG; THIẾT BỊ GHI VÀ TÁI TẠO ÂM THANH, THIẾT BỊ GHI VÀ TÁI TẠO HÌNH ẢNH, ÂM THANH TRUYỀN HÌNH VÀ CÁC BỘ PHẬN VÀ PHỤ KIỆN CỦA CÁC THIẾT BỊ TRÊN","source_pages":[3,4]},"subheading_classification":{"content_of_explanatory_notes":"Phần (C) MÁY CHIẾU nêu rõ: Máy chiếu cho phép các hình ảnh được tái tạo bình thường trên màn ảnh của máy thu truyền hình hoặc của màn hình monitor được chiếu trên một bề mặt bên ngoài; chúng có thể dựa trên công nghệ CRT hoặc màn hình dẹt (ví dụ DMD, LCD, plasma). Ngoài ra, Khái quát chung cũng quy định rằng nếu màn hình hoặc máy chiếu có tích hợp bộ dò tín hiệu truyền hình thì được xem như thiết bị thu dùng trong truyền hình.","gri_usage":["1","6"],"reason":"Theo GRI 1, sản phẩm được xác định thuộc Nhóm 85.28 vì đây là máy chiếu sử dụng công nghệ DLP (DMD) để tái tạo và chiếu hình ảnh lên bề mặt bên ngoài, đúng với mô tả tại phần (C) MÁY CHIẾU trong Khái quát chung. Sản phẩm không phải là màn hình (monitor) vì không hiển thị trực tiếp trên một màn hình tích hợp, và cũng không phải là thiết bị thu dùng cho truyền hình do không có thông tin về bộ dò kênh (tuner) thu tín hiệu truyền hình. Áp dụng GRI 6 để phân loại ở cấp phân nhóm, trước hết tại cấp 1 gạch (-), hàng hóa phù hợp với phân nhóm “- Máy chiếu”. Tiếp theo, ở cấp 2 gạch (--), cần xem xét tiêu chí “có khả năng kết nối trực tiếp và được thiết kế để dùng cho máy xử lý dữ liệu tự động thuộc nhóm 84.71”. Mặc dù máy có cổng HDMI và Wi‑Fi, mô tả cho thấy đây là máy chiếu Home Cinema dùng chiếu phim gia đình với Android TV tích hợp, không được thiết kế chuyên dùng cho hệ thống máy xử lý dữ liệu tự động. Do đó, không đáp ứng tiêu chí của phân nhóm 8528.62. Vì vậy, phân nhóm phù hợp nhất là 8528.69 – Loại khác.","source_pages":[1,3],"subheading_id":"8528.69","subheading_title":"-- Loại khác."},"task_id":"8f40ee6a-f7cb-4fa3-acc8-e60b5d5590be"}},"row_index":1,"status":"completed"}],"job_id":"bb0e8400-e29b-41d4-a716-446655440006","processed_rows":50,"status":"completed","total_rows":50}},"CancelReasonCode":{"type":"string","enum":["upload_wrong_file","change_scope","need_other_module","wrong_timing","other"],"title":"CancelReasonCode","description":"User cancel reason — 5 enumerated values (BR-016, IC-m-002).\n\nPhase 16 S3.4 replaces the 1-5 magic int. DB column migrated from\nSmallInteger → VARCHAR(32) via in-place edit of Alembic 0001_baseline\n(Q-PH16-01 user override 2026-05-09 — pre-release, no ALTER needed).\nService `request_cancel_service` checks `== CancelReasonCode.other`\ninstead of `== 5` for the conditional `reason_text` requirement."},"CancelRequest":{"properties":{"reason_code":{"$ref":"#/components/schemas/CancelReasonCode","description":"Reason enum (upload_wrong_file / change_scope / need_other_module / wrong_timing / other). Phase 16 S3.4 replaced int 1-5 magic.","examples":["other"]},"reason_text":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Reason Text","description":"Required when reason_code='other'. Service-layer guard rejects empty when code=other.","examples":["Upload nhầm file ECUS tháng 4 thay vì tháng 5; gửi lại bằng request mới."]}},"additionalProperties":false,"type":"object","required":["reason_code"],"title":"CancelRequest"},"ChangePasswordRequest":{"properties":{"current":{"type":"string","maxLength":200,"minLength":1,"title":"Current","description":"Current plaintext password. Mismatch returns 401 invalid_credentials.","examples":["P@ssw0rd123!"]},"new":{"type":"string","maxLength":200,"minLength":1,"title":"New","description":"New plaintext password. Server bcrypt-hashes; subsequent logins require this value.","examples":["NewP@ssw0rd456!"]}},"additionalProperties":false,"type":"object","required":["current","new"],"title":"ChangePasswordRequest"},"ChcModule":{"type":"string","enum":["item_code_generator","tariff_classification","customs_valuation","non_tariff_measures","exim_statistics"],"title":"ChcModule","description":"5 CHC service modules — single source of truth (BR-009).\n\nPhase 16 S3.3 consolidates two duplicate frozensets that previously\nlived in `app/admin/schemas/experts.py` (`_CHC_MODULES`) and\n`app/user/schemas/request.py` (`MODULES_5SET`). Pydantic v2 enum\nvalidation replaces the manual `model_post_init` checks."},"CompanyResponse":{"properties":{"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"company_tax_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Tax Id"},"company_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Address"},"company_industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Industry"},"company_type":{"anyOf":[{"$ref":"#/components/schemas/CompanyType"},{"type":"null"}]}},"type":"object","title":"CompanyResponse","description":"``GET /api/user/settings/company`` — full company snapshot.","example":{"company_address":"123 Nguyễn Huệ, P. Bến Nghé, Q.1, TP.HCM","company_industry":"Sản xuất linh kiện điện tử","company_name":"Công ty TNHH Acme Việt Nam","company_tax_id":"0312345678","company_type":"san_xuat"}},"CompanyStep":{"properties":{"company_name":{"type":"string","maxLength":300,"minLength":1,"title":"Company Name","description":"Tên công ty pháp lý.","examples":["Công ty TNHH Acme Việt Nam"]},"company_tax_id":{"type":"string","pattern":"^[0-9]{10,13}$","title":"Company Tax Id","description":"Mã số thuế VN (10-13 ký số). Immutable post-set (BR-008) — service-level guard 409 mst_immutable_post_set.","examples":["0312345678"]},"company_type":{"$ref":"#/components/schemas/CompanyType","description":"Phân khúc hoạt động DN theo nghiệp vụ hải quan (fdi / xnk / epe / kcn_kkt / san_xuat / thuong_mai / dai_ly_logistics / khac).","examples":["san_xuat"]},"company_address":{"type":"string","minLength":1,"title":"Company Address","description":"Địa chỉ đăng ký kinh doanh.","examples":["123 Nguyễn Huệ, P. Bến Nghé, Q.1, TP.HCM"]},"company_industry":{"type":"string","maxLength":200,"minLength":1,"title":"Company Industry","description":"Ngành nghề kinh doanh chính.","examples":["Sản xuất linh kiện điện tử"]}},"additionalProperties":false,"type":"object","required":["company_name","company_tax_id","company_type","company_address","company_industry"],"title":"CompanyStep","description":"``POST /api/user/onboarding/company`` body — 5 required fields.\n\nUC-ONBD-002 step 1: tất cả 5 trường bắt buộc, không có ``name``.\nBR-008: MST regex enforced here; immutability enforced in service."},"CompanyType":{"type":"string","enum":["fdi","xnk","epe","kcn_kkt","san_xuat","thuong_mai","dai_ly_logistics","khac"],"title":"CompanyType"},"CompanyUpdate":{"properties":{"company_name":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Company Name","description":"Updated company legal name. Null = no change.","examples":["Công ty TNHH Acme Việt Nam"]},"company_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Address","description":"Updated registered address. Null = no change.","examples":["123 Nguyễn Huệ, P. Bến Nghé, Q.1, TP.HCM"]},"company_industry":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Company Industry","description":"Updated business industry/sector. Null = no change.","examples":["Sản xuất linh kiện điện tử"]},"company_type":{"anyOf":[{"$ref":"#/components/schemas/CompanyType"},{"type":"null"}],"description":"Updated company business segmentation (fdi / xnk / epe / kcn_kkt / san_xuat / thuong_mai / dai_ly_logistics / khac per VN-customs domain). Null = no change.","examples":["san_xuat"]}},"additionalProperties":false,"type":"object","title":"CompanyUpdate","description":"``PUT /api/user/settings/company`` partial body.\n\nBR-008 immutable post-onboarding — ``company_tax_id`` deliberately\nabsent. ``extra='forbid'`` turns any attempt to PATCH MST into a\n422 at the schema boundary, no service-layer guard needed."},"ConfirmResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"code":{"type":"string","title":"Code"},"status":{"type":"string","title":"Status"},"sla_due_at":{"type":"string","format":"date-time","title":"Sla Due At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","code","status","sla_due_at","created_at"],"title":"ConfirmResponse","example":{"code":"REQ-2026-000123","created_at":"2026-05-09T10:15:00+07:00","id":"770e8400-e29b-41d4-a716-446655440002","sla_due_at":"2026-05-12T17:00:00+07:00","status":"pending"}},"ContactStep":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name","description":"Optional người liên hệ. COALESCE service-side (overwrite users.name when present).","examples":["Trần Thị B"]},"phone":{"type":"string","maxLength":30,"minLength":1,"title":"Phone","description":"VN phone số liên hệ.","examples":["0901234567"]},"email_contact":{"type":"string","maxLength":320,"minLength":3,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$","title":"Email Contact","description":"Email liên hệ (mutable, có thể khác email_login).","examples":["contact@acme-corp.vn"]},"email_result":{"type":"string","maxLength":320,"minLength":3,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$","title":"Email Result","description":"Email nhận kết quả request (mutable, có thể là shared corporate inbox).","examples":["result@acme-corp.vn"]}},"additionalProperties":false,"type":"object","required":["phone","email_contact","email_result"],"title":"ContactStep","description":"``POST /api/user/onboarding/contact`` body — 3 required + name?.\n\nUC-ONBD-003 step 5 + biz-summary §2.2: ``name`` (Người liên hệ)\noptional, COALESCE service-side. ``email_login`` deliberately absent\n(BR-007 immutable) — ``extra='forbid'`` rejects any attempt with 422."},"DisplayStatus":{"type":"string","enum":["receiving","processing","completed","delivered","cancelled"],"title":"DisplayStatus"},"EtariffLookupStatus":{"type":"string","enum":["pending","processing","completed","failed"],"title":"EtariffLookupStatus","description":"Phase 11.5 — Manual lookup async lifecycle (UC-ET-002 v2).\n\nManual mode flow: ``pending`` (POST handler INSERT) → ``processing``\n(Celery task pickup) → ``completed`` (chain success) / ``failed``\n(chain hard-fail). Batch mode rows are inserted directly as\n``completed`` (or carry the legacy ``_status`` marker in result_json\nfor skipped_quota/failed per IC-M-008 — predates this enum)."},"EtariffMode":{"type":"string","enum":["manual","batch"],"title":"EtariffMode"},"FileDownloadResponse":{"properties":{"url":{"type":"string","title":"Url"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"popup_rating_eligible":{"type":"boolean","title":"Popup Rating Eligible","default":false}},"type":"object","required":["url","expires_at"],"title":"FileDownloadResponse","example":{"expires_at":"2026-05-09T22:30:00+07:00","popup_rating_eligible":true,"url":"https://chc-private.s3.amazonaws.com/wp_final/770e8400.../wp-final-2026-05-09.xlsx?X-Amz-Algorithm=..."}},"FileSummary":{"properties":{"kind":{"type":"string","title":"Kind"},"filename":{"type":"string","title":"Filename"},"size_bytes":{"type":"integer","title":"Size Bytes"},"uploaded_at":{"type":"string","format":"date-time","title":"Uploaded At"}},"type":"object","required":["kind","filename","size_bytes","uploaded_at"],"title":"FileSummary"},"ForgotRequest":{"properties":{"email":{"type":"string","maxLength":320,"minLength":3,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$","title":"Email","description":"Account email. Server returns 202 generic regardless of existence (anti-enumeration).","examples":["user@example.com"]}},"additionalProperties":false,"type":"object","required":["email"],"title":"ForgotRequest"},"GenericAccepted":{"properties":{"detail":{"type":"string","title":"Detail","default":"if_email_exists_link_sent"}},"type":"object","title":"GenericAccepted","description":"Anti-enumeration response for ``/auth/forgot``.","example":{"detail":"if_email_exists_link_sent"}},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HistoryItem":{"properties":{"lookup_id":{"type":"string","format":"uuid","title":"Lookup Id"},"mode":{"type":"string","title":"Mode"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"input_json_summary":{"additionalProperties":true,"type":"object","title":"Input Json Summary"},"has_result":{"type":"boolean","title":"Has Result"}},"type":"object","required":["lookup_id","mode","created_at","input_json_summary","has_result"],"title":"HistoryItem"},"HistoryResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/HistoryItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["items","total","page","page_size","total_pages"],"title":"HistoryResponse","example":{"items":[{"created_at":"2026-05-09T16:57:00+07:00","has_result":true,"input_json_summary":{"commodity_name":"Điện thoại di động thông minh"},"lookup_id":"770e8400-e29b-41d4-a716-446655440002","mode":"manual"}],"page":1,"page_size":20,"total":1,"total_pages":1}},"LanguageCode":{"type":"string","enum":["vi","en","ko","zh"],"title":"LanguageCode"},"LanguageUpdate":{"properties":{"language":{"$ref":"#/components/schemas/LanguageCode","description":"4-locale enum (vi / en / ko / zh) — BR-032. Admin pool VI-only at runtime; user pool free choice.","examples":["vi"]}},"additionalProperties":false,"type":"object","required":["language"],"title":"LanguageUpdate","description":"``PUT /api/{admin,user}/settings/language`` body."},"LoginRequest":{"properties":{"email":{"type":"string","maxLength":320,"minLength":3,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$","title":"Email","description":"Login email (case-insensitive). Pool resolution: admin pool tries first, user pool fallback (per Phase 03 baseline).","examples":["user@example.com"]},"password":{"type":"string","maxLength":200,"minLength":1,"title":"Password","description":"Plaintext password — bcrypt verified server-side. Lockout after 5 failures within 15 min (P7).","examples":["P@ssw0rd123!"]},"remember_me":{"type":"boolean","title":"Remember Me","description":"Reserved for FE preference; server still issues 3-day access + 7-day refresh regardless (override 2026-05-03).","default":false,"examples":[false]}},"additionalProperties":false,"type":"object","required":["email","password"],"title":"LoginRequest","description":"Body of ``POST /api/{user,admin}/auth/login``."},"LoginResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"role":{"type":"string","title":"Role"},"force_password_change":{"type":"boolean","title":"Force Password Change"}},"type":"object","required":["access_token","refresh_token","role","force_password_change"],"title":"LoginResponse","example":{"access_token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJyb2xlIjoidGVuYW50X2FkbWluIn0.signature","force_password_change":false,"refresh_token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJqdGkiOiI4ODBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDMifQ.signature","role":"tenant_admin","token_type":"bearer"}},"ManualLookupBody":{"properties":{"commodity_name":{"type":"string","maxLength":2000,"minLength":1,"title":"Commodity Name","description":"Required (FSD §5.7 4-required). Tên thương phẩm.","examples":["Điện thoại di động thông minh"]},"commodity_description":{"type":"string","maxLength":2000,"minLength":1,"title":"Commodity Description","description":"Required. Mô tả chi tiết hàng hoá.","examples":["Smartphone hỗ trợ 5G, màn hình OLED 6.7 inch, RAM 12GB"]},"function_use":{"type":"string","maxLength":2000,"minLength":1,"title":"Function Use","description":"Required. Công dụng / mục đích sử dụng.","examples":["Liên lạc thoại + dữ liệu di động"]},"material_composition":{"type":"string","maxLength":2000,"minLength":1,"title":"Material Composition","description":"Required. Vật liệu / thành phần cấu thành.","examples":["Nhôm + kính cường lực + nhựa polycarbonate + vi mạch silicon"]},"scientific_name":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Scientific Name","description":"Optional. Tên khoa học (chemical/biological).","examples":["N/A — sản phẩm công nghiệp"]},"structure_components":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Structure Components","description":"Optional. Cấu trúc / thành phần kỹ thuật.","examples":["Bộ vi xử lý A17 Pro + module camera 48MP + pin lithium-polymer 3274 mAh"]},"technical_specification":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Technical Specification","description":"Optional. Quy cách kỹ thuật.","examples":["IP68, sạc nhanh 27W, USB-C, Wi-Fi 6E"]},"additional_info":{"items":{"$ref":"#/components/schemas/AdditionalInfoEntry"},"type":"array","maxItems":20,"title":"Additional Info","description":"Dynamic field array (G-C-003). Max 20 entries. Server forwards verbatim to AI provider.","examples":[[{"label":"Xuất xứ","value":"Việt Nam"},{"label":"Hãng SX","value":"Apple"}]]}},"additionalProperties":false,"type":"object","required":["commodity_name","commodity_description","function_use","material_composition"],"title":"ManualLookupBody"},"ManualLookupResponse":{"properties":{"lookup_id":{"type":"string","format":"uuid","title":"Lookup Id"},"status":{"$ref":"#/components/schemas/EtariffLookupStatus","description":"Lifecycle state right after the POST. Always `pending` for a fresh lookup — the Celery worker flips to `processing` then `completed`/`failed`. Poll the GET status endpoint for the terminal value.","examples":["pending"]}},"type":"object","required":["lookup_id","status"],"title":"ManualLookupResponse","description":"Manual E-Tariff lookup acknowledgement (Phase 11.5 v2 — async).\n\nPOST returns 202 with ``{lookup_id, status='pending'}``; FE polls\n``GET /api/user/etariff/manual/{lookup_id}`` until status is\nterminal (``completed`` or ``failed``). Lookup row is created\nsynchronously in the POST handler (DB row + quota consume) so the\npolling endpoint always finds it. ``result_json`` lives only on\n:class:`ManualLookupStatusResponse`.","example":{"lookup_id":"770e8400-e29b-41d4-a716-446655440002","status":"pending"}},"ManualLookupStatusResponse":{"properties":{"lookup_id":{"type":"string","format":"uuid","title":"Lookup Id"},"status":{"$ref":"#/components/schemas/EtariffLookupStatus","description":"Async lifecycle: `pending` → `processing` → `completed` (with `result_json`) or `failed` (with `error_message`). FE polls every 2-3s until `completed`/`failed`.","examples":["completed"]},"result_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Result Json","description":"4-tab UI contract (FSD §5.7): `ai_conclusion`, `wco_hs_notes`, `wco_compendium`, `sen_ahtn`. Populated only when `status == 'completed'`."},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message","description":"Human-readable failure reason. Populated only when `status == 'failed'` (e.g. provider auth fail, timeout, upstream 5xx). Quota auto-rolled-back on failure."}},"type":"object","required":["lookup_id","status"],"title":"ManualLookupStatusResponse","description":"Polling endpoint payload for ``GET /api/user/etariff/manual/{lookup_id}``.\n\n``result_json`` populated only when ``status == 'completed'`` (4-tab\nUI contract — same shape as Phase 13). ``error_message`` populated\nonly when ``status == 'failed'`` so FE can show a toast without\nwaiting for retry. Both null while ``status`` is in\n``pending`` / ``processing``.","example":{"lookup_id":"770e8400-e29b-41d4-a716-446655440002","result_json":{"ai_conclusion":{"analysis_summary":"Máy chiếu DLP gia đình 4K UHD có bản chất là máy chiếu video thuộc heading 8528, Section XVI, Chapter 85. Các mã thuộc nhóm thiết bị ghi âm, ghi hình, máy biến áp hoặc đồ chơi đều không phù hợp với chức năng chính của sản phẩm. Trong danh sách, mã 8528.52 là phù hợp nhất để phân loại mặt hàng này.","product_name":"Máy chiếu DLP gia đình","recommended_hs_code":"8528.52","results":[{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.95,"hs_code":"8528.52","hs_code_description":"Màn hình và máy chiếu, không kết hợp với thiết bị thu truyền hình; máy chiếu video","number_of_occurrences":5,"reason":"Mã 8528.52 thuộc nhóm 8528 bao gồm màn hình và máy chiếu, không kết hợp với thiết bị thu truyền hình; loại có khả năng kết nối trực tiếp và được thiết kế chủ yếu để sử dụng với máy xử lý dữ liệu tự động. Máy chiếu DLP gia đình là thiết bị chiếu hình ảnh video, đúng bản chất là “video projector” thuộc heading 8528. Sản phẩm có cổng HDMI, xử lý hình ảnh 4K và chức năng trình chiếu, hoàn toàn phù hợp với phạm vi máy chiếu của nhóm này. Đây là nhóm mã HS phổ biến và phù hợp nhất cho máy chiếu video gia đình.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.9,"hs_code":"8528.69","hs_code_description":"Máy chiếu khác","number_of_occurrences":1,"reason":"Mã 8528.69 thuộc phân nhóm máy chiếu khác trong heading 8528. Máy chiếu DLP gia đình 4K UHD là thiết bị chiếu video kỹ thuật số, phù hợp trực tiếp với mô tả này. Sản phẩm không phải màn hình đơn thuần mà là máy chiếu hình ảnh lên bề mặt ngoài. Do đó đây là mã rất phù hợp, chỉ xếp sau 8528.52 nếu xét phân nhóm chi tiết hơn theo cấu hình kết nối.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.85,"hs_code":"8528","hs_code_description":"Màn hình và máy chiếu, có hoặc không kết hợp với thiết bị thu truyền hình","number_of_occurrences":1,"reason":"Nhóm 8528 bao gồm màn hình và máy chiếu, có hoặc không kết hợp thiết bị thu truyền hình. Máy chiếu DLP gia đình thuộc đúng phạm vi chung của heading này về mặt chức năng và bản chất hàng hóa. Tuy nhiên, đây chỉ là mã 4 số (heading) chưa thể hiện phân nhóm cụ thể theo yêu cầu phân loại chi tiết. Do đó phù hợp cao nhưng chưa phải mã đầy đủ tối ưu để khai báo.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.05,"hs_code":"8504.31.30","hs_code_description":"Máy biến áp khác, công suất không quá 1 kVA","number_of_occurrences":1,"reason":"Mã 8504.31.30 thuộc nhóm máy biến áp công suất không quá 1 kVA. Máy chiếu DLP không phải là máy biến áp mà là thiết bị điện tử dùng để xử lý và chiếu hình ảnh. Mặc dù bên trong có thể có bộ nguồn hoặc biến áp, nhưng theo GRI 1 và chú giải phần XVI, không phân loại theo bộ phận phụ mà theo chức năng chính của toàn bộ thiết bị. Vì vậy mã này hoàn toàn không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.05,"hs_code":"8521.90.11","hs_code_description":"Thiết bị ghi hoặc tái tạo video khác","number_of_occurrences":1,"reason":"Mã 8521.90.11 thuộc nhóm thiết bị ghi hoặc tái tạo video khác (ví dụ đầu đĩa DVD, Blu-ray). Máy chiếu có thể tích hợp Android TV nhưng không phải thiết bị ghi/tái tạo video độc lập mà là thiết bị hiển thị. Theo nguyên tắc phân loại theo chức năng chính, sản phẩm không thuộc heading 8521. Do đó mức độ phù hợp rất thấp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.05,"hs_code":"8521.90.91","hs_code_description":"Thiết bị ghi hoặc tái tạo video khác, loại khác","number_of_occurrences":1,"reason":"Tương tự các mã 8521 khác, 8521.90.91 áp dụng cho thiết bị ghi hoặc tái tạo video. Máy chiếu DLP không thực hiện chức năng ghi hoặc phát lại nội dung từ phương tiện lưu trữ theo nghĩa của heading này. Chức năng chính vẫn là chiếu hình ảnh nhận từ nguồn tín hiệu. Vì vậy mã này không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.02,"hs_code":"8519.81.71","hs_code_description":"Thiết bị ghi hoặc tái tạo âm thanh khác","number_of_occurrences":1,"reason":"Mã 8519.81.71 thuộc nhóm thiết bị ghi hoặc tái tạo âm thanh (ví dụ đầu đĩa, thiết bị phát nhạc). Máy chiếu DLP có thể có loa tích hợp nhưng chức năng chính không phải ghi hoặc phát âm thanh độc lập. Bản chất hàng hóa là thiết bị chiếu hình ảnh video, không phải thiết bị âm thanh chuyên dụng. Do đó mã này không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 85 - Máy điện và thiết bị điện và các bộ phận của chúng","compatibility_score":0.01,"hs_code":"8521.10.10","hs_code_description":"Thiết bị ghi hoặc tái tạo video dùng băng từ","number_of_occurrences":1,"reason":"Mã 8521.10.10 thuộc nhóm thiết bị ghi hoặc tái tạo video sử dụng băng từ (ví dụ đầu video cassette). Máy chiếu DLP không có chức năng ghi hoặc phát lại từ băng từ hay phương tiện lưu trữ độc lập như mô tả. Chức năng chính là nhận tín hiệu và chiếu hình ảnh lên màn chiếu. Vì vậy mã này hoàn toàn không phù hợp.","section_info":"Section XVI - Máy và thiết bị cơ khí; thiết bị điện; các bộ phận của chúng"},{"chapter_info":"Chapter 95 - Đồ chơi, dụng cụ thể thao và các sản phẩm giải trí","compatibility_score":0.0,"hs_code":"9503.00.80","hs_code_description":"Đồ chơi khác","number_of_occurrences":1,"reason":"Mã 9503.00.80 thuộc nhóm đồ chơi và các sản phẩm giải trí cho trẻ em. Máy chiếu DLP gia đình là thiết bị điện tử cao cấp dùng cho giải trí và trình chiếu, không phải đồ chơi. Về bản chất kỹ thuật, cấu tạo và giá trị, sản phẩm thuộc nhóm thiết bị điện tử nghe nhìn chứ không phải hàng hóa thuộc Chương 95. Vì vậy hoàn toàn không phù hợp.","section_info":"Section XX - Hàng hóa và sản phẩm khác"}],"total_hs_codes_analyzed":9},"sen_ahtn":[{"content_of_citation":"\"THIẾT BỊ GHI HOẶC TÁI TẠO VIDEO, LOẠI DÙNG CHO ĐIỆN ẢNH HOẶC PHÁT THANH TRUYỀN HÌNH... được thiết kế chuyên dụng cho công nghệ phát thanh truyền hình hoặc điện ảnh, không dùng cho gia dụng.\"","metadata":{"chapter":"85","heading":"85.21","source_pages":[393,394],"title":"Thiết bị ghi hoặc tái tạo video dùng cho điện ảnh hoặc phát thanh truyền hình"},"reason":"Có liên quan đến thiết bị xử lý/tái tạo video thuộc Chương 85, tuy nhiên mô tả chỉ áp dụng cho thiết bị ghi hoặc tái tạo video chuyên dụng cho điện ảnh hoặc phát thanh truyền hình, không phải máy chiếu gia đình.","subheading_ids":["8521.90.11","8521.90.91","8521.10.10"]},{"content_of_citation":"\"MÁY BIẾN ÁP QUÉT VỀ... được sử dụng trong thiết bị thu truyền hình để cung cấp điện áp hồi lưu...\"","metadata":{"chapter":"85","heading":"85.04","source_pages":[385,386],"title":"Máy biến áp quét về (biến áp tần số quét ngược)"},"reason":"Là mã cho biến áp quét về dùng trong thiết bị thu truyền hình. Máy chiếu DLP có linh kiện điện tử và mạch xử lý nhưng bản chất không phải là biến áp hay linh kiện rời.","subheading_ids":["8504.31.30"]},{"content_of_citation":"\"THIẾT BỊ TÁI TẠO ÂM THANH KHÁC, KIỂU CASSETTE, LOẠI DÙNG CHO ĐIỆN ẢNH HOẶC PHÁT THANH...\"","metadata":{"chapter":"85","heading":"85.19","source_pages":[392,393],"title":"Thiết bị tái tạo âm thanh kiểu cassette dùng cho điện ảnh hoặc phát thanh"},"reason":"Là thiết bị tái tạo âm thanh kiểu cassette chuyên dùng cho điện ảnh hoặc phát thanh; không phù hợp vì sản phẩm là máy chiếu hình ảnh, không phải thiết bị âm thanh cassette.","subheading_ids":["8519.81.71"]},{"content_of_citation":"\"THIẾT BỊ GIÁO DỤC ĐIỆN TỬ TƯƠNG TÁC CẦM TAY ĐƯỢC THIẾT KẾ CHỦ YẾU CHO TRẺ EM...\"","metadata":{"chapter":"95","heading":"95.03","source_pages":[438,439,440],"title":"Thiết bị giáo dục điện tử tương tác cầm tay cho trẻ em"},"reason":"Là thiết bị giáo dục điện tử cầm tay cho trẻ em; không phù hợp vì máy chiếu DLP là thiết bị trình chiếu gia đình, không phải đồ chơi hay thiết bị giáo dục tương tác cầm tay.","subheading_ids":["9503.00.80"]}],"wco_compendium":[{"content_of_citation":"“Colour monitor comprising ... TFT LCD ... combined in the same housing with control circuitry... one HDMI connector... Resolution ... Application of GIRs 1 and 6.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[351]},"reason":"Sản phẩm là máy chiếu (projector) dùng để hiển thị hình ảnh 4K UHD, thuộc nhóm thiết bị hiển thị hình ảnh của Chương 85, nhóm 8528. Mặc dù các tiền lệ 8528.52 mô tả màn hình TFT LCD, nhưng chúng cùng bản chất là thiết bị hiển thị hình ảnh màu, có cổng HDMI và mạch điều khiển tích hợp. Máy chiếu DLP có chức năng tương tự là nhận tín hiệu HDMI và hiển thị hình ảnh.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor ... capable of directly connecting ... via one VGA or two HDMI connectors... Resolution : 1920 x 1080.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[352]},"reason":"Tiền lệ mô tả màn hình màu có khả năng kết nối HDMI/VGA và hiển thị độ phân giải cao. Máy chiếu DLP 4K UHD (3840x2160), 3000 lumens, HDMI 2.1, Wi‑Fi 6 có bản chất là thiết bị hiển thị hình ảnh màu từ nguồn tín hiệu số, tương đồng về chức năng nhận và xử lý tín hiệu hình ảnh.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor comprising ... TFT LCD active-matrix panel combined in the same housing with control circuitry... DVI-D ... VGA ... Resolution (max) ... Application of GIRs 1 and 6.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[347,573,574,691,692]},"reason":"Các tiền lệ 8528.52 đều nhấn mạnh bản chất là thiết bị hiển thị màu tích hợp mạch điều khiển và các cổng tín hiệu số. Máy chiếu DLP sử dụng chip DLP + bo mạch xử lý hình ảnh + cổng HDMI 2.1, phù hợp với nhóm thiết bị hiển thị hình ảnh thuộc 8528.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor ... one HDMI (High-Definition Multimedia Interface) connector... Supports High-bandwidth Digital Content Protection (HDCP)... Resolution (max) : 1920 x 1200.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[351]},"reason":"Tiền lệ mô tả màn hình có HDMI, Audio-In, hỗ trợ HDCP – là các tính năng nhận tín hiệu đa phương tiện tương tự máy chiếu gia đình. Máy chiếu có Android TV và Wi‑Fi 6 mở rộng chức năng nhưng không làm thay đổi bản chất là thiết bị hiển thị hình ảnh.","subheading_ids":["8528.52"]},{"content_of_citation":"“Colour monitor ... Resolution (max) : 1280 x 1024 ... Brightness : 250 cd/m2; Contrast ratio : 1000:1... Application of GIRs 1 and 6.”","metadata":{"chapter":"85","heading":"85.28","source_pages":[349]},"reason":"Tiền lệ 8528.52 mô tả màn hình màu với thông số độ sáng, độ phân giải và mạch điều khiển tích hợp. Máy chiếu DLP 4K UHD có thông số độ phân giải cao hơn và độ sáng 3000 lumens, nhưng vẫn cùng bản chất là thiết bị hiển thị hình ảnh màu thuộc nhóm 8528.","subheading_ids":["8528.52"]}],"wco_hs_notes":{"cache_hit":false,"chapter_classification":{"chapter_id":"85","chapter_title":"Chương 85: Máy điện và thiết bị điện và các bộ phận của chúng; máy ghi và tái tạo âm thanh, máy ghi và tái tạo hình ảnh và âm thanh truyền hình, bộ phận và phụ kiện của các loại máy trên","content_of_explanatory_notes":"Chú giải 6(D) Chương 84 quy định rằng nhóm 84.71 không bao gồm “màn hình và máy chiếu, không kết hợp thiết bị thu truyền hình”, ngay cả khi đáp ứng các điều kiện của máy xử lý dữ liệu tự động. Khái quát chung Chương 85 nêu rõ Chương này bao gồm tất cả các máy móc và thiết bị điện, ngoại trừ các loại đã được mô tả tại Chương 84; đồng thời bao gồm các thiết bị ghi hoặc tái tạo hình ảnh và các thiết bị điện hoạt động phụ thuộc vào đặc tính của điện.","file_name":"Section XVI - Chapter 85","file_path":"Section XVI/Chapter 85","gri_usage":["1"],"reason":"Trước hết, loại trừ Chương 84 vì theo Chú giải 6(D) Chương 84, “màn hình và máy chiếu, không kết hợp thiết bị thu truyền hình” không thuộc nhóm 84.71 ngay cả khi đáp ứng điều kiện của máy xử lý dữ liệu tự động. Sản phẩm là máy chiếu DLP hoàn chỉnh, hoạt động bằng điện, có chức năng chính là chiếu hình ảnh 4K UHD, do đó bản chất là thiết bị điện theo chức năng (Loại B – hàng hóa theo công dụng). Theo GRI 1, việc phân loại phải dựa trên nội dung tiêu đề Chương và các Chú giải pháp lý liên quan. Chương 85 bao gồm tất cả các máy móc và thiết bị điện, trừ những loại đã được mô tả cụ thể tại Chương 84. Vì máy chiếu không thuộc các nhóm chức năng cơ khí của Chương 84 và bị loại khỏi 84.71 theo Chú giải 6(D), nên phù hợp với phạm vi Chương 85. Do đó, xét theo tiêu đề và chú giải pháp lý, Chương 85 là chương phù hợp nhất cho sản phẩm này.","source_pages":[3,7,8]},"heading_classification":{"content_of_explanatory_notes":"Khái quát chung của nhóm 85.28 nêu rõ nhóm này bao gồm: (1) Màn hình và máy chiếu, không gắn với thiết bị thu sóng truyền hình; (2) Máy thu truyền hình có hoặc không gắn thiết bị khác. Phần (C) quy định “Máy chiếu cho phép các hình ảnh được tái tạo… chiếu trên một bề mặt bên ngoài” và có thể dựa trên các công nghệ như LCD, DMD (Digital Micromirror Device – nền tảng của DLP) hoặc công nghệ tương tự. Điều này phù hợp trực tiếp với máy chiếu DLP 4K UHD dùng để chiếu hình ảnh ra màn chiếu trong gia đình.","gri_usage":["1"],"heading_id":"85.28","heading_title":"Màn hình và máy chiếu, không gắn với thiết bị thu dùng trong truyền hình; thiết bị thu dùng trong truyền hình, có hoặc không gắn với máy thu thanh sóng vô tuyến hoặc thiết bị ghi hoặc tái tạo âm thanh hoặc hình ảnh.","reason":"Sản phẩm được mô tả là “Máy chiếu DLP gia đình – Home Cinema 4K UHD”, có chức năng chiếu phim và trình chiếu trong gia đình. Xét về bản chất, đây là một thiết bị hoàn chỉnh hoạt động bằng điện, có chức năng chính là chiếu hình ảnh ra bề mặt bên ngoài thông qua công nghệ DLP, đèn LED và hệ thống xử lý hình ảnh – tức là một máy chiếu video. Theo GRI 1, việc phân loại được thực hiện dựa trên nội dung của các Heading và Chú giải liên quan. Đối chiếu các nhóm trong Chương 85, nhóm 85.28 mô tả rõ “Màn hình và máy chiếu, không gắn với thiết bị thu dùng trong truyền hình”, phù hợp trực tiếp với chức năng cốt lõi của hàng hóa. Sản phẩm không phải là thiết bị ghi hoặc tái tạo video (loại trừ nhóm 85.21), cũng không phải thiết bị phát sóng hay camera (loại trừ nhóm 85.25). Không có Chú giải loại trừ nào của nhóm 85.28 áp dụng cho máy chiếu gia đình độc lập như mô tả. Do đó, nhóm 85.28 là nhóm phù hợp và mô tả chính xác nhất bản chất hàng hóa.","source_pages":[1,2,3,4]},"pre_classification":{"candidate_section_ids":["XVI","XVIII","VII"],"reasoning":"Rerank scores: ['0.6646', '0.5212', '0.3013']"},"section_classification":{"content_of_explanatory_notes":"Phần XVI bao gồm tất cả các loại máy móc hoặc thiết bị cơ khí hoặc điện, trừ khi được nêu đặc biệt trong các Phần khác. Theo Chú giải 1 Phần XVI, Phần này không bao gồm các sản phẩm đã được quy định cụ thể tại các Phần khác như Phần XVII, XVIII, Chương 90, 91… Khái quát chung cũng nêu rõ máy móc chưa hoàn chỉnh hoặc tháo rời vẫn được phân loại như máy hoàn chỉnh nếu có đặc trưng cơ bản của máy đó. Phần này bao gồm thiết bị điện và các thiết bị ghi, tái tạo hình ảnh và âm thanh truyền hình.","file_name":"N/A","file_path":"N/A","gri_usage":["1"],"product_analysis":"- <strong>Bản chất hàng hoá:</strong> Là một thiết bị điện tử hoàn chỉnh (máy chiếu DLP) dùng để trình chiếu hình ảnh 4K UHD, thuộc nhóm máy móc – thiết bị điện.\n- <strong>Loại hàng hoá liên quan:</strong> Là thiết bị trình chiếu hình ảnh (video projector) sử dụng công nghệ DLP, tích hợp chip xử lý hình ảnh, đèn LED, cổng HDMI, Wi‑Fi và hệ điều hành Android TV.\n- <strong>Công dụng chung:</strong> Không phải là bộ phận có công dụng chung; đây là một máy hoàn chỉnh có chức năng xác định là chiếu phim và trình chiếu hình ảnh trong gia đình.\n- <strong>Tình trạng hàng hoá:</strong> Hàng hóa hoàn chỉnh, đã lắp ráp đầy đủ các bộ phận cấu thành (chip DLP, bo mạch, ống kính, nguồn sáng LED) và sẵn sàng sử dụng.","reason":"Trước hết, loại trừ Section VII vì mặc dù sản phẩm có vỏ nhựa ABS, nhưng Chú giải loại trừ của Chương 39 nêu rõ không bao gồm các mặt hàng thuộc Phần XVI (máy và thiết bị cơ khí hoặc điện). Máy chiếu là một thiết bị điện tử hoàn chỉnh, không phải sản phẩm được phân loại theo vật liệu cấu thành, do đó không phù hợp với bản chất của Section VII. Tiếp theo, xem xét Section XVIII (Chương 90) về dụng cụ quang học; tuy nhiên, Chương 90 chủ yếu bao gồm các thiết bị có tính chính xác cao dùng cho mục đích khoa học, kỹ thuật, đo lường hoặc y tế, trong khi máy chiếu gia đình là thiết bị điện tử nghe nhìn phục vụ giải trí. Theo GRI 1, việc phân loại phải dựa trên nội dung tiêu đề Phần và các Chú giải pháp lý liên quan; Section XVI bao quát “thiết bị điện; thiết bị ghi và tái tạo hình ảnh, âm thanh truyền hình”, phù hợp trực tiếp với chức năng chiếu hình ảnh 4K UHD qua HDMI, Wi-Fi, Android TV. Máy chiếu DLP là một thiết bị điện hoàn chỉnh, tích hợp chip DLP, bo mạch xử lý hình ảnh và nguồn sáng LED để thực hiện chức năng hiển thị hình ảnh. Ngoài ra, Chú giải Phần XVI cũng quy định máy hoàn chỉnh hoặc tháo rời vẫn phân loại như máy hoàn chỉnh, càng củng cố việc xếp vào Phần này. Do đó, Section XVI là Phần phù hợp nhất với bản chất và chức năng cốt lõi của sản phẩm.","section_id":"XVI","section_title":"MÁY VÀ CÁC TRANG THIẾT BỊ CƠ KHÍ; THIẾT BỊ ĐIỆN; CÁC BỘ PHẬN CỦA CHÚNG; THIẾT BỊ GHI VÀ TÁI TẠO ÂM THANH, THIẾT BỊ GHI VÀ TÁI TẠO HÌNH ẢNH, ÂM THANH TRUYỀN HÌNH VÀ CÁC BỘ PHẬN VÀ PHỤ KIỆN CỦA CÁC THIẾT BỊ TRÊN","source_pages":[3,4]},"subheading_classification":{"content_of_explanatory_notes":"Phần (C) MÁY CHIẾU nêu rõ: Máy chiếu cho phép các hình ảnh được tái tạo bình thường trên màn ảnh của máy thu truyền hình hoặc của màn hình monitor được chiếu trên một bề mặt bên ngoài; chúng có thể dựa trên công nghệ CRT hoặc màn hình dẹt (ví dụ DMD, LCD, plasma). Ngoài ra, Khái quát chung cũng quy định rằng nếu màn hình hoặc máy chiếu có tích hợp bộ dò tín hiệu truyền hình thì được xem như thiết bị thu dùng trong truyền hình.","gri_usage":["1","6"],"reason":"Theo GRI 1, sản phẩm được xác định thuộc Nhóm 85.28 vì đây là máy chiếu sử dụng công nghệ DLP (DMD) để tái tạo và chiếu hình ảnh lên bề mặt bên ngoài, đúng với mô tả tại phần (C) MÁY CHIẾU trong Khái quát chung. Sản phẩm không phải là màn hình (monitor) vì không hiển thị trực tiếp trên một màn hình tích hợp, và cũng không phải là thiết bị thu dùng cho truyền hình do không có thông tin về bộ dò kênh (tuner) thu tín hiệu truyền hình. Áp dụng GRI 6 để phân loại ở cấp phân nhóm, trước hết tại cấp 1 gạch (-), hàng hóa phù hợp với phân nhóm “- Máy chiếu”. Tiếp theo, ở cấp 2 gạch (--), cần xem xét tiêu chí “có khả năng kết nối trực tiếp và được thiết kế để dùng cho máy xử lý dữ liệu tự động thuộc nhóm 84.71”. Mặc dù máy có cổng HDMI và Wi‑Fi, mô tả cho thấy đây là máy chiếu Home Cinema dùng chiếu phim gia đình với Android TV tích hợp, không được thiết kế chuyên dùng cho hệ thống máy xử lý dữ liệu tự động. Do đó, không đáp ứng tiêu chí của phân nhóm 8528.62. Vì vậy, phân nhóm phù hợp nhất là 8528.69 – Loại khác.","source_pages":[1,3],"subheading_id":"8528.69","subheading_title":"-- Loại khác."},"task_id":"8f40ee6a-f7cb-4fa3-acc8-e60b5d5590be"}},"status":"completed"}},"OnboardingCompanyData":{"properties":{"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"company_tax_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Tax Id"},"company_type":{"anyOf":[{"$ref":"#/components/schemas/CompanyType"},{"type":"null"}]},"company_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Address"},"company_industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Industry"}},"type":"object","title":"OnboardingCompanyData","description":"Saved company snapshot returned by ``GET /state``."},"OnboardingContactData":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"email_contact":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email Contact"},"email_result":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email Result"}},"type":"object","title":"OnboardingContactData","description":"Saved contact snapshot returned by ``GET /state``."},"OnboardingState":{"properties":{"step":{"type":"integer","enum":[0,1,2,3],"title":"Step"},"data":{"$ref":"#/components/schemas/OnboardingStateData"}},"type":"object","required":["step","data"],"title":"OnboardingState","description":"``GET /api/user/onboarding/state`` response.","example":{"data":{"company":{"company_address":"123 Nguyễn Huệ, P. Bến Nghé, Q.1, TP.HCM","company_industry":"Sản xuất linh kiện điện tử","company_name":"Công ty TNHH Acme Việt Nam","company_tax_id":"0312345678","company_type":"san_xuat"},"contact":{},"email_login":"user@example.com"},"step":2}},"OnboardingStateData":{"properties":{"company":{"$ref":"#/components/schemas/OnboardingCompanyData"},"contact":{"$ref":"#/components/schemas/OnboardingContactData"},"email_login":{"type":"string","title":"Email Login"}},"type":"object","required":["company","contact","email_login"],"title":"OnboardingStateData","description":"Composite ``data`` payload of ``GET /state``."},"ProfileUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name","description":"Updated display name. Null = no change.","examples":["Trần Thị B"]},"phone":{"anyOf":[{"type":"string","maxLength":30},{"type":"null"}],"title":"Phone","description":"Updated VN phone. Null = no change.","examples":["0901234567"]}},"additionalProperties":false,"type":"object","title":"ProfileUpdate","description":"``PUT /api/{admin,user}/settings/profile`` partial body.\n\nExcludes: ``email`` (immutable BR-007), ``password`` (use\n``/auth/change-password`` per IC-M-011), ``company_*`` (use\n``/settings/company`` for users, no admin equivalent)."},"QuotaStatusResponse":{"properties":{"used":{"type":"integer","title":"Used"},"limit":{"type":"integer","title":"Limit"},"remaining":{"type":"integer","title":"Remaining"},"reset_at":{"type":"string","title":"Reset At"}},"type":"object","required":["used","limit","remaining","reset_at"],"title":"QuotaStatusResponse","example":{"limit":100,"remaining":77,"reset_at":"2026-05-10T00:00:00+07:00","used":23}},"RateRequest":{"properties":{"stars":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Stars","description":"1-5 stars rating (BR-019). Single-shot — duplicate POST returns 409 already_rated.","examples":[5]},"comment":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Comment","description":"Optional free-text feedback shown to expert + admin.","examples":["Chuyên gia xử lý nhanh, kết quả chính xác, file Word trình bày rõ ràng."]}},"additionalProperties":false,"type":"object","required":["stars"],"title":"RateRequest"},"RatingReminderItem":{"properties":{"request_id":{"type":"string","format":"uuid","title":"Request Id"},"code":{"type":"string","title":"Code"}},"type":"object","required":["request_id","code"],"title":"RatingReminderItem"},"RefreshRequest":{"properties":{"refresh_token":{"type":"string","minLength":1,"title":"Refresh Token","description":"Opaque JWT refresh token from prior /auth/login. Server rotates: returns new refresh + blacklists the old jti (D9 rotation).","examples":["eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NTBlODQwMC0uLi4ifQ.signature"]}},"additionalProperties":false,"type":"object","required":["refresh_token"],"title":"RefreshRequest"},"RefreshResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"}},"type":"object","required":["access_token","refresh_token"],"title":"RefreshResponse","description":"Rotation D9: server always returns a new refresh alongside the access.","example":{"access_token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAifQ.new_access_signature","refresh_token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJqdGkiOiI5OTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDQifQ.new_refresh_signature","token_type":"bearer"}},"RequestDetail":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"code":{"type":"string","title":"Code"},"display_status":{"$ref":"#/components/schemas/DisplayStatus"},"sla_status":{"type":"string","title":"Sla Status"},"sla_due_at":{"type":"string","format":"date-time","title":"Sla Due At"},"has_downloaded":{"type":"boolean","title":"Has Downloaded"},"has_rated":{"type":"boolean","title":"Has Rated"},"rating_reminder_dismissed":{"type":"boolean","title":"Rating Reminder Dismissed"},"modules":{"items":{"$ref":"#/components/schemas/ChcModule"},"type":"array","title":"Modules"},"expert_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expert Name"},"files":{"items":{"$ref":"#/components/schemas/FileSummary"},"type":"array","title":"Files"},"rating_stars":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rating Stars"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"cancel_reason_code":{"anyOf":[{"$ref":"#/components/schemas/CancelReasonCode"},{"type":"null"}]},"cancel_reason_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cancel Reason Text"},"rating_comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rating Comment"}},"type":"object","required":["id","code","display_status","sla_status","sla_due_at","has_downloaded","has_rated","rating_reminder_dismissed","modules","created_at"],"title":"RequestDetail","example":{"code":"REQ-2026-000123","created_at":"2026-05-09T10:15:00+07:00","display_status":"completed","expert_name":"Lê Quang Phi","files":[{"filename":"ecus-export-2026-05-09.xlsx","kind":"ecus","size_bytes":524288,"uploaded_at":"2026-05-09T10:15:00+07:00"},{"filename":"wp-final-2026-05-09.xlsx","kind":"wp_final","size_bytes":102400,"uploaded_at":"2026-05-09T16:30:00+07:00"}],"has_downloaded":false,"has_rated":false,"id":"770e8400-e29b-41d4-a716-446655440002","modules":["item_code_generator","tariff_classification"],"rating_reminder_dismissed":false,"sla_due_at":"2026-05-12T17:00:00+07:00","sla_status":"on_time"}},"RequestListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/RequestSummary"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["items","total","page","page_size","total_pages"],"title":"RequestListResponse","example":{"items":[{"code":"REQ-2026-000123","created_at":"2026-05-09T10:15:00+07:00","display_status":"completed","expert_name":"Lê Quang Phi","files":[{"filename":"ecus-export-2026-05-09.xlsx","kind":"ecus","size_bytes":524288,"uploaded_at":"2026-05-09T10:15:00+07:00"}],"has_downloaded":false,"has_rated":false,"id":"770e8400-e29b-41d4-a716-446655440002","modules":["item_code_generator","tariff_classification"],"rating_reminder_dismissed":false,"sla_due_at":"2026-05-12T17:00:00+07:00","sla_status":"on_time"}],"page":1,"page_size":20,"total":1,"total_pages":1}},"RequestSummary":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"code":{"type":"string","title":"Code"},"display_status":{"$ref":"#/components/schemas/DisplayStatus"},"sla_status":{"type":"string","title":"Sla Status"},"sla_due_at":{"type":"string","format":"date-time","title":"Sla Due At"},"has_downloaded":{"type":"boolean","title":"Has Downloaded"},"has_rated":{"type":"boolean","title":"Has Rated"},"rating_reminder_dismissed":{"type":"boolean","title":"Rating Reminder Dismissed"},"modules":{"items":{"$ref":"#/components/schemas/ChcModule"},"type":"array","title":"Modules"},"expert_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expert Name"},"files":{"items":{"$ref":"#/components/schemas/FileSummary"},"type":"array","title":"Files"},"rating_stars":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rating Stars"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","code","display_status","sla_status","sla_due_at","has_downloaded","has_rated","rating_reminder_dismissed","modules","created_at"],"title":"RequestSummary","description":"Used by both list and detail endpoints; user-facing field set.\n\nPhase 18: ``ecus_filename`` removed — FE derives it from\n``files.find(f => f.kind === 'ecus')?.filename``. List + detail\nboth populate ``files`` filtered to user-visible kinds (ecus /\nwp_final / report — never wp_draft, B-002 v1.3).","example":{"code":"REQ-2026-000123","created_at":"2026-05-09T10:15:00+07:00","display_status":"completed","expert_name":"Lê Quang Phi","files":[{"filename":"ecus-export-2026-05-09.xlsx","kind":"ecus","size_bytes":524288,"uploaded_at":"2026-05-09T10:15:00+07:00"}],"has_downloaded":false,"has_rated":false,"id":"770e8400-e29b-41d4-a716-446655440002","modules":["item_code_generator","tariff_classification"],"rating_reminder_dismissed":false,"sla_due_at":"2026-05-12T17:00:00+07:00","sla_status":"on_time"}},"ResetRequest":{"properties":{"token":{"type":"string","maxLength":512,"minLength":20,"title":"Token","description":"URL-safe random token from email link (≥32 bytes pre-hash, single-use, expires 30 min — P7).","examples":["a8f3c2b1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a5"]},"new_password":{"type":"string","maxLength":200,"minLength":1,"title":"New Password","description":"New plaintext password. Server bcrypt-hashes and clears force_password_change flag.","examples":["NewP@ssw0rd456!"]}},"additionalProperties":false,"type":"object","required":["token","new_password"],"title":"ResetRequest"},"StepResult":{"properties":{"next_step":{"type":"integer","enum":[2,3],"title":"Next Step"}},"type":"object","required":["next_step"],"title":"StepResult","description":"``POST /company`` and ``POST /contact`` response.","example":{"next_step":2}},"UserCompany":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"tax_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tax Id"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"}},"type":"object","title":"UserCompany"},"UserDashboardResponse":{"properties":{"company":{"$ref":"#/components/schemas/UserCompany"},"kpi":{"$ref":"#/components/schemas/UserKpi"},"active_orders":{"items":{"$ref":"#/components/schemas/UserRecentOrder"},"type":"array","title":"Active Orders"},"recent_delivered":{"items":{"$ref":"#/components/schemas/UserRecentOrder"},"type":"array","title":"Recent Delivered"},"etariff":{"$ref":"#/components/schemas/UserEtariffWidget"},"rating_reminder_eligible":{"items":{"$ref":"#/components/schemas/RatingReminderItem"},"type":"array","title":"Rating Reminder Eligible"}},"type":"object","required":["company","kpi","active_orders","recent_delivered","etariff","rating_reminder_eligible"],"title":"UserDashboardResponse","example":{"active_orders":[{"code":"REQ-2026-000123","created_at":"2026-05-09T10:15:00+07:00","display_status":"processing","ecus_filename":"ecus-export-2026-05-09.xlsx","modules":["item_code_generator"],"request_id":"770e8400-e29b-41d4-a716-446655440002"}],"company":{"industry":"Sản xuất linh kiện điện tử","name":"Công ty TNHH Acme Việt Nam","tax_id":"0312345678","type":"san_xuat"},"etariff":{"limit":100,"remaining":77,"used":23},"kpi":{"cancelled":3,"completed":18,"delivered":142,"processing":5,"receiving":2,"total":170},"rating_reminder_eligible":[{"code":"REQ-2026-000118","request_id":"770e8400-e29b-41d4-a716-446655440008"}],"recent_delivered":[{"code":"REQ-2026-000118","created_at":"2026-05-05T10:15:00+07:00","delivered_at":"2026-05-08T16:30:00+07:00","display_status":"delivered","ecus_filename":"ecus-export-2026-05-05.xlsx","modules":["item_code_generator"],"rating_stars":5,"request_id":"770e8400-e29b-41d4-a716-446655440003"}]}},"UserEtariffWidget":{"properties":{"used":{"type":"integer","title":"Used"},"limit":{"type":"integer","title":"Limit"},"remaining":{"type":"integer","title":"Remaining"}},"type":"object","required":["used","limit","remaining"],"title":"UserEtariffWidget"},"UserFileKind":{"type":"string","enum":["ecus","wp_final","report"],"title":"UserFileKind"},"UserKpi":{"properties":{"receiving":{"type":"integer","title":"Receiving"},"processing":{"type":"integer","title":"Processing"},"completed":{"type":"integer","title":"Completed"},"delivered":{"type":"integer","title":"Delivered"},"cancelled":{"type":"integer","title":"Cancelled"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["receiving","processing","completed","delivered","cancelled","total"],"title":"UserKpi"},"UserProfileFullResponse":{"properties":{"name":{"type":"string","title":"Name"},"email_login":{"type":"string","title":"Email Login"},"email_contact":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email Contact"},"email_result":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email Result"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"language":{"anyOf":[{"$ref":"#/components/schemas/LanguageCode"},{"type":"null"}]},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"company_tax_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Tax Id"},"company_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Address"},"company_industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Industry"},"company_type":{"anyOf":[{"$ref":"#/components/schemas/CompanyType"},{"type":"null"}]}},"type":"object","required":["name","email_login"],"title":"UserProfileFullResponse","description":"``GET /api/user/profile`` — complete profile snapshot.","example":{"company_address":"123 Nguyễn Huệ, P. Bến Nghé, Q.1, TP.HCM","company_industry":"Sản xuất linh kiện điện tử","company_name":"Công ty TNHH Acme Việt Nam","company_tax_id":"0312345678","company_type":"san_xuat","email_contact":"contact@acme-corp.vn","email_login":"user@example.com","email_result":"result@acme-corp.vn","language":"vi","name":"Trần Thị B","phone":"0901234567"}},"UserProfileFullUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name","examples":["Trần Thị B"]},"phone":{"anyOf":[{"type":"string","maxLength":30},{"type":"null"}],"title":"Phone","examples":["0901234567"]},"email_contact":{"anyOf":[{"type":"string","maxLength":320,"minLength":3,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"},{"type":"null"}],"title":"Email Contact","examples":["contact@acme-corp.vn"]},"email_result":{"anyOf":[{"type":"string","maxLength":320,"minLength":3,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"},{"type":"null"}],"title":"Email Result","examples":["result@acme-corp.vn"]},"language":{"anyOf":[{"$ref":"#/components/schemas/LanguageCode"},{"type":"null"}],"examples":["vi"]},"company_name":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Company Name","examples":["Công ty TNHH Acme Việt Nam"]},"company_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Address","examples":["123 Nguyễn Huệ, P. Bến Nghé, Q.1, TP.HCM"]},"company_industry":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Company Industry","examples":["Sản xuất linh kiện điện tử"]},"company_type":{"anyOf":[{"$ref":"#/components/schemas/CompanyType"},{"type":"null"}],"examples":["san_xuat"]}},"additionalProperties":false,"type":"object","title":"UserProfileFullUpdate","description":"``PUT /api/user/profile`` partial body — all mutable fields.\n\nExcludes: ``email_login`` (BR-007), ``company_tax_id`` (BR-008),\n``password`` (cross-ref ``/auth/change-password``). ``extra='forbid'``\nrejects any attempt to PATCH the immutable trio with 422."},"UserProfileResponse":{"properties":{"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"language":{"anyOf":[{"$ref":"#/components/schemas/LanguageCode"},{"type":"null"}]}},"type":"object","required":["name","email"],"title":"UserProfileResponse","description":"``GET /api/user/settings/profile`` — user pool 4-locale (BR-032).\n\nPhase 16 S3.7: companion of :class:`AdminProfileResponse`.\n``language`` reflects ``users.language`` column (nullable for\npre-onboarding rows).","example":{"email":"user@example.com","language":"vi","name":"Trần Thị B","phone":"0901234567"}},"UserRecentOrder":{"properties":{"request_id":{"type":"string","format":"uuid","title":"Request Id"},"code":{"type":"string","title":"Code"},"display_status":{"type":"string","title":"Display Status"},"modules":{"items":{"type":"string"},"type":"array","title":"Modules"},"ecus_filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ecus Filename"},"delivered_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Delivered At"},"rating_stars":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rating Stars"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["request_id","code","display_status","modules","created_at"],"title":"UserRecentOrder"},"UserStatusCountsResponse":{"properties":{"counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Counts"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["counts","total"],"title":"UserStatusCountsResponse","description":"Per-display-status request count for user filter chips (Phase 18).\n\nAlways returns all 5 display-status keys (count=0 when empty) so the\nFE can render a stable chip set. ``total`` reflects the same scope\n(``user_id``) and same non-status filters (``search``) used by the\nlist endpoint.","example":{"counts":{"cancelled":1,"completed":4,"delivered":6,"processing":2,"receiving":3},"total":16}},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"ErrorBody":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable error key (see GET /api/public/error-catalog). FE switches logic / shows icon based on this value.","example":"request_not_found"},"message":{"type":"string","description":"Localized human-readable text. Language picked from Accept-Language header (vi/en/ko/zh); /api/admin/* always returns vi.","example":"Không tìm thấy đơn hàng"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/ErrorBody"}},"example":{"error":{"code":"request_not_found","message":"Không tìm thấy đơn hàng"}}},"ValidationErrorDetail":{"type":"object","properties":{"field":{"type":"string","example":"body.email"},"message":{"type":"string","example":"Field required"},"type":{"type":"string","example":"missing"}}},"ValidationErrorBody":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"validation_error"},"message":{"type":"string","example":"Dữ liệu không hợp lệ"},"details":{"type":"array","items":{"$ref":"#/components/schemas/ValidationErrorDetail"}}}},"ValidationErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/ValidationErrorBody"}},"example":{"error":{"code":"validation_error","message":"Dữ liệu không hợp lệ","details":[{"field":"body.email","message":"Field required","type":"missing"}]}}}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}