Skip to content

spec: add usage page, update key lifecycle, and switch revoke provider endpoint #51

@pochun1021

Description

@pochun1021

背景

需要新增 API Key 使用量頁面,並同步調整 key lifecycle 與 provider revoke 行為。

本次需求包含四個主題:

  1. 新增使用量頁面 /usage
  2. expired key 改走 renew
  3. 停用 key 時 provider 改呼叫 /key/delete
  4. extend 對 provider 固定送基數天數,不再計算累積總天數

需求摘要

  • renew 允許 expiredrevoked
  • extend 只允許 active
  • 停用 key 時,provider endpoint 從 /key/block 改為 /key/delete
  • 本地 key 狀態仍維持 revoked,不新增 deleted 狀態
  • 新增 /usage 頁面,useradmin 都可用
  • 使用量圖表只做「按日期」查詢,時間範圍可自訂
  • 不做小時圖
  • extend 對 provider 一律直接送 30|180|360,不再依 created_at -> expires_at 計算總天數

規格變更

1. Key lifecycle

  • POST /api/v1/api-keys/{id}/renew

    • 來源狀態由原本僅 revoked 改為允許 revoked|expired
    • renew 維持既有語意:建立新 key,回傳一次性 plaintext
    • 舊 key 依既有規則對一般使用者隱藏
  • POST /api/v1/api-keys/{id}/extend

    • 改為只允許 active
    • expired 呼叫時需回 KEY_NOT_EXTENDABLE
    • 本地資料仍更新:
      • application_date = 本次展延起算日
      • duration_days = original_duration_days
      • expires_at = 依該基數重算
    • provider payload 的 duration 一律直接送 original_duration_days
    • 移除現有「依 key 建立日累算總天數」邏輯
  • POST /api/v1/api-keys/{id}/revoke

    • provider client 從 /key/block 改成 /key/delete
    • 本地 DB 仍寫入 revoked

2. My API Keys Page

  • active 顯示 extend
  • expired 顯示 renew
  • revoked 顯示 renew
  • expired 不再顯示 extend

3. Usage Page

  • 新增路由 /usage
  • useradmin 都可見
  • 進頁後需先選一把 key
  • 支援自訂日期區間
  • 圖表顯示每日使用量
  • 主圖表指標為 total_tokens
  • tooltip 顯示:
    • prompt_tokens
    • completion_tokens
    • total_tokens
    • spend
  • 提供 Loading / Empty / Error / Retry 狀態

資料模型

沿用並擴充現有 api_key_usage_snapshots,不新增第二張 usage 時序表。

新增欄位

  • bucket_granularity,第一版固定使用 day
  • bucket_start_utc
  • bucket_end_utc

新增唯一鍵

  • (api_key_id, bucket_granularity, bucket_start_utc)

保留既有欄位

  • spend
  • prompt_tokens
  • completion_tokens
  • total_tokens
  • budget_reset_at
  • synced_at

說明

  • api_key_usage_snapshots 正式作為每日聚合歷史來源
  • api_keys.usage_* 快取欄位保留,繼續提供 My API Keys 的 usage popover / health 使用
  • 不做小時資料模型
  • 不做舊資料的精確回填,避免錯誤 bucket 污染圖表語意

使用量同步

  • sync 腳本改為以「日」為單位聚合 provider spend logs
  • 每次同步對 active keys 抓取最近一段日期區間資料,建議先抓最近 30 天
  • 同一天 bucket 允許後續 sync 覆寫
  • 不做獨立 backfill 腳本
  • 新頁面的日圖以功能上線後累積資料為主

新增 API

GET /api/v1/api-keys/usage-series

權限

  • user 只能查自己的 key
  • admin 可查任意 key

Request

  • key_id 必填
  • granularity=day 必填
  • from 必填
  • to 必填

Response

  • items[]
  • 每筆包含:
    • bucket_start
    • bucket_label
    • prompt_tokens
    • completion_tokens
    • total_tokens
    • spend
  • 回傳:
    • granularity
    • key_id
    • from
    • to

時間語意

  • DB 以 UTC 儲存 bucket
  • 查詢與畫面日期區間以 Asia/Taipei 的日曆日為基準

測試項目

lifecycle

  • expired key 可成功 renew
  • revoked key 仍可成功 renew
  • expired key 不可 extend
  • active key 仍可 extend
  • extend 時 provider payload 的 duration 必須直接等於 original_duration_days
  • extend 不可再送累積總天數
  • revoke 會呼叫 provider /key/delete
  • provider delete 失敗時,本地狀態不得提前改成 revoked

usage-series API

  • user 查他人 key 會被拒絕
  • 可正確回傳日期區間的每日 token 聚合
  • 日期區間跨 UTC 換日時,Taipei 日期分組正確
  • 無資料時回傳正確空結構
  • 日期區間參數非法時回 422

sync job

  • 同一天 bucket 可重跑覆寫,不重複灌資料
  • rolling window 重抓時可更新既有日期 bucket
  • active key 不再同步新資料,但既有歷史資料保留

frontend

  • 主導覽顯示 /usage
  • 使用量頁可載入 key 選單並依日期區間畫圖
  • My API Keysexpired|revoked 顯示 renew
  • My API Keys 只有 active 顯示 extend

驗收標準

  • 使用者可在 /usage 依 key + 日期區間查看每日 token 使用量
  • expired key 不再能 extend,但可以 renew
  • revoked key 可 renew
  • active key extend 時,provider 僅收到固定基數 30|180|360
  • 停用 key 時,provider 改呼叫 /key/delete
  • 本地狀態與既有 status contract 仍維持 active|revoked|expired

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions