メインコンテンツまでスキップ

Requirement — LLM Credit Quotas

Tài liệu mô tả chức năng quản lý hạn mức credit LLM theo tháng UTC hiện tại (YYYY-MM)

Quy ước chung​

  • 1 credit = $0.01 USD
  • Số credit trên UI (limit / used / remaining / default) hiển thị số nguyên; phần trăm làm tròn tối đa 3 chữ số thập phân, bỏ số 0 thừa ở cuối (12.3%, không phải 12.300%) — cần thiết vì limit tổ chức có thể rất lớn nên % dùng thực tế nhiều khi < 0.01% và trước đây bị làm tròn xuống 0%
  • Ngôn ngữ UI theo lựa chọn của user (English / 日本語). Text lỗi/toast/banner dưới đây ghi cả hai
  • Lỗi form admin: banner đỏ trên modal — prefix Error! / エラー! + text lỗi hiển thị theo error_code (không hiện message thô từ server)
  • Lỗi khi chat: toast / banner theo error_code hoặc blocked_reason (không hiện mã lỗi thô cho end-user)
  • Soft-admit: câu chat đã được phép gửi có thể khiến used vượt limit sau khi tính cost; chỉ câu tiếp theo mới bị chặn
  • default_credit: gợi ý hạn mức tự gán khi invite / create / update user (auto-allocate). 0 = không auto-allocate. Trên UI FE: default_credit là số nguyên >= 0 và không được lớn hơn limit_credits của org

Mục 1 — Chức năng chính từng màn / modal​

1.1 Màn Credit Budgets — tổ chức (System Admin)​

Ai dùng: người có role System Admin.

Vào đâu: Governance → Credit Budgets (màn danh sách tổ chức).

Làm gì:

  • Xem mọi organization: trần tháng (Limit), đã dùng (Used), đã chia cho member (Allocated), còn để chia (Remaining), trạng thái bật/tắt
  • Gán trần mới (Set budget), sửa (Edit), xóa (Remove) — form gồm Limit + Default credit
  • Bật / tắt ngân sách org
  • Xem danh sách member và quota trong một org (View members — chỉ xem)

Không làm: không gán hạn mức cho từng member (việc đó thuộc Org Admin).


1.2 Màn Credit Budgets — member (Org Admin)​

Ai dùng: người có role Org Admin

Vào đâu: Governance → Credit Budgets (màn phân bổ trong org của mình).

Làm gì:

  • Xem tóm tắt ngân sách org: Org limit / Org used / Allocated / Remaining
  • Xem danh sách member và hạn mức từng người
  • Edit Default Credit — sửa default_credit của org (không đổi Limit / Status)
  • Gán hàng loạt (Assign quotas) cho member chưa có quota
  • Set / Edit / Remove / bật-tắt quota từng member

Điều kiện: org phải đã được System Admin gán budget. Chưa có thì màn báo ngân sách chưa thiết lập (xem UC-B1).

Quy tắc chọn người để gán: chỉ member chưa có quota; không gán cho tài khoản có role System Admin (họ bypass hạn mức chat, không nên nằm trong pool chia credit của org).


1.3 Modal Usage credit (menu avatar)​

Ai thấy mục menu: mọi user đã đăng nhập trừ System Admin.

Làm gì: xem hạn mức tháng của chính mình (đã dùng / trần / %, còn lại, trạng thái). Chỉ đọc, không chỉnh sửa.


1.4 Chat — kiểm tra hạn mức khi gửi tin​

Ai bị kiểm tra: mọi user gửi tin / retry, trừ System Admin (được bypass).

Làm gì:

  • Trước khi chat: nếu tài khoản đang bị chặn hạn mức → khóa ô nhập + banner giải thích
  • Khi gửi bị từ chối vì quota → toast + cập nhật trạng thái khóa nếu cần
  • Sau khi một câu chat tính cost xong, nếu vượt mốc 80 / 85 / 90 / 95 / 100% → thông báo chuông + toast trong cuộc hội thoại đang mở (nếu có)

Mục 2 — Luồng tổng thể​

2.1 Sơ đồ​

Ảnh nằm trong docs/rate-limit/diagrams/ (file .png).

2.1.1 Tổng quan — phân bổ credit​

Tổng quan phân bổ credit

Chú thích: SA = System Admin · OB = ngân sách org · OA = Org Admin · MQ = quota member · CHAT = kiểm tra hạn mức khi gửi tin (chi tiết ở 2.1.5)


2.1.2 Màn Credit Budgets — tổ chức (System Admin)​

Luồng màn Credit Budgets — tổ chức (System Admin)

Ghi chú: Set / Edit validate Limit > 0; Default credit ≥ 0 và ≤ Limit. Edit Limit không thấp hơn used / allocated. Remove thường chỉ khi used = 0 và không còn quota member. Toggle tắt org → mọi member org bị chặn chat (ORG_QUOTA_DISABLED).


2.1.3 Màn Credit Budgets — member (Org Admin)​

Luồng màn Credit Budgets — member (Org Admin)

Ghi chú: danh sách Assign = member chưa có quota, không gồm System Admin (API GET …/without-llm-credit-quotas). Org Admin sửa Default credit qua nút Edit Default Credit (PATCH …/default-credit), không lẫn với form Assign / Set member quota.


2.1.4 Modal Usage credit​

Luồng modal Usage credit

Ghi chú: chỉ xem, không chỉnh sửa; chỉ dữ liệu user đang đăng nhập.


2.1.5 Chat — kiểm tra hạn mức​

Sequence — luồng gửi tin

Sequence — kiểm tra hạn mức khi chat

Decision tree — mã lỗi khi gửi tin

Decision tree — mã lỗi khi gửi tin

2.2 Diễn giải​

Bước 1 — System Admin phân bổ cho org

  1. Vào màn tổ chức → Set budget cho org chưa có trần (limit_credits > 0, default_credit ≥ 0 và ≤ limit; mặc định default = 0).
  2. Có thể Edit (Limit không hạ dưới used / allocated; Default ≤ Limit), bật/tắt, Remove (khi chưa dùng và không còn cấu hình member).
  3. Có thể View members để theo dõi đã chia bao nhiêu.

Bước 2 — Org Admin phân bổ cho member

  1. Vào màn member trong org của mình.
  2. Có thể Edit Default Credit (chỉ đổi gợi ý auto-allocate khi invite; không đổi Limit org).
  3. Assign / Set cho member chưa có quota; bỏ qua System Admin.
  4. Tổng limit các member không vượt quá limit org (Remaining phải đủ).
  5. Có thể tắt quota một member; nếu System Admin tắt cả org budget thì mọi member trong org đều bị chặn chat.

Bước 2b — Auto-allocate khi invite / đổi org (ngoài 2 màn Credit Budgets)

Khi admin tạo / cập nhật user (POST / PUT /auth/users), hệ thống có thể tự cấp quota = default_credit nếu còn budget. User API vẫn thành công dù allocate thất bại (soft-fail). Chi tiết: Mục 3.E.

Bước 3 — Member dùng chat — các case

  1. Chưa được gán quota → không gửi được (NO_QUOTA_ASSIGNED)
  2. Quota cá nhân hoặc ngân sách org bị tắt → không gửi được (QUOTA_DISABLED / ORG_QUOTA_DISABLED)
  3. Còn hạn mức → gửi được; used tăng sau mỗi câu; có thể nhận cảnh báo ngưỡng
  4. Đã dùng hết / vượt → không gửi thêm (USER_QUOTA_EXCEEDED); soft-admit có thể khiến used > limit sau câu cuối vẫn thành công
  5. System Admin → không bị kiểm tra hạn mức; không có mục Usage credit trên avatar

Ai xem được modal Usage credit

  • Có: Org Admin, workspace admin, AI builder, member, … (mọi role trừ System Admin)
  • Không: mọi user mang role System Admin
  • Nội dung: chỉ của chính người đang đăng nhập, không xem hộ người khác

Mục 3 — Use case chi tiết theo chức năng​

Mỗi use case: mục đích → điều kiện → validate trên form → thành công → lỗi (mã + EN + JA).

Cách ghi lỗi form:

Mã: CODE
EN: …
JA: …

Prefix banner form luôn là:

  • EN: Error!
  • JA: エラー!

3.A — Màn tổ chức (System Admin)​

UC-A1 — Xem danh sách ngân sách org​

Mục đích: theo dõi trần và mức dùng / đã chia của từng org.

Điều kiện: System Admin.

Hành vi UI:

  • Tìm kiếm theo tên org, phân trang
  • Cột: Organization, Limit, Used (+ %), Allocated, Remaining (limit − allocated), Status (bật/tắt), Actions
  • Org chưa gán: Limit = Not set / 未設定; các cột số khác trống hoặc “—”

Thành công — pager:

  • EN: Showing {{from}}–{{to}} of {{total}}
  • JA: {{from}}–{{to}} / {{total}} 件を表示

Lỗi tải danh sách:

  • EN: Could not load credit budgets.
  • JA: クレジット予算を読み込めませんでした。

UC-A2 — Set budget (tạo mới)​

Mục đích: gán trần tháng + default credit cho org chưa có budget.

Điều kiện: org chưa có ngân sách.

Validate trước khi lưu (nút chỉ bật khi hợp lệ):

  • Phải chọn Organization
    • EN: Select an organization.
    • JA: 組織を選択してください。
  • Limit bắt buộc, số nguyên > 0
    • EN: Enter a credit limit. / Limit must be a whole number greater than 0.
    • JA: クレジット上限を入力してください。 / 上限は 0 より大きい整数である必要があります。
  • Default credit bắt buộc, số nguyên ≥ 0 (mặc định form = 0)
    • EN: Enter a default credit. / Default credit must be a whole number of 0 or greater.
    • JA: デフォルトクレジットを入力してください。 / デフォルトクレジットは 0 以上の整数である必要があります。
  • Default credit ≤ Limit
    • EN: Default credit cannot be greater than the organization limit ({{limit}}).
    • JA: デフォルトクレジットは組織上限({{limit}})を超えられません。
  • Help dưới Default credit:
    • EN: Suggested quota when inviting members. Use 0 to skip auto-allocate.
    • JA: メンバー招待時の推奨枠。自動割当しない場合は 0。

Body gửi server: { limit_credits, default_credit } (API A3).

Thành công:

  • EN toast: Organization budget set.
  • JA toast: 組織予算を設定しました。
  • Budget mới luôn ở trạng thái bật

Lỗi banner (sau khi gửi server):

Mã: QUOTA_ALREADY_EXISTS
EN: This organization already has a credit budget.
JA: この組織にはすでにクレジット予算があります。

Mã: QUOTA_NOT_FOUND
EN: Organization budget was not found.
JA: 組織のクレジット予算が見つかりませんでした。

Mã: (không nhận diện / khác)
EN: Could not save the organization budget.
JA: 組織のクレジット予算を保存できませんでした。

UC-A3 — Edit organization budget​

Mục đích: đổi limit_credits và/hoặc default_credit của org đã có budget.

Validate:

  • Limit số nguyên > 0 (cùng copy UC-A2)
  • Limit không thấp hơn mức đã dùng của org trong tháng và không thấp hơn tổng đã allocate
    • EN: Limit must be at least {{floor}}.
    • JA: 上限は {{floor}} 以上である必要があります。
    • Gợi ý dưới field: EN Minimum {{floor}} (used or allocated). / JA tương ứng trong locale
  • Default credit ≥ 0 và ≤ Limit (cùng copy UC-A2; khi đổi Limit thì re-validate Default)

Body gửi server: { limit_credits, default_credit } (API A4). is_enabled giữ nguyên.

Thành công:

  • EN: Organization budget updated.
  • JA: 組織予算を更新しました。

Lỗi banner:

Mã: LIMIT_BELOW_USAGE
EN: This limit cannot be lower than credits already used this month.
JA: この上限は、今月すでに使用したクレジットより低く設定できません。

Mã: ALLOCATION_EXCEEDED
EN: This limit cannot be lower than credits already allocated to members.
JA: この上限は、メンバーに割り当て済みのクレジット合計より低く設定できません。

Mã: QUOTA_NOT_FOUND
EN: Organization budget was not found.
JA: 組織のクレジット予算が見つかりませんでした。

Mã: (fallback)
EN: Could not save the organization budget.
JA: 組織のクレジット予算を保存できませんでした。

UC-A4 — Bật / tắt ngân sách org​

Mục đích: bật hoặc tắt trần org. Khi tắt, mọi member thuộc org bị chặn chat với mã ORG_QUOTA_DISABLED (kể cả chưa có quota cá nhân).

Thành công: toggle trên hàng cập nhật ngay.

Lỗi (toast, không banner form):

  • EN: Could not update status.
  • JA: ステータスを更新できませんでした。

UC-A5 — Remove organization budget​

Mục đích: xóa cấu hình ngân sách org.

Điều kiện UI: thường không cho xóa khi org đã có used > 0 hoặc còn cấu hình quota member.

Xác nhận:

  • EN title: Remove organization budget?
  • EN body: Remove the credit budget for {{org}}? This cannot be undone.
  • JA: tương ứng trong locale (組織予算を削除しますか? / nội dung xác nhận có tên org)

Thành công:

  • EN: Organization budget removed.
  • JA: 組織予算を削除しました。

Lỗi (toast):

Mã: LIMIT_BELOW_USAGE — org đã có used > 0
Mã: ALLOCATION_EXCEEDED — còn cấu hình quota member
Mã: QUOTA_NOT_FOUND — đã bị xóa trước đó

Toast chung khi xóa thất bại:

  • EN: Could not remove.
  • JA: 削除できませんでした。

UC-A6 — View members (chỉ xem)​

Mục đích: System Admin xem quota từng member trong một org; không chỉnh sửa từ modal này.

Hành vi: tìm theo tên/email; cột Member, Limit, Used, Remaining, Status.

Lỗi tải:

  • EN: Could not load members.
  • JA: メンバーを読み込めませんでした。

Empty:

  • EN: No members found. / No member quotas yet.
  • JA: メンバーが見つかりません。 / メンバー枠はまだありません。

3.B — Màn member (Org Admin)​

UC-B1 — Xem summary org + danh sách member​

Mục đích: theo dõi ngân sách org và hạn mức từng member.

Điều kiện: Org Admin (không phải System Admin).

Hành vi:

  • Thẻ tóm tắt: Org limit, Org used, Allocated, Remaining
  • Bảng: Member, Limit, Used, Remaining (limit − used), Status, Actions
  • Member chưa có quota: Limit = Not set / 未設定

Org chưa có budget (empty state):

  • EN title: Organization budget not set
  • EN body: Ask a system admin to set an organization credit budget before assigning member quotas.
  • JA title: 組織予算が未設定です
  • JA body: メンバー枠を割り当てる前に、システム管理者に組織のクレジット予算の設定を依頼してください。
  • Liên quan mã API: ORG_BUDGET_NOT_SET

Lỗi tải danh sách:

  • EN: Could not load member credit quotas.
  • JA: メンバーのクレジット枠を読み込めませんでした。

UC-B1b — Edit Default Credit (Org Admin)​

Mục đích: chỉ đổi default_credit của org — gợi ý hạn mức khi invite / auto-allocate. Không đổi limit_credits / is_enabled.

Điều kiện: org đã có budget (màn không ở empty state ORG_BUDGET_NOT_SET).

UI: nút Edit Default Credit cạnh Assign quotas → modal (template giống Assign: header + X, banner current default, 1 input, Cancel / Save).

API: PATCH /rate-limit/org/llm-credit-quota/default-credit body { default_credit } (B1b). Chỉ Org Admin (LC-09); System Admin không gọi API này.

Validate:

  • Default credit bắt buộc, số nguyên ≥ 0 (cùng copy UC-A2)
  • Default credit ≤ org.limit_credits hiện tại
    • EN: Default credit cannot be greater than the organization limit ({{limit}}).
    • JA: デフォルトクレジットは組織上限({{limit}})を超えられません。
  • Help dưới input:
    • EN: The default value will be assigned automatically to members when inviting members.
    • JA: メンバー招待時に、このデフォルト値が自動的に割り当てられます。

Thành công:

  • EN toast: Default credit updated.
  • JA toast: デフォルトクレジットを更新しました。
  • Refresh summary / list org (có default_credit mới)

Lỗi banner:

Mã: QUOTA_NOT_FOUND
EN: Organization budget was not found.
JA: 組織のクレジット予算が見つかりませんでした。

Mã: (fallback)
EN: Could not update default credit.
JA: デフォルトクレジットを更新できませんでした。

UC-B2 — Assign quotas (gán hàng loạt)​

Mục đích: gán cùng một limit cho nhiều member chưa có quota.

Điều kiện:

  • Org đã có budget
  • Danh sách chọn lấy từ GET /rate-limit/org/users/without-llm-credit-quotas — BE đã lọc member chưa có quota và không gồm System Admin

Validate trước khi Assign:

  • Chọn ≥ 1 người
    • EN: Select at least one member without a quota.
    • JA: 枠未割当のメンバーを1人以上選択してください。
  • Limit bắt buộc, số nguyên > 0 (cùng copy field Limit như UC-A2)
  • Tổng limit × số người không vượt Remaining
    • EN: Need {{needed}} credits; only {{remaining}} remaining.
    • JA: {{needed}} クレジット必要ですが、残りは {{remaining}} のみです。

Thành công:

  • EN: Member quotas assigned.
  • JA: メンバー枠を割り当てました。

Lỗi banner:

Mã: ORG_BUDGET_NOT_SET
EN: Organization budget is not set. Ask a system admin to set it first.
JA: 組織の予算が未設定です。先にシステム管理者に設定を依頼してください。

Mã: ALLOCATION_EXCEEDED
EN: Not enough organization budget left for the selected members and limit.
JA: 選択したメンバーと上限に対して、組織の残り予算が不足しています。

Mã: USER_NOT_IN_ORG
EN: One or more selected members are not in this organization.
JA: 選択したメンバーの一部がこの組織に所属していません。

Mã: LIMIT_BELOW_USAGE
EN: Limit cannot be lower than credits a selected member has already used.
JA: 上限は、選択したメンバーがすでに使用したクレジットより低く設定できません。

Mã: QUOTA_ALREADY_EXISTS
EN: One or more selected members already have a quota.
JA: 選択したメンバーの一部にはすでに枠が割り当てられています。

Mã: (fallback)
EN: Could not assign member quotas.
JA: メンバー枠を割り当てできませんでした。

UC-B3 — Set quota (một member chưa có)​

Mục đích: gán hạn mức cho đúng một member chưa có quota.

Validate: limit > 0; không vượt Remaining org.

Thành công:

  • EN: Member quota set.
  • JA: メンバー枠を設定しました。

Lỗi banner: cùng bộ mã như UC-B4 (bối cảnh set/edit member).


UC-B4 — Edit member quota​

Validate:

  • Limit ≥ used của member
    • EN: Limit must be at least {{floor}}.
  • Limit ≤ Remaining org + limit hiện tại của member đó
    • EN: Limit cannot exceed {{max}} remaining credits.
    • JA: 上限は残り {{max}} クレジットを超えられません。

Thành công:

  • EN: Member quota updated.
  • JA: メンバー枠を更新しました。

Lỗi banner:

Mã: ORG_BUDGET_NOT_SET
EN: Organization budget is not set. Ask a system admin to set it first.
JA: 組織の予算が未設定です。先にシステム管理者に設定を依頼してください。

Mã: LIMIT_BELOW_USAGE
EN: This limit cannot be lower than credits this member has already used.
JA: この上限は、このメンバーがすでに使用したクレジットより低く設定できません。

Mã: ALLOCATION_EXCEEDED
EN: This limit exceeds the organization budget remaining.
JA: この上限は、組織の残り予算を超えています。

Mã: USER_NOT_IN_ORG
EN: This member is not in the organization.
JA: このメンバーは組織に所属していません。

Mã: QUOTA_ALREADY_EXISTS
EN: This member already has a credit quota.
JA: このメンバーにはすでにクレジット枠があります。

Mã: QUOTA_NOT_FOUND
EN: Member quota was not found.
JA: メンバーのクレジット枠が見つかりませんでした。

Mã: (fallback)
EN: Could not save the member quota.
JA: メンバーのクレジット枠を保存できませんでした。

UC-B5 — Bật / tắt quota member​

Mục đích: tắt hoặc bật hạn mức một người. Khi tắt, member đó bị chặn chat với mã QUOTA_DISABLED.

Lỗi toast:

  • EN: Could not update status.
  • JA: ステータスを更新できませんでした。

UC-B6 — Remove member quota​

Điều kiện UI: thường chỉ khi used = 0 (nút Remove bị khóa nếu đã dùng).

Thành công:

  • EN: Member quota removed.
  • JA: メンバー枠を削除しました。

Lỗi:

Mã: LIMIT_BELOW_USAGE — đã có used > 0
Mã: QUOTA_NOT_FOUND — đã bị xóa

Toast chung:

  • EN: Could not remove.
  • JA: 削除できませんでした。

3.C — Modal Usage credit​

UC-C1 — Mở từ menu avatar​

Điều kiện hiện menu: không phải System Admin.

Hiển thị: kỳ (period), Used / limit, %, thanh tiến độ, dòng còn lại, badge trạng thái. Nút Cancel / キャンセル để đóng. Không có form chỉnh sửa.

Khi ORG_QUOTA_DISABLED: nếu member đó đã có quota cá nhân (UserLlmCreditConfig riêng, độc lập với công tắc tổng của org), modal vẫn hiện used/limit/%/remaining thật — chỉ badge đổi thành lý do org bị tắt, không phải toàn bộ số liệu trống (—). Chỉ khi member chưa từng được gán quota riêng thì mới không có gì để hiển thị.

Dòng còn lại:

  • EN: {{remaining}} credits remaining
  • JA: 残り {{remaining}} クレジット

Lỗi tải:

  • EN: Could not load credit usage.
  • JA: クレジット使用量を読み込めませんでした。

Thứ tự chọn badge trạng thái (ưu tiên từ trên xuống):

  1. System Admin và chưa có quota cá nhân → Unlimited
    • EN: Unlimited (system admin)
    • JA: 無制限(システム管理者)
      (menu thường đã ẩn; trường hợp hiếm nếu vẫn mở được API)
  2. Có blocked_reason đã biết → dùng text reason bên dưới
  3. Chưa có quota →
    • EN: No quota assigned
    • JA: 枠未割当
  4. Quota tắt →
    • EN: Quota disabled
    • JA: 枠が無効
  5. Đã vượt →
    • EN: Quota exceeded
    • JA: 枠を超過
  6. Bình thường →
    • EN: Available
    • JA: 利用可能

Text theo blocked_reason trên badge:

Mã: ORG_QUOTA_DISABLED
EN: Organization credit budget is disabled
JA: 組織のクレジット予算が無効です

Mã: NO_QUOTA_ASSIGNED
EN: No personal credit quota assigned
JA: 個人のクレジット枠が割り当てられていません

Mã: QUOTA_DISABLED
EN: Your credit quota is disabled
JA: クレジット枠が無効です

Mã: USER_QUOTA_EXCEEDED
EN: Monthly credit quota exceeded
JA: 月次クレジット枠を超過しています

3.D — Chat: khóa gửi tin & cảnh báo ngưỡng​

UC-D1 — Khóa ô nhập khi tài khoản đang bị block​

Khi vào chat, hệ thống kiểm tra hạn mức của user.

Nếu đang bị chặn:

  • Khóa ô nhập + nút Send
  • Banner đỏ:
    • Tiêu đề EN: Messaging is paused for your account.
    • Tiêu đề JA: アカウントのメッセージ送信が一時停止されています。
    • Phụ đề: câu theo mã bên dưới

Text theo blocked_reason / error_code (chat):

Mã: ORG_QUOTA_DISABLED
EN: Your organization's credit budget is disabled. Contact your admin.
JA: 組織のクレジット予算が無効です。管理者に連絡してください。

Mã: NO_QUOTA_ASSIGNED
EN: No credit quota has been assigned to you. Contact your org admin.
JA: クレジット枠が割り当てられていません。組織管理者に連絡してください。

Mã: QUOTA_DISABLED
EN: Your credit quota is disabled. Contact your org admin.
JA: クレジット枠が無効です。組織管理者に連絡してください。

Mã: USER_QUOTA_EXCEEDED
EN: Monthly credit quota exceeded. Contact your admin.
JA: 月次クレジット枠を超過しました。管理者に連絡してください。

Mã: FORBIDDEN
EN: You cannot start a chat with the current credit settings.
JA: 現在のクレジット設定ではチャットを開始できません。

System Admin: không bị khóa vì hạn mức.


UC-D2 — Gửi tin / retry bị từ chối​

Thứ tự kiểm tra phía server (trước khi chạy LLM):

  1. System Admin → cho qua
  2. Ngân sách org tắt → 403 ORG_QUOTA_DISABLED
  3. Chưa có quota cá nhân → 403 NO_QUOTA_ASSIGNED
  4. Quota cá nhân tắt → 403 QUOTA_DISABLED
  5. Đã dùng ≥ limit → 429 USER_QUOTA_EXCEEDED

UI: toast với cùng bộ text như UC-D1 (theo mã, không hiện message server). Tin nhắn tạm thời được gỡ nếu gửi thất bại. Nếu là lỗi quota → giữ / đặt trạng thái khóa ô nhập.

Fallback không phải lỗi quota:

  • EN: Could not send your message.
  • JA: メッセージを送信できませんでした。

UC-D3 — Cảnh báo ngưỡng 80 / 85 / 90 / 95 / 100%​

Khi nào: sau khi một câu chat đã chạy xong và tính cost (không phải lỗi lúc bấm Send). Mỗi mốc báo một lần / user / tháng.

Hai kênh:

  1. Chuông thông báo trong app (nội dung title/body do server tạo)
  2. Toast trong chat nếu user đang mở đúng cuộc hội thoại đó

Toast 80–95% (cảnh báo):

  • EN title: Credit usage at {{threshold}}%
  • EN body: You have used {{threshold}}% of your monthly LLM credits.
  • JA title: クレジット使用率 {{threshold}}%
  • JA body: 月次 LLM クレジットの {{threshold}}% を使用しています。

Toast 100% (lỗi):

  • EN title: Monthly credit quota exceeded
  • EN body: You have used all of your monthly LLM credits. Contact your admin.
  • JA title: 月次クレジット枠を超過しました
  • JA body: 月次 LLM クレジットを使い切りました。管理者に連絡してください。
  • Đồng thời khóa ô nhập như USER_QUOTA_EXCEEDED

Nếu lúc tính cost không gắn được cuộc hội thoại → chỉ còn thông báo chuông, không toast trong chat.


UC-D4 — Soft-admit vs câu tiếp theo​

  • Câu đã được phép gửi có thể hoàn tất dù sau đó used ≥ limit → có thể thấy toast 100%
  • Câu kế tiếp bị 429 USER_QUOTA_EXCEEDED + khóa ô nhập

3.E — Auto-allocate default_credit khi invite / tạo / sửa user​

Không thuộc 2 màn Credit Budgets UI, nhưng ảnh hưởng danh sách member sau khi invite. Chi tiết kỹ thuật: rate-limit-fe-api.md §8 và rate-limit-user-lifecycle-credit.md.

API liên quan: POST /auth/users (create hoặc reactivate email soft-deleted), PUT /auth/users/{user_id} (admin path).

Nguyên tắc:

  • User create/update vẫn thành công khi auth OK — allocate credit là soft-fail
  • remaining = org.limit − SUM(member limit configs)
  • Chỉ allocate khi đủ tất cả: target không phải System Admin; org có budget và default_credit > 0; user chưa có config quota; remaining >= default_credit; used kỳ hiện tại <= default_credit
  • Khi allocate được: tạo config với limit_credits = default_credit
  • Khi thiếu budget / used vượt default: không tạo config; notify chuông cho người gọi API (requester), type llm_credit_org_budget_insufficient — không gửi cho user mới
  • default_credit = 0 / chưa có org budget / org_id null / target System Admin → skip, không notify

UC-E1 — Create user​

CaseĐiều kiệnCreditNotify requester?
C1Có org_id, default_credit > 0, remaining OK, used OKTạo quota = defaultKhông
C2default_credit > 0 nhưng remaining < defaultKhông tạoCó
C3default_credit > 0 nhưng used > defaultKhông tạoCó
C4default_credit = 0 hoặc chưa có org budgetKhông tạoKhông
C5org_id nullSkipKhông
C6Target là System AdminSkip (bypass)Không

UC-E2 — Reactivate user (create tìm email soft-deleted)​

CaseĐiều kiệnCredit
R1Đổi org + có config cũXóa config cũ → thử allocate org mới (như C1–C6)
R2Cùng org + đã có configGiữ nguyên
R3Cùng org + chưa có configThử allocate như create

UC-E3 — Update user (admin; không phải self-edit thường)​

CaseĐiều kiệnCredit
U1Đổi org + có config cũXóa cũ → allocate org mới
U2Đổi org + chưa có configAllocate org mới
U3Đổi org → org_id nullXóa config; không allocate
U4Cùng org + chưa có config + default/budget OKBackfill tạo config
U5Cùng org + chưa có config + thiếu budget/usedKhông tạo; notify
U6Cùng org + đã có configGiữ limit cũ (no-op)
U7Self-edit (non–sysadmin sửa chính mình)Không đụng credit

Phụ lục A — Tra nhanh mã lỗi + EN / JA​

A.1 Form — ngân sách org (Limit + Default credit)​

Validate FE (không có mã error_code):

defaultRequired
EN: Enter a default credit.
JA: デフォルトクレジットを入力してください。

defaultNonNegative
EN: Default credit must be a whole number of 0 or greater.
JA: デフォルトクレジットは 0 以上の整数である必要があります。

defaultAboveLimit
EN: Default credit cannot be greater than the organization limit ({{limit}}).
JA: デフォルトクレジットは組織上限({{limit}})を超えられません。

Banner theo error_code:

LIMIT_BELOW_USAGE
EN: This limit cannot be lower than credits already used this month.
JA: この上限は、今月すでに使用したクレジットより低く設定できません。

ALLOCATION_EXCEEDED
EN: This limit cannot be lower than credits already allocated to members.
JA: この上限は、メンバーに割り当て済みのクレジット合計より低く設定できません。

QUOTA_ALREADY_EXISTS
EN: This organization already has a credit budget.
JA: この組織にはすでにクレジット予算があります。

QUOTA_NOT_FOUND
EN: Organization budget was not found.
JA: 組織のクレジット予算が見つかりませんでした。

(fallback)
EN: Could not save the organization budget.
JA: 組織のクレジット予算を保存できませんでした。

A.2 Form — Assign hàng loạt​

ORG_BUDGET_NOT_SET
EN: Organization budget is not set. Ask a system admin to set it first.
JA: 組織の予算が未設定です。先にシステム管理者に設定を依頼してください。

ALLOCATION_EXCEEDED
EN: Not enough organization budget left for the selected members and limit.
JA: 選択したメンバーと上限に対して、組織の残り予算が不足しています。

USER_NOT_IN_ORG
EN: One or more selected members are not in this organization.
JA: 選択したメンバーの一部がこの組織に所属していません。

LIMIT_BELOW_USAGE
EN: Limit cannot be lower than credits a selected member has already used.
JA: 上限は、選択したメンバーがすでに使用したクレジットより低く設定できません。

QUOTA_ALREADY_EXISTS
EN: One or more selected members already have a quota.
JA: 選択したメンバーの一部にはすでに枠が割り当てられています。

(fallback)
EN: Could not assign member quotas.
JA: メンバー枠を割り当てできませんでした。

A.3 Form — Set / Edit quota member​

ORG_BUDGET_NOT_SET
EN: Organization budget is not set. Ask a system admin to set it first.
JA: 組織の予算が未設定です。先にシステム管理者に設定を依頼してください。

LIMIT_BELOW_USAGE
EN: This limit cannot be lower than credits this member has already used.
JA: この上限は、このメンバーがすでに使用したクレジットより低く設定できません。

ALLOCATION_EXCEEDED
EN: This limit exceeds the organization budget remaining.
JA: この上限は、組織の残り予算を超えています。

USER_NOT_IN_ORG
EN: This member is not in the organization.
JA: このメンバーは組織に所属していません。

QUOTA_ALREADY_EXISTS
EN: This member already has a credit quota.
JA: このメンバーにはすでにクレジット枠があります。

QUOTA_NOT_FOUND
EN: Member quota was not found.
JA: メンバーのクレジット枠が見つかりませんでした。

(fallback)
EN: Could not save the member quota.
JA: メンバーのクレジット枠を保存できませんでした。

A.3b Form — Edit Default Credit (Org Admin)​

Validate FE: cùng defaultRequired / defaultNonNegative / defaultAboveLimit như A.1 (so với org.limit_credits).

Banner theo error_code:

QUOTA_NOT_FOUND
EN: Organization budget was not found.
JA: 組織のクレジット予算が見つかりませんでした。

(fallback)
EN: Could not update default credit.
JA: デフォルトクレジットを更新できませんでした。

A.4 Chat gate (HTTP + blocked_reason)​

ORG_QUOTA_DISABLED (403)
EN: Your organization's credit budget is disabled. Contact your admin.
JA: 組織のクレジット予算が無効です。管理者に連絡してください。

NO_QUOTA_ASSIGNED (403)
EN: No credit quota has been assigned to you. Contact your org admin.
JA: クレジット枠が割り当てられていません。組織管理者に連絡してください。

QUOTA_DISABLED (403)
EN: Your credit quota is disabled. Contact your org admin.
JA: クレジット枠が無効です。組織管理者に連絡してください。

USER_QUOTA_EXCEEDED (429)
EN: Monthly credit quota exceeded. Contact your admin.
JA: 月次クレジット枠を超過しました。管理者に連絡してください。

FORBIDDEN (403)
EN: You cannot start a chat with the current credit settings.
JA: 現在のクレジット設定ではチャットを開始できません。

A.5 Usage credit — badge reason (ngắn hơn chat)​

ORG_QUOTA_DISABLED
EN: Organization credit budget is disabled
JA: 組織のクレジット予算が無効です

NO_QUOTA_ASSIGNED
EN: No personal credit quota assigned
JA: 個人のクレジット枠が割り当てられていません

QUOTA_DISABLED
EN: Your credit quota is disabled
JA: クレジット枠が無効です

USER_QUOTA_EXCEEDED
EN: Monthly credit quota exceeded
JA: 月次クレジット枠を超過しています

A.6 Toast / empty state thường gặp (không gắn một mã cụ thể)​

Toggle thất bại
EN: Could not update status.
JA: ステータスを更新できませんでした。

Xóa thất bại
EN: Could not remove.
JA: 削除できませんでした。

Prefix banner form
EN: Error!
JA: エラー!

Gửi chat thất bại (không phải quota)
EN: Could not send your message.
JA: メッセージを送信できませんでした。

Default credit đã cập nhật
EN: Default credit updated.
JA: デフォルトクレジットを更新しました。

Phụ lục B — Quyền (tóm tắt)​

  • Màn ngân sách org: chỉ System Admin (Set/Edit gồm Limit + Default credit)
  • Màn quota member: chỉ Org Admin (không gồm System Admin)
  • Edit Default Credit (B1b): chỉ Org Admin
  • Menu Usage credit: mọi user trừ System Admin
  • Áp hạn mức khi chat: mọi user trừ System Admin (bypass)
  • Assign member: không đưa System Admin vào danh sách chọn
  • Auto-allocate khi invite: skip System Admin; notify requester khi thiếu budget