feat(api): add admin master key listing/revoke

Add admin endpoints to list and revoke child keys under a master.
Standardize OpenAPI responses to use ResponseEnvelope with MapData
for error payloads, and regenerate swagger specs accordingly.
This commit is contained in:
zenfun
2026-01-10 01:10:36 +08:00
parent ac6a1858cf
commit 5349c9c833
27 changed files with 9407 additions and 1134 deletions

View File

@@ -168,7 +168,7 @@ func (h *MasterHandler) masterLogBase(masterID uint) (*gorm.DB, error) {
// @Param model query string false "model"
// @Param status_code query int false "status code"
// @Success 200 {object} ResponseEnvelope{data=ListLogsResponse}
// @Failure 500 {object} ResponseEnvelope{data=gin.H}
// @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/logs [get]
func (h *Handler) ListLogs(c *gin.Context) {
limit, offset := parseLimitOffset(c)
@@ -268,8 +268,8 @@ type DeleteLogsResponse struct {
// @Security AdminAuth
// @Param request body DeleteLogsRequest true "Delete filters"
// @Success 200 {object} ResponseEnvelope{data=DeleteLogsResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H}
// @Failure 500 {object} ResponseEnvelope{data=gin.H}
// @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/logs [delete]
func (h *Handler) DeleteLogs(c *gin.Context) {
var req DeleteLogsRequest
@@ -359,8 +359,8 @@ func (h *Handler) deleteLogsBefore(cutoff time.Time, keyID uint, modelName strin
// @Param group_by query string false "group by dimension: model, day, month, hour, minute. Returns GroupedStatsResponse when specified." Enums(model, day, month, hour, minute)
// @Success 200 {object} ResponseEnvelope{data=LogStatsResponse} "Default aggregated stats (when group_by is not specified)"
// @Success 200 {object} ResponseEnvelope{data=GroupedStatsResponse} "Grouped stats (when group_by is specified)"
// @Failure 400 {object} ResponseEnvelope{data=gin.H}
// @Failure 500 {object} ResponseEnvelope{data=gin.H}
// @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/logs/stats [get]
func (h *Handler) LogStats(c *gin.Context) {
q := h.logBaseQuery()
@@ -768,8 +768,8 @@ func buildTrafficChartSeriesResponse(rows []trafficBucketRow, topN int, granular
// @Param until query int false "End time (unix seconds), defaults to now"
// @Param top_n query int false "Number of top models to return (1-20), defaults to 5"
// @Success 200 {object} ResponseEnvelope{data=TrafficChartResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H}
// @Failure 500 {object} ResponseEnvelope{data=gin.H}
// @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/logs/stats/traffic-chart [get]
func (h *Handler) GetTrafficChart(c *gin.Context) {
// Parse granularity
@@ -870,8 +870,8 @@ func (h *Handler) GetTrafficChart(c *gin.Context) {
// @Param model query string false "model"
// @Param status_code query int false "status code"
// @Success 200 {object} ResponseEnvelope{data=ListMasterLogsResponse}
// @Failure 401 {object} ResponseEnvelope{data=gin.H}
// @Failure 500 {object} ResponseEnvelope{data=gin.H}
// @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/logs [get]
func (h *MasterHandler) ListSelfLogs(c *gin.Context) {
master, exists := c.Get("master")
@@ -929,8 +929,8 @@ func (h *MasterHandler) ListSelfLogs(c *gin.Context) {
// @Param since query int false "unix seconds"
// @Param until query int false "unix seconds"
// @Success 200 {object} ResponseEnvelope{data=LogStatsResponse}
// @Failure 401 {object} ResponseEnvelope{data=gin.H}
// @Failure 500 {object} ResponseEnvelope{data=gin.H}
// @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/logs/stats [get]
func (h *MasterHandler) GetSelfLogStats(c *gin.Context) {
master, exists := c.Get("master")