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

@@ -343,6 +343,8 @@ func main() {
adminGroup.POST("/masters/batch", adminHandler.BatchMasters) adminGroup.POST("/masters/batch", adminHandler.BatchMasters)
adminGroup.POST("/masters/:id/manage", adminHandler.ManageMaster) adminGroup.POST("/masters/:id/manage", adminHandler.ManageMaster)
adminGroup.POST("/masters/:id/keys", adminHandler.IssueChildKeyForMaster) adminGroup.POST("/masters/:id/keys", adminHandler.IssueChildKeyForMaster)
adminGroup.GET("/masters/:id/keys", adminHandler.ListKeysForMaster)
adminGroup.DELETE("/masters/:id/keys/:key_id", adminHandler.DeleteKeyForMaster)
adminGroup.GET("/masters/:id/access", handler.GetMasterAccess) adminGroup.GET("/masters/:id/access", handler.GetMasterAccess)
adminGroup.PUT("/masters/:id/access", handler.UpdateMasterAccess) adminGroup.PUT("/masters/:id/access", handler.UpdateMasterAccess)
adminGroup.GET("/keys/:id/access", handler.GetKeyAccess) adminGroup.GET("/keys/:id/access", handler.GetKeyAccess)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -30,9 +30,9 @@ type UpdateAccessRequest struct {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Master ID" // @Param id path int true "Master ID"
// @Success 200 {object} ResponseEnvelope{data=AccessResponse} // @Success 200 {object} ResponseEnvelope{data=AccessResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters/{id}/access [get] // @Router /admin/masters/{id}/access [get]
func (h *Handler) GetMasterAccess(c *gin.Context) { func (h *Handler) GetMasterAccess(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -62,9 +62,9 @@ func (h *Handler) GetMasterAccess(c *gin.Context) {
// @Param id path int true "Master ID" // @Param id path int true "Master ID"
// @Param request body UpdateAccessRequest true "Access settings" // @Param request body UpdateAccessRequest true "Access settings"
// @Success 200 {object} ResponseEnvelope{data=AccessResponse} // @Success 200 {object} ResponseEnvelope{data=AccessResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters/{id}/access [put] // @Router /admin/masters/{id}/access [put]
func (h *Handler) UpdateMasterAccess(c *gin.Context) { func (h *Handler) UpdateMasterAccess(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -145,9 +145,9 @@ func (h *Handler) UpdateMasterAccess(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Key ID" // @Param id path int true "Key ID"
// @Success 200 {object} ResponseEnvelope{data=AccessResponse} // @Success 200 {object} ResponseEnvelope{data=AccessResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/keys/{id}/access [get] // @Router /admin/keys/{id}/access [get]
func (h *Handler) GetKeyAccess(c *gin.Context) { func (h *Handler) GetKeyAccess(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -175,9 +175,9 @@ func (h *Handler) GetKeyAccess(c *gin.Context) {
// @Param id path int true "Key ID" // @Param id path int true "Key ID"
// @Param request body UpdateAccessRequest true "Access settings" // @Param request body UpdateAccessRequest true "Access settings"
// @Success 200 {object} ResponseEnvelope{data=AccessResponse} // @Success 200 {object} ResponseEnvelope{data=AccessResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/keys/{id}/access [put] // @Router /admin/keys/{id}/access [put]
func (h *Handler) UpdateKeyAccess(c *gin.Context) { func (h *Handler) UpdateKeyAccess(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")

View File

@@ -54,9 +54,9 @@ type CreateMasterRequest struct {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Param master body CreateMasterRequest true "Master Info" // @Param master body CreateMasterRequest true "Master Info"
// @Success 201 {object} ResponseEnvelope{data=gin.H} // @Success 201 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters [post] // @Router /admin/masters [post]
func (h *AdminHandler) CreateMaster(c *gin.Context) { func (h *AdminHandler) CreateMaster(c *gin.Context) {
var req CreateMasterRequest var req CreateMasterRequest
@@ -136,7 +136,7 @@ func toMasterView(m model.Master) MasterView {
// @Param limit query int false "limit (default 50, max 200)" // @Param limit query int false "limit (default 50, max 200)"
// @Param search query string false "search by name/group" // @Param search query string false "search by name/group"
// @Success 200 {object} ResponseEnvelope{data=[]MasterView} // @Success 200 {object} ResponseEnvelope{data=[]MasterView}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters [get] // @Router /admin/masters [get]
func (h *AdminHandler) ListMasters(c *gin.Context) { func (h *AdminHandler) ListMasters(c *gin.Context) {
var masters []model.Master var masters []model.Master
@@ -163,9 +163,9 @@ func (h *AdminHandler) ListMasters(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Master ID" // @Param id path int true "Master ID"
// @Success 200 {object} ResponseEnvelope{data=MasterView} // @Success 200 {object} ResponseEnvelope{data=MasterView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters/{id} [get] // @Router /admin/masters/{id} [get]
func (h *AdminHandler) GetMaster(c *gin.Context) { func (h *AdminHandler) GetMaster(c *gin.Context) {
idRaw := strings.TrimSpace(c.Param("id")) idRaw := strings.TrimSpace(c.Param("id"))
@@ -209,9 +209,9 @@ type UpdateMasterRequest struct {
// @Param id path int true "Master ID" // @Param id path int true "Master ID"
// @Param request body UpdateMasterRequest true "Update payload" // @Param request body UpdateMasterRequest true "Update payload"
// @Success 200 {object} ResponseEnvelope{data=MasterView} // @Success 200 {object} ResponseEnvelope{data=MasterView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters/{id} [put] // @Router /admin/masters/{id} [put]
func (h *AdminHandler) UpdateMaster(c *gin.Context) { func (h *AdminHandler) UpdateMaster(c *gin.Context) {
idRaw := strings.TrimSpace(c.Param("id")) idRaw := strings.TrimSpace(c.Param("id"))
@@ -314,9 +314,9 @@ type ManageMasterRequest struct {
// @Param id path int true "Master ID" // @Param id path int true "Master ID"
// @Param request body ManageMasterRequest true "Action" // @Param request body ManageMasterRequest true "Action"
// @Success 200 {object} ResponseEnvelope{data=MasterView} // @Success 200 {object} ResponseEnvelope{data=MasterView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters/{id}/manage [post] // @Router /admin/masters/{id}/manage [post]
func (h *AdminHandler) ManageMaster(c *gin.Context) { func (h *AdminHandler) ManageMaster(c *gin.Context) {
idRaw := strings.TrimSpace(c.Param("id")) idRaw := strings.TrimSpace(c.Param("id"))
@@ -370,10 +370,10 @@ func (h *AdminHandler) ManageMaster(c *gin.Context) {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Master ID" // @Param id path int true "Master ID"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters/{id} [delete] // @Router /admin/masters/{id} [delete]
func (h *AdminHandler) DeleteMaster(c *gin.Context) { func (h *AdminHandler) DeleteMaster(c *gin.Context) {
idRaw := strings.TrimSpace(c.Param("id")) idRaw := strings.TrimSpace(c.Param("id"))
@@ -404,11 +404,11 @@ func (h *AdminHandler) DeleteMaster(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Master ID" // @Param id path int true "Master ID"
// @Param request body IssueChildKeyRequest true "Key Request" // @Param request body IssueChildKeyRequest true "Key Request"
// @Success 201 {object} ResponseEnvelope{data=gin.H} // @Success 201 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 403 {object} ResponseEnvelope{data=gin.H} // @Failure 403 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters/{id}/keys [post] // @Router /admin/masters/{id}/keys [post]
func (h *AdminHandler) IssueChildKeyForMaster(c *gin.Context) { func (h *AdminHandler) IssueChildKeyForMaster(c *gin.Context) {
idRaw := strings.TrimSpace(c.Param("id")) idRaw := strings.TrimSpace(c.Param("id"))
@@ -477,3 +477,89 @@ func (h *AdminHandler) IssueChildKeyForMaster(c *gin.Context) {
"issued_by": key.IssuedBy, "issued_by": key.IssuedBy,
}) })
} }
// ListKeysForMaster godoc
// @Summary List child keys for a master
// @Description List child keys issued under a master (admin view)
// @Tags admin
// @Produce json
// @Security AdminAuth
// @Param id path int true "Master ID"
// @Param page query int false "page (1-based)"
// @Param limit query int false "limit (default 50, max 200)"
// @Param search query string false "search by group/scopes/namespaces/status"
// @Success 200 {object} ResponseEnvelope{data=[]TokenView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H}
// @Failure 500 {object} ResponseEnvelope{data=gin.H}
// @Router /admin/masters/{id}/keys [get]
func (h *AdminHandler) ListKeysForMaster(c *gin.Context) {
masterID, ok := parseUintParam(c, "id")
if !ok {
return
}
var keys []model.Key
q := h.db.Model(&model.Key{}).Where("master_id = ?", masterID).Order("id desc")
query := parseListQuery(c)
q = applyListSearch(q, query.Search, `"group"`, "scopes", "default_namespace", "namespaces", "status")
q = applyListPagination(q, query)
if err := q.Find(&keys).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list tokens", "details": err.Error()})
return
}
out := make([]TokenView, 0, len(keys))
for _, k := range keys {
out = append(out, toTokenView(k))
}
c.JSON(http.StatusOK, out)
}
// DeleteKeyForMaster godoc
// @Summary Delete (revoke) child key
// @Description Suspends a child key under the specified master
// @Tags admin
// @Produce json
// @Security AdminAuth
// @Param id path int true "Master ID"
// @Param key_id path int true "Token ID"
// @Success 200 {object} ResponseEnvelope{data=gin.H}
// @Failure 400 {object} ResponseEnvelope{data=gin.H}
// @Failure 404 {object} ResponseEnvelope{data=gin.H}
// @Failure 500 {object} ResponseEnvelope{data=gin.H}
// @Router /admin/masters/{id}/keys/{key_id} [delete]
func (h *AdminHandler) DeleteKeyForMaster(c *gin.Context) {
masterID, ok := parseUintParam(c, "id")
if !ok {
return
}
keyID, ok := parseUintParam(c, "key_id")
if !ok {
return
}
var k model.Key
if err := h.db.Where("master_id = ? AND id = ?", masterID, keyID).First(&k).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
c.JSON(http.StatusNotFound, gin.H{"error": "token not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to load token", "details": err.Error()})
return
}
if err := h.db.Model(&k).Update("status", "suspended").Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to revoke token", "details": err.Error()})
return
}
if err := h.db.Where("master_id = ? AND id = ?", masterID, keyID).First(&k).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to reload token", "details": err.Error()})
return
}
if err := h.syncService.SyncKey(&k); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to sync token", "details": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "revoked"})
}

View File

@@ -91,7 +91,7 @@ type ListAlertsResponse struct {
// @Param severity query string false "filter by severity (info, warning, critical)" // @Param severity query string false "filter by severity (info, warning, critical)"
// @Param type query string false "filter by type (rate_limit, error_spike, quota_exceeded, key_disabled, key_expired, provider_down, traffic_spike)" // @Param type query string false "filter by type (rate_limit, error_spike, quota_exceeded, key_disabled, key_expired, provider_down, traffic_spike)"
// @Success 200 {object} ResponseEnvelope{data=ListAlertsResponse} // @Success 200 {object} ResponseEnvelope{data=ListAlertsResponse}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/alerts [get] // @Router /admin/alerts [get]
func (h *AlertHandler) ListAlerts(c *gin.Context) { func (h *AlertHandler) ListAlerts(c *gin.Context) {
limit, offset := parseLimitOffset(c) limit, offset := parseLimitOffset(c)
@@ -141,8 +141,8 @@ func (h *AlertHandler) ListAlerts(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Alert ID" // @Param id path int true "Alert ID"
// @Success 200 {object} ResponseEnvelope{data=AlertView} // @Success 200 {object} ResponseEnvelope{data=AlertView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Router /admin/alerts/{id} [get] // @Router /admin/alerts/{id} [get]
func (h *AlertHandler) GetAlert(c *gin.Context) { func (h *AlertHandler) GetAlert(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -181,8 +181,8 @@ type CreateAlertRequest struct {
// @Security AdminAuth // @Security AdminAuth
// @Param request body CreateAlertRequest true "Alert data" // @Param request body CreateAlertRequest true "Alert data"
// @Success 201 {object} ResponseEnvelope{data=AlertView} // @Success 201 {object} ResponseEnvelope{data=AlertView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/alerts [post] // @Router /admin/alerts [post]
func (h *AlertHandler) CreateAlert(c *gin.Context) { func (h *AlertHandler) CreateAlert(c *gin.Context) {
var req CreateAlertRequest var req CreateAlertRequest
@@ -248,9 +248,9 @@ type AckAlertRequest struct {
// @Param id path int true "Alert ID" // @Param id path int true "Alert ID"
// @Param request body AckAlertRequest false "Ack data" // @Param request body AckAlertRequest false "Ack data"
// @Success 200 {object} ResponseEnvelope{data=AlertView} // @Success 200 {object} ResponseEnvelope{data=AlertView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/alerts/{id}/ack [post] // @Router /admin/alerts/{id}/ack [post]
func (h *AlertHandler) AcknowledgeAlert(c *gin.Context) { func (h *AlertHandler) AcknowledgeAlert(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -295,9 +295,9 @@ func (h *AlertHandler) AcknowledgeAlert(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Alert ID" // @Param id path int true "Alert ID"
// @Success 200 {object} ResponseEnvelope{data=AlertView} // @Success 200 {object} ResponseEnvelope{data=AlertView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/alerts/{id}/resolve [post] // @Router /admin/alerts/{id}/resolve [post]
func (h *AlertHandler) ResolveAlert(c *gin.Context) { func (h *AlertHandler) ResolveAlert(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -337,10 +337,10 @@ func (h *AlertHandler) ResolveAlert(c *gin.Context) {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Alert ID" // @Param id path int true "Alert ID"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/alerts/{id} [delete] // @Router /admin/alerts/{id} [delete]
func (h *AlertHandler) DismissAlert(c *gin.Context) { func (h *AlertHandler) DismissAlert(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -380,7 +380,7 @@ type AlertStats struct {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Success 200 {object} ResponseEnvelope{data=AlertStats} // @Success 200 {object} ResponseEnvelope{data=AlertStats}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/alerts/stats [get] // @Router /admin/alerts/stats [get]
func (h *AlertHandler) GetAlertStats(c *gin.Context) { func (h *AlertHandler) GetAlertStats(c *gin.Context) {
var total, active, acknowledged, resolved, critical, warning, info int64 var total, active, acknowledged, resolved, critical, warning, info int64
@@ -436,7 +436,7 @@ func toAlertThresholdView(cfg model.AlertThresholdConfig) AlertThresholdView {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Success 200 {object} ResponseEnvelope{data=AlertThresholdView} // @Success 200 {object} ResponseEnvelope{data=AlertThresholdView}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/alerts/thresholds [get] // @Router /admin/alerts/thresholds [get]
func (h *AlertHandler) GetAlertThresholds(c *gin.Context) { func (h *AlertHandler) GetAlertThresholds(c *gin.Context) {
cfg, err := h.loadThresholdConfig() cfg, err := h.loadThresholdConfig()
@@ -467,8 +467,8 @@ type UpdateAlertThresholdsRequest struct {
// @Security AdminAuth // @Security AdminAuth
// @Param request body UpdateAlertThresholdsRequest true "Threshold configuration" // @Param request body UpdateAlertThresholdsRequest true "Threshold configuration"
// @Success 200 {object} ResponseEnvelope{data=AlertThresholdView} // @Success 200 {object} ResponseEnvelope{data=AlertThresholdView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/alerts/thresholds [put] // @Router /admin/alerts/thresholds [put]
func (h *AlertHandler) UpdateAlertThresholds(c *gin.Context) { func (h *AlertHandler) UpdateAlertThresholds(c *gin.Context) {
var req UpdateAlertThresholdsRequest var req UpdateAlertThresholdsRequest

View File

@@ -18,8 +18,8 @@ import (
// @Security AdminAuth // @Security AdminAuth
// @Param key body dto.APIKeyDTO true "API key payload" // @Param key body dto.APIKeyDTO true "API key payload"
// @Success 201 {object} ResponseEnvelope{data=model.APIKey} // @Success 201 {object} ResponseEnvelope{data=model.APIKey}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/api-keys [post] // @Router /admin/api-keys [post]
func (h *Handler) CreateAPIKey(c *gin.Context) { func (h *Handler) CreateAPIKey(c *gin.Context) {
var req dto.APIKeyDTO var req dto.APIKeyDTO
@@ -101,7 +101,7 @@ func (h *Handler) CreateAPIKey(c *gin.Context) {
// @Param group_id query int false "filter by group_id" // @Param group_id query int false "filter by group_id"
// @Param status query string false "filter by status (active, suspended, auto_disabled, manual_disabled)" // @Param status query string false "filter by status (active, suspended, auto_disabled, manual_disabled)"
// @Success 200 {object} ResponseEnvelope{data=[]model.APIKey} // @Success 200 {object} ResponseEnvelope{data=[]model.APIKey}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/api-keys [get] // @Router /admin/api-keys [get]
func (h *Handler) ListAPIKeys(c *gin.Context) { func (h *Handler) ListAPIKeys(c *gin.Context) {
var keys []model.APIKey var keys []model.APIKey
@@ -129,9 +129,9 @@ func (h *Handler) ListAPIKeys(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "APIKey ID" // @Param id path int true "APIKey ID"
// @Success 200 {object} ResponseEnvelope{data=model.APIKey} // @Success 200 {object} ResponseEnvelope{data=model.APIKey}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/api-keys/{id} [get] // @Router /admin/api-keys/{id} [get]
func (h *Handler) GetAPIKey(c *gin.Context) { func (h *Handler) GetAPIKey(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -156,9 +156,9 @@ func (h *Handler) GetAPIKey(c *gin.Context) {
// @Param id path int true "APIKey ID" // @Param id path int true "APIKey ID"
// @Param key body dto.APIKeyDTO true "API key payload" // @Param key body dto.APIKeyDTO true "API key payload"
// @Success 200 {object} ResponseEnvelope{data=model.APIKey} // @Success 200 {object} ResponseEnvelope{data=model.APIKey}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/api-keys/{id} [put] // @Router /admin/api-keys/{id} [put]
func (h *Handler) UpdateAPIKey(c *gin.Context) { func (h *Handler) UpdateAPIKey(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -275,10 +275,10 @@ func (h *Handler) UpdateAPIKey(c *gin.Context) {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "APIKey ID" // @Param id path int true "APIKey ID"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/api-keys/{id} [delete] // @Router /admin/api-keys/{id} [delete]
func (h *Handler) DeleteAPIKey(c *gin.Context) { func (h *Handler) DeleteAPIKey(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")

View File

@@ -26,7 +26,7 @@ type APIKeyStatsSummaryResponse struct {
// @Param since query int false "Start time (unix seconds)" // @Param since query int false "Start time (unix seconds)"
// @Param until query int false "End time (unix seconds)" // @Param until query int false "End time (unix seconds)"
// @Success 200 {object} ResponseEnvelope{data=APIKeyStatsSummaryResponse} // @Success 200 {object} ResponseEnvelope{data=APIKeyStatsSummaryResponse}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/apikey-stats/summary [get] // @Router /admin/apikey-stats/summary [get]
func (h *AdminHandler) GetAPIKeyStatsSummary(c *gin.Context) { func (h *AdminHandler) GetAPIKeyStatsSummary(c *gin.Context) {
if h == nil || h.db == nil { if h == nil || h.db == nil {

View File

@@ -172,7 +172,7 @@ type WhoamiResponse struct {
// @Security AdminAuth // @Security AdminAuth
// @Security MasterAuth // @Security MasterAuth
// @Success 200 {object} ResponseEnvelope{data=WhoamiResponse} // @Success 200 {object} ResponseEnvelope{data=WhoamiResponse}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} "Invalid or missing token" // @Failure 401 {object} ResponseEnvelope{data=MapData} "Invalid or missing token"
// @Router /auth/whoami [get] // @Router /auth/whoami [get]
func (h *AuthHandler) Whoami(c *gin.Context) { func (h *AuthHandler) Whoami(c *gin.Context) {
authHeader := c.GetHeader("Authorization") authHeader := c.GetHeader("Authorization")

View File

@@ -58,8 +58,8 @@ func isAllowedStatus(raw string, allowed ...string) bool {
// @Security AdminAuth // @Security AdminAuth
// @Param request body BatchActionRequest true "Batch payload" // @Param request body BatchActionRequest true "Batch payload"
// @Success 200 {object} ResponseEnvelope{data=BatchResponse} // @Success 200 {object} ResponseEnvelope{data=BatchResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters/batch [post] // @Router /admin/masters/batch [post]
func (h *AdminHandler) BatchMasters(c *gin.Context) { func (h *AdminHandler) BatchMasters(c *gin.Context) {
var req BatchActionRequest var req BatchActionRequest
@@ -113,8 +113,8 @@ func (h *AdminHandler) BatchMasters(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param request body BatchActionRequest true "Batch payload" // @Param request body BatchActionRequest true "Batch payload"
// @Success 200 {object} ResponseEnvelope{data=BatchResponse} // @Success 200 {object} ResponseEnvelope{data=BatchResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/api-keys/batch [post] // @Router /admin/api-keys/batch [post]
func (h *Handler) BatchAPIKeys(c *gin.Context) { func (h *Handler) BatchAPIKeys(c *gin.Context) {
var req BatchActionRequest var req BatchActionRequest
@@ -197,8 +197,8 @@ func (h *Handler) BatchAPIKeys(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param request body BatchActionRequest true "Batch payload" // @Param request body BatchActionRequest true "Batch payload"
// @Success 200 {object} ResponseEnvelope{data=BatchResponse} // @Success 200 {object} ResponseEnvelope{data=BatchResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/models/batch [post] // @Router /admin/models/batch [post]
func (h *Handler) BatchModels(c *gin.Context) { func (h *Handler) BatchModels(c *gin.Context) {
var req BatchActionRequest var req BatchActionRequest
@@ -249,8 +249,8 @@ func (h *Handler) BatchModels(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param request body BatchActionRequest true "Batch payload" // @Param request body BatchActionRequest true "Batch payload"
// @Success 200 {object} ResponseEnvelope{data=BatchResponse} // @Success 200 {object} ResponseEnvelope{data=BatchResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/bindings/batch [post] // @Router /admin/bindings/batch [post]
func (h *Handler) BatchBindings(c *gin.Context) { func (h *Handler) BatchBindings(c *gin.Context) {
var req BatchActionRequest var req BatchActionRequest

View File

@@ -20,8 +20,8 @@ import (
// @Security AdminAuth // @Security AdminAuth
// @Param binding body dto.BindingDTO true "Binding Info" // @Param binding body dto.BindingDTO true "Binding Info"
// @Success 201 {object} ResponseEnvelope{data=model.Binding} // @Success 201 {object} ResponseEnvelope{data=model.Binding}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/bindings [post] // @Router /admin/bindings [post]
func (h *Handler) CreateBinding(c *gin.Context) { func (h *Handler) CreateBinding(c *gin.Context) {
var req dto.BindingDTO var req dto.BindingDTO
@@ -85,7 +85,7 @@ func (h *Handler) CreateBinding(c *gin.Context) {
// @Param limit query int false "limit (default 50, max 200)" // @Param limit query int false "limit (default 50, max 200)"
// @Param search query string false "search by namespace/public_model" // @Param search query string false "search by namespace/public_model"
// @Success 200 {object} ResponseEnvelope{data=[]model.Binding} // @Success 200 {object} ResponseEnvelope{data=[]model.Binding}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/bindings [get] // @Router /admin/bindings [get]
func (h *Handler) ListBindings(c *gin.Context) { func (h *Handler) ListBindings(c *gin.Context) {
var out []model.Binding var out []model.Binding
@@ -110,9 +110,9 @@ func (h *Handler) ListBindings(c *gin.Context) {
// @Param id path int true "Binding ID" // @Param id path int true "Binding ID"
// @Param binding body dto.BindingDTO true "Binding Info" // @Param binding body dto.BindingDTO true "Binding Info"
// @Success 200 {object} ResponseEnvelope{data=model.Binding} // @Success 200 {object} ResponseEnvelope{data=model.Binding}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/bindings/{id} [put] // @Router /admin/bindings/{id} [put]
func (h *Handler) UpdateBinding(c *gin.Context) { func (h *Handler) UpdateBinding(c *gin.Context) {
idParam := c.Param("id") idParam := c.Param("id")
@@ -181,9 +181,9 @@ func (h *Handler) UpdateBinding(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Binding ID" // @Param id path int true "Binding ID"
// @Success 200 {object} ResponseEnvelope{data=model.Binding} // @Success 200 {object} ResponseEnvelope{data=model.Binding}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/bindings/{id} [get] // @Router /admin/bindings/{id} [get]
func (h *Handler) GetBinding(c *gin.Context) { func (h *Handler) GetBinding(c *gin.Context) {
idParam := c.Param("id") idParam := c.Param("id")
@@ -207,10 +207,10 @@ func (h *Handler) GetBinding(c *gin.Context) {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Binding ID" // @Param id path int true "Binding ID"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/bindings/{id} [delete] // @Router /admin/bindings/{id} [delete]
func (h *Handler) DeleteBinding(c *gin.Context) { func (h *Handler) DeleteBinding(c *gin.Context) {
idParam := c.Param("id") idParam := c.Param("id")

View File

@@ -188,8 +188,8 @@ type DashboardSummaryResponse struct {
// @Param until query int false "unix seconds" // @Param until query int false "unix seconds"
// @Param include_trends query bool false "include trend data comparing to previous period" // @Param include_trends query bool false "include trend data comparing to previous period"
// @Success 200 {object} ResponseEnvelope{data=DashboardSummaryResponse} // @Success 200 {object} ResponseEnvelope{data=DashboardSummaryResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/dashboard/summary [get] // @Router /admin/dashboard/summary [get]
func (h *DashboardHandler) GetSummary(c *gin.Context) { func (h *DashboardHandler) GetSummary(c *gin.Context) {
rng, err := parseStatsRange(c) rng, err := parseStatsRange(c)

View File

@@ -37,8 +37,8 @@ func NewFeatureHandler(rdb *redis.Client) *FeatureHandler {
// @Tags admin // @Tags admin
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/features [get] // @Router /admin/features [get]
func (h *FeatureHandler) ListFeatures(c *gin.Context) { func (h *FeatureHandler) ListFeatures(c *gin.Context) {
if h.rdb == nil { if h.rdb == nil {
@@ -75,9 +75,9 @@ type UpdateFeaturesRequest map[string]any
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Param request body object true "Feature map" // @Param request body object true "Feature map"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/features [put] // @Router /admin/features [put]
func (h *FeatureHandler) UpdateFeatures(c *gin.Context) { func (h *FeatureHandler) UpdateFeatures(c *gin.Context) {
if h.rdb == nil { if h.rdb == nil {

View File

@@ -63,8 +63,8 @@ func (h *Handler) logBaseQuery() *gorm.DB {
// @Security AdminAuth // @Security AdminAuth
// @Param model body dto.ModelDTO true "Model Info" // @Param model body dto.ModelDTO true "Model Info"
// @Success 201 {object} ResponseEnvelope{data=model.Model} // @Success 201 {object} ResponseEnvelope{data=model.Model}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/models [post] // @Router /admin/models [post]
func (h *Handler) CreateModel(c *gin.Context) { func (h *Handler) CreateModel(c *gin.Context) {
var req dto.ModelDTO var req dto.ModelDTO
@@ -124,7 +124,7 @@ func (h *Handler) CreateModel(c *gin.Context) {
// @Param limit query int false "limit (default 50, max 200)" // @Param limit query int false "limit (default 50, max 200)"
// @Param search query string false "search by name/kind" // @Param search query string false "search by name/kind"
// @Success 200 {object} ResponseEnvelope{data=[]model.Model} // @Success 200 {object} ResponseEnvelope{data=[]model.Model}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/models [get] // @Router /admin/models [get]
func (h *Handler) ListModels(c *gin.Context) { func (h *Handler) ListModels(c *gin.Context) {
var models []model.Model var models []model.Model
@@ -149,9 +149,9 @@ func (h *Handler) ListModels(c *gin.Context) {
// @Param id path int true "Model ID" // @Param id path int true "Model ID"
// @Param model body dto.ModelDTO true "Model Info" // @Param model body dto.ModelDTO true "Model Info"
// @Success 200 {object} ResponseEnvelope{data=model.Model} // @Success 200 {object} ResponseEnvelope{data=model.Model}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/models/{id} [put] // @Router /admin/models/{id} [put]
func (h *Handler) UpdateModel(c *gin.Context) { func (h *Handler) UpdateModel(c *gin.Context) {
idParam := c.Param("id") idParam := c.Param("id")
@@ -222,10 +222,10 @@ func (h *Handler) UpdateModel(c *gin.Context) {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Model ID" // @Param id path int true "Model ID"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/models/{id} [delete] // @Router /admin/models/{id} [delete]
func (h *Handler) DeleteModel(c *gin.Context) { func (h *Handler) DeleteModel(c *gin.Context) {
idParam := c.Param("id") idParam := c.Param("id")
@@ -260,8 +260,8 @@ func (h *Handler) DeleteModel(c *gin.Context) {
// @Tags admin // @Tags admin
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/sync/snapshot [post] // @Router /admin/sync/snapshot [post]
func (h *Handler) SyncSnapshot(c *gin.Context) { func (h *Handler) SyncSnapshot(c *gin.Context) {
if err := h.sync.SyncAll(h.db); err != nil { if err := h.sync.SyncAll(h.db); err != nil {
@@ -278,8 +278,8 @@ func (h *Handler) SyncSnapshot(c *gin.Context) {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param log body model.LogRecord true "Log Record" // @Param log body model.LogRecord true "Log Record"
// @Success 202 {object} ResponseEnvelope{data=gin.H} // @Success 202 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Router /logs [post] // @Router /logs [post]
func (h *Handler) IngestLog(c *gin.Context) { func (h *Handler) IngestLog(c *gin.Context) {
var rec model.LogRecord var rec model.LogRecord

View File

@@ -47,9 +47,9 @@ type apiKeyStatsFlushEntry struct {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param request body statsFlushRequest true "Stats to flush" // @Param request body statsFlushRequest true "Stats to flush"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /internal/stats/flush [post] // @Router /internal/stats/flush [post]
func (h *InternalHandler) FlushStats(c *gin.Context) { func (h *InternalHandler) FlushStats(c *gin.Context) {
if h == nil || h.db == nil { if h == nil || h.db == nil {
@@ -124,9 +124,9 @@ func (h *InternalHandler) FlushStats(c *gin.Context) {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param request body apiKeyStatsFlushRequest true "Stats to flush" // @Param request body apiKeyStatsFlushRequest true "Stats to flush"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /internal/apikey-stats/flush [post] // @Router /internal/apikey-stats/flush [post]
func (h *InternalHandler) FlushAPIKeyStats(c *gin.Context) { func (h *InternalHandler) FlushAPIKeyStats(c *gin.Context) {
if h == nil || h.db == nil { if h == nil || h.db == nil {
@@ -288,8 +288,8 @@ const alertDeduplicationCooldown = 5 * time.Minute
// @Produce json // @Produce json
// @Param request body reportAlertsRequest true "Alerts to report" // @Param request body reportAlertsRequest true "Alerts to report"
// @Success 200 {object} ResponseEnvelope{data=reportAlertsResponse} // @Success 200 {object} ResponseEnvelope{data=reportAlertsResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /internal/alerts/report [post] // @Router /internal/alerts/report [post]
func (h *InternalHandler) ReportAlerts(c *gin.Context) { func (h *InternalHandler) ReportAlerts(c *gin.Context) {
if h == nil || h.db == nil { if h == nil || h.db == nil {

View File

@@ -90,9 +90,9 @@ func toIPBanView(ban *model.IPBan) IPBanView {
// @Security AdminAuth // @Security AdminAuth
// @Param ban body CreateIPBanRequest true "IP Ban Info" // @Param ban body CreateIPBanRequest true "IP Ban Info"
// @Success 201 {object} ResponseEnvelope{data=IPBanView} // @Success 201 {object} ResponseEnvelope{data=IPBanView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 409 {object} ResponseEnvelope{data=gin.H} // @Failure 409 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/ip-bans [post] // @Router /admin/ip-bans [post]
func (h *IPBanHandler) Create(c *gin.Context) { func (h *IPBanHandler) Create(c *gin.Context) {
var req CreateIPBanRequest var req CreateIPBanRequest
@@ -140,7 +140,7 @@ func (h *IPBanHandler) Create(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param status query string false "Filter by status (active, expired)" // @Param status query string false "Filter by status (active, expired)"
// @Success 200 {object} ResponseEnvelope{data=[]IPBanView} // @Success 200 {object} ResponseEnvelope{data=[]IPBanView}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/ip-bans [get] // @Router /admin/ip-bans [get]
func (h *IPBanHandler) List(c *gin.Context) { func (h *IPBanHandler) List(c *gin.Context) {
status := c.Query("status") status := c.Query("status")
@@ -168,8 +168,8 @@ func (h *IPBanHandler) List(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "IP Ban ID" // @Param id path int true "IP Ban ID"
// @Success 200 {object} ResponseEnvelope{data=IPBanView} // @Success 200 {object} ResponseEnvelope{data=IPBanView}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/ip-bans/{id} [get] // @Router /admin/ip-bans/{id} [get]
func (h *IPBanHandler) Get(c *gin.Context) { func (h *IPBanHandler) Get(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 64) id, err := strconv.ParseUint(c.Param("id"), 10, 64)
@@ -201,10 +201,10 @@ func (h *IPBanHandler) Get(c *gin.Context) {
// @Param id path int true "IP Ban ID" // @Param id path int true "IP Ban ID"
// @Param ban body UpdateIPBanRequest true "IP Ban Update" // @Param ban body UpdateIPBanRequest true "IP Ban Update"
// @Success 200 {object} ResponseEnvelope{data=IPBanView} // @Success 200 {object} ResponseEnvelope{data=IPBanView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 409 {object} ResponseEnvelope{data=gin.H} // @Failure 409 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/ip-bans/{id} [put] // @Router /admin/ip-bans/{id} [put]
func (h *IPBanHandler) Update(c *gin.Context) { func (h *IPBanHandler) Update(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 64) id, err := strconv.ParseUint(c.Param("id"), 10, 64)
@@ -250,8 +250,8 @@ func (h *IPBanHandler) Update(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "IP Ban ID" // @Param id path int true "IP Ban ID"
// @Success 204 // @Success 204
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/ip-bans/{id} [delete] // @Router /admin/ip-bans/{id} [delete]
func (h *IPBanHandler) Delete(c *gin.Context) { func (h *IPBanHandler) Delete(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 64) id, err := strconv.ParseUint(c.Param("id"), 10, 64)

View File

@@ -168,7 +168,7 @@ func (h *MasterHandler) masterLogBase(masterID uint) (*gorm.DB, error) {
// @Param model query string false "model" // @Param model query string false "model"
// @Param status_code query int false "status code" // @Param status_code query int false "status code"
// @Success 200 {object} ResponseEnvelope{data=ListLogsResponse} // @Success 200 {object} ResponseEnvelope{data=ListLogsResponse}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/logs [get] // @Router /admin/logs [get]
func (h *Handler) ListLogs(c *gin.Context) { func (h *Handler) ListLogs(c *gin.Context) {
limit, offset := parseLimitOffset(c) limit, offset := parseLimitOffset(c)
@@ -268,8 +268,8 @@ type DeleteLogsResponse struct {
// @Security AdminAuth // @Security AdminAuth
// @Param request body DeleteLogsRequest true "Delete filters" // @Param request body DeleteLogsRequest true "Delete filters"
// @Success 200 {object} ResponseEnvelope{data=DeleteLogsResponse} // @Success 200 {object} ResponseEnvelope{data=DeleteLogsResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/logs [delete] // @Router /admin/logs [delete]
func (h *Handler) DeleteLogs(c *gin.Context) { func (h *Handler) DeleteLogs(c *gin.Context) {
var req DeleteLogsRequest 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) // @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=LogStatsResponse} "Default aggregated stats (when group_by is not specified)"
// @Success 200 {object} ResponseEnvelope{data=GroupedStatsResponse} "Grouped stats (when group_by is specified)" // @Success 200 {object} ResponseEnvelope{data=GroupedStatsResponse} "Grouped stats (when group_by is specified)"
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/logs/stats [get] // @Router /admin/logs/stats [get]
func (h *Handler) LogStats(c *gin.Context) { func (h *Handler) LogStats(c *gin.Context) {
q := h.logBaseQuery() 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 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" // @Param top_n query int false "Number of top models to return (1-20), defaults to 5"
// @Success 200 {object} ResponseEnvelope{data=TrafficChartResponse} // @Success 200 {object} ResponseEnvelope{data=TrafficChartResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/logs/stats/traffic-chart [get] // @Router /admin/logs/stats/traffic-chart [get]
func (h *Handler) GetTrafficChart(c *gin.Context) { func (h *Handler) GetTrafficChart(c *gin.Context) {
// Parse granularity // Parse granularity
@@ -870,8 +870,8 @@ func (h *Handler) GetTrafficChart(c *gin.Context) {
// @Param model query string false "model" // @Param model query string false "model"
// @Param status_code query int false "status code" // @Param status_code query int false "status code"
// @Success 200 {object} ResponseEnvelope{data=ListMasterLogsResponse} // @Success 200 {object} ResponseEnvelope{data=ListMasterLogsResponse}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} // @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/logs [get] // @Router /v1/logs [get]
func (h *MasterHandler) ListSelfLogs(c *gin.Context) { func (h *MasterHandler) ListSelfLogs(c *gin.Context) {
master, exists := c.Get("master") master, exists := c.Get("master")
@@ -929,8 +929,8 @@ func (h *MasterHandler) ListSelfLogs(c *gin.Context) {
// @Param since query int false "unix seconds" // @Param since query int false "unix seconds"
// @Param until query int false "unix seconds" // @Param until query int false "unix seconds"
// @Success 200 {object} ResponseEnvelope{data=LogStatsResponse} // @Success 200 {object} ResponseEnvelope{data=LogStatsResponse}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} // @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/logs/stats [get] // @Router /v1/logs/stats [get]
func (h *MasterHandler) GetSelfLogStats(c *gin.Context) { func (h *MasterHandler) GetSelfLogStats(c *gin.Context) {
master, exists := c.Get("master") master, exists := c.Get("master")

View File

@@ -14,7 +14,7 @@ import (
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Success 200 {object} ResponseEnvelope{data=service.LogWebhookConfig} // @Success 200 {object} ResponseEnvelope{data=service.LogWebhookConfig}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/logs/webhook [get] // @Router /admin/logs/webhook [get]
func (h *Handler) GetLogWebhookConfig(c *gin.Context) { func (h *Handler) GetLogWebhookConfig(c *gin.Context) {
if h == nil || h.logWebhook == nil { if h == nil || h.logWebhook == nil {
@@ -38,8 +38,8 @@ func (h *Handler) GetLogWebhookConfig(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param request body service.LogWebhookConfig true "Webhook config" // @Param request body service.LogWebhookConfig true "Webhook config"
// @Success 200 {object} ResponseEnvelope{data=service.LogWebhookConfig} // @Success 200 {object} ResponseEnvelope{data=service.LogWebhookConfig}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/logs/webhook [put] // @Router /admin/logs/webhook [put]
func (h *Handler) UpdateLogWebhookConfig(c *gin.Context) { func (h *Handler) UpdateLogWebhookConfig(c *gin.Context) {
if h == nil || h.logWebhook == nil { if h == nil || h.logWebhook == nil {

View File

@@ -58,11 +58,11 @@ type IssueChildKeyRequest struct {
// @Produce json // @Produce json
// @Security MasterAuth // @Security MasterAuth
// @Param request body IssueChildKeyRequest true "Key Request" // @Param request body IssueChildKeyRequest true "Key Request"
// @Success 201 {object} ResponseEnvelope{data=gin.H} // @Success 201 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} // @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 403 {object} ResponseEnvelope{data=gin.H} // @Failure 403 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/tokens [post] // @Router /v1/tokens [post]
func (h *MasterHandler) IssueChildKey(c *gin.Context) { func (h *MasterHandler) IssueChildKey(c *gin.Context) {
master, exists := c.Get("master") master, exists := c.Get("master")
@@ -146,7 +146,7 @@ func (h *MasterHandler) IssueChildKey(c *gin.Context) {
// @Produce json // @Produce json
// @Security MasterAuth // @Security MasterAuth
// @Success 200 {object} ResponseEnvelope{data=MasterView} // @Success 200 {object} ResponseEnvelope{data=MasterView}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} // @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Router /v1/self [get] // @Router /v1/self [get]
func (h *MasterHandler) GetSelf(c *gin.Context) { func (h *MasterHandler) GetSelf(c *gin.Context) {
master, exists := c.Get("master") master, exists := c.Get("master")
@@ -220,8 +220,8 @@ func toTokenView(k model.Key) TokenView {
// @Param limit query int false "limit (default 50, max 200)" // @Param limit query int false "limit (default 50, max 200)"
// @Param search query string false "search by group/scopes/namespaces/status" // @Param search query string false "search by group/scopes/namespaces/status"
// @Success 200 {object} ResponseEnvelope{data=[]TokenView} // @Success 200 {object} ResponseEnvelope{data=[]TokenView}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} // @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/tokens [get] // @Router /v1/tokens [get]
func (h *MasterHandler) ListTokens(c *gin.Context) { func (h *MasterHandler) ListTokens(c *gin.Context) {
master, exists := c.Get("master") master, exists := c.Get("master")
@@ -255,10 +255,10 @@ func (h *MasterHandler) ListTokens(c *gin.Context) {
// @Security MasterAuth // @Security MasterAuth
// @Param id path int true "Token ID" // @Param id path int true "Token ID"
// @Success 200 {object} ResponseEnvelope{data=TokenView} // @Success 200 {object} ResponseEnvelope{data=TokenView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} // @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/tokens/{id} [get] // @Router /v1/tokens/{id} [get]
func (h *MasterHandler) GetToken(c *gin.Context) { func (h *MasterHandler) GetToken(c *gin.Context) {
master, exists := c.Get("master") master, exists := c.Get("master")
@@ -303,10 +303,10 @@ type UpdateTokenRequest struct {
// @Param id path int true "Token ID" // @Param id path int true "Token ID"
// @Param request body UpdateTokenRequest true "Update payload" // @Param request body UpdateTokenRequest true "Update payload"
// @Success 200 {object} ResponseEnvelope{data=TokenView} // @Success 200 {object} ResponseEnvelope{data=TokenView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} // @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/tokens/{id} [put] // @Router /v1/tokens/{id} [put]
func (h *MasterHandler) UpdateToken(c *gin.Context) { func (h *MasterHandler) UpdateToken(c *gin.Context) {
master, exists := c.Get("master") master, exists := c.Get("master")
@@ -398,11 +398,11 @@ func (h *MasterHandler) UpdateToken(c *gin.Context) {
// @Produce json // @Produce json
// @Security MasterAuth // @Security MasterAuth
// @Param id path int true "Token ID" // @Param id path int true "Token ID"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} // @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/tokens/{id} [delete] // @Router /v1/tokens/{id} [delete]
func (h *MasterHandler) DeleteToken(c *gin.Context) { func (h *MasterHandler) DeleteToken(c *gin.Context) {
master, exists := c.Get("master") master, exists := c.Get("master")

View File

@@ -23,7 +23,7 @@ func NewModelRegistryHandler(reg *service.ModelRegistryService) *ModelRegistryHa
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Success 200 {object} ResponseEnvelope{data=service.ModelRegistryStatus} // @Success 200 {object} ResponseEnvelope{data=service.ModelRegistryStatus}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/model-registry/status [get] // @Router /admin/model-registry/status [get]
func (h *ModelRegistryHandler) GetStatus(c *gin.Context) { func (h *ModelRegistryHandler) GetStatus(c *gin.Context) {
if h == nil || h.reg == nil { if h == nil || h.reg == nil {
@@ -51,8 +51,8 @@ type refreshModelRegistryRequest struct {
// @Security AdminAuth // @Security AdminAuth
// @Param body body refreshModelRegistryRequest false "optional override ref" // @Param body body refreshModelRegistryRequest false "optional override ref"
// @Success 200 {object} ResponseEnvelope{data=service.ModelRegistryCheckResult} // @Success 200 {object} ResponseEnvelope{data=service.ModelRegistryCheckResult}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/model-registry/check [post] // @Router /admin/model-registry/check [post]
func (h *ModelRegistryHandler) Check(c *gin.Context) { func (h *ModelRegistryHandler) Check(c *gin.Context) {
if h == nil || h.reg == nil { if h == nil || h.reg == nil {
@@ -78,9 +78,9 @@ func (h *ModelRegistryHandler) Check(c *gin.Context) {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Param body body refreshModelRegistryRequest false "optional override ref" // @Param body body refreshModelRegistryRequest false "optional override ref"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/model-registry/refresh [post] // @Router /admin/model-registry/refresh [post]
func (h *ModelRegistryHandler) Refresh(c *gin.Context) { func (h *ModelRegistryHandler) Refresh(c *gin.Context) {
if h == nil || h.reg == nil { if h == nil || h.reg == nil {
@@ -103,8 +103,8 @@ func (h *ModelRegistryHandler) Refresh(c *gin.Context) {
// @Tags admin // @Tags admin
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/model-registry/rollback [post] // @Router /admin/model-registry/rollback [post]
func (h *ModelRegistryHandler) Rollback(c *gin.Context) { func (h *ModelRegistryHandler) Rollback(c *gin.Context) {
if h == nil || h.reg == nil { if h == nil || h.reg == nil {

View File

@@ -23,8 +23,8 @@ type NamespaceRequest struct {
// @Security AdminAuth // @Security AdminAuth
// @Param namespace body NamespaceRequest true "Namespace payload" // @Param namespace body NamespaceRequest true "Namespace payload"
// @Success 201 {object} ResponseEnvelope{data=model.Namespace} // @Success 201 {object} ResponseEnvelope{data=model.Namespace}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/namespaces [post] // @Router /admin/namespaces [post]
func (h *Handler) CreateNamespace(c *gin.Context) { func (h *Handler) CreateNamespace(c *gin.Context) {
var req NamespaceRequest var req NamespaceRequest
@@ -65,7 +65,7 @@ func (h *Handler) CreateNamespace(c *gin.Context) {
// @Param limit query int false "limit (default 50, max 200)" // @Param limit query int false "limit (default 50, max 200)"
// @Param search query string false "search by name/description" // @Param search query string false "search by name/description"
// @Success 200 {object} ResponseEnvelope{data=[]model.Namespace} // @Success 200 {object} ResponseEnvelope{data=[]model.Namespace}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/namespaces [get] // @Router /admin/namespaces [get]
func (h *Handler) ListNamespaces(c *gin.Context) { func (h *Handler) ListNamespaces(c *gin.Context) {
var out []model.Namespace var out []model.Namespace
@@ -88,9 +88,9 @@ func (h *Handler) ListNamespaces(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Namespace ID" // @Param id path int true "Namespace ID"
// @Success 200 {object} ResponseEnvelope{data=model.Namespace} // @Success 200 {object} ResponseEnvelope{data=model.Namespace}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/namespaces/{id} [get] // @Router /admin/namespaces/{id} [get]
func (h *Handler) GetNamespace(c *gin.Context) { func (h *Handler) GetNamespace(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -121,9 +121,9 @@ type UpdateNamespaceRequest struct {
// @Param id path int true "Namespace ID" // @Param id path int true "Namespace ID"
// @Param namespace body UpdateNamespaceRequest true "Update payload" // @Param namespace body UpdateNamespaceRequest true "Update payload"
// @Success 200 {object} ResponseEnvelope{data=model.Namespace} // @Success 200 {object} ResponseEnvelope{data=model.Namespace}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/namespaces/{id} [put] // @Router /admin/namespaces/{id} [put]
func (h *Handler) UpdateNamespace(c *gin.Context) { func (h *Handler) UpdateNamespace(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -185,10 +185,10 @@ func (h *Handler) UpdateNamespace(c *gin.Context) {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Namespace ID" // @Param id path int true "Namespace ID"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/namespaces/{id} [delete] // @Router /admin/namespaces/{id} [delete]
func (h *Handler) DeleteNamespace(c *gin.Context) { func (h *Handler) DeleteNamespace(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")

View File

@@ -49,7 +49,7 @@ func toOperationLogView(l model.OperationLog) OperationLogView {
// @Param limit query int false "limit (default 50, max 200)" // @Param limit query int false "limit (default 50, max 200)"
// @Param search query string false "search by actor/method/path" // @Param search query string false "search by actor/method/path"
// @Success 200 {object} ResponseEnvelope{data=[]OperationLogView} // @Success 200 {object} ResponseEnvelope{data=[]OperationLogView}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/operation-logs [get] // @Router /admin/operation-logs [get]
func (h *AdminHandler) ListOperationLogs(c *gin.Context) { func (h *AdminHandler) ListOperationLogs(c *gin.Context) {
var rows []model.OperationLog var rows []model.OperationLog

View File

@@ -20,8 +20,8 @@ import (
// @Security AdminAuth // @Security AdminAuth
// @Param group body dto.ProviderGroupDTO true "Provider group payload" // @Param group body dto.ProviderGroupDTO true "Provider group payload"
// @Success 201 {object} ResponseEnvelope{data=model.ProviderGroup} // @Success 201 {object} ResponseEnvelope{data=model.ProviderGroup}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/provider-groups [post] // @Router /admin/provider-groups [post]
func (h *Handler) CreateProviderGroup(c *gin.Context) { func (h *Handler) CreateProviderGroup(c *gin.Context) {
var req dto.ProviderGroupDTO var req dto.ProviderGroupDTO
@@ -79,7 +79,7 @@ func (h *Handler) CreateProviderGroup(c *gin.Context) {
// @Param limit query int false "limit (default 50, max 200)" // @Param limit query int false "limit (default 50, max 200)"
// @Param search query string false "search by name/type" // @Param search query string false "search by name/type"
// @Success 200 {object} ResponseEnvelope{data=[]model.ProviderGroup} // @Success 200 {object} ResponseEnvelope{data=[]model.ProviderGroup}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/provider-groups [get] // @Router /admin/provider-groups [get]
func (h *Handler) ListProviderGroups(c *gin.Context) { func (h *Handler) ListProviderGroups(c *gin.Context) {
var groups []model.ProviderGroup var groups []model.ProviderGroup
@@ -102,9 +102,9 @@ func (h *Handler) ListProviderGroups(c *gin.Context) {
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "ProviderGroup ID" // @Param id path int true "ProviderGroup ID"
// @Success 200 {object} ResponseEnvelope{data=model.ProviderGroup} // @Success 200 {object} ResponseEnvelope{data=model.ProviderGroup}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/provider-groups/{id} [get] // @Router /admin/provider-groups/{id} [get]
func (h *Handler) GetProviderGroup(c *gin.Context) { func (h *Handler) GetProviderGroup(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")
@@ -129,9 +129,9 @@ func (h *Handler) GetProviderGroup(c *gin.Context) {
// @Param id path int true "ProviderGroup ID" // @Param id path int true "ProviderGroup ID"
// @Param group body dto.ProviderGroupDTO true "Provider group payload" // @Param group body dto.ProviderGroupDTO true "Provider group payload"
// @Success 200 {object} ResponseEnvelope{data=model.ProviderGroup} // @Success 200 {object} ResponseEnvelope{data=model.ProviderGroup}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/provider-groups/{id} [put] // @Router /admin/provider-groups/{id} [put]
func (h *Handler) UpdateProviderGroup(c *gin.Context) { func (h *Handler) UpdateProviderGroup(c *gin.Context) {
idParam := c.Param("id") idParam := c.Param("id")
@@ -221,10 +221,10 @@ func (h *Handler) UpdateProviderGroup(c *gin.Context) {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "ProviderGroup ID" // @Param id path int true "ProviderGroup ID"
// @Success 200 {object} ResponseEnvelope{data=gin.H} // @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/provider-groups/{id} [delete] // @Router /admin/provider-groups/{id} [delete]
func (h *Handler) DeleteProviderGroup(c *gin.Context) { func (h *Handler) DeleteProviderGroup(c *gin.Context) {
id, ok := parseUintParam(c, "id") id, ok := parseUintParam(c, "id")

View File

@@ -45,9 +45,9 @@ func toMasterRealtimeView(stats service.MasterRealtimeSnapshot) *MasterRealtimeV
// @Security AdminAuth // @Security AdminAuth
// @Param id path int true "Master ID" // @Param id path int true "Master ID"
// @Success 200 {object} ResponseEnvelope{data=MasterRealtimeView} // @Success 200 {object} ResponseEnvelope{data=MasterRealtimeView}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 404 {object} ResponseEnvelope{data=gin.H} // @Failure 404 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/masters/{id}/realtime [get] // @Router /admin/masters/{id}/realtime [get]
func (h *AdminHandler) GetMasterRealtime(c *gin.Context) { func (h *AdminHandler) GetMasterRealtime(c *gin.Context) {
idRaw := strings.TrimSpace(c.Param("id")) idRaw := strings.TrimSpace(c.Param("id"))
@@ -88,8 +88,8 @@ func (h *AdminHandler) GetMasterRealtime(c *gin.Context) {
// @Produce json // @Produce json
// @Security MasterAuth // @Security MasterAuth
// @Success 200 {object} ResponseEnvelope{data=MasterRealtimeView} // @Success 200 {object} ResponseEnvelope{data=MasterRealtimeView}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} // @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/realtime [get] // @Router /v1/realtime [get]
func (h *MasterHandler) GetSelfRealtime(c *gin.Context) { func (h *MasterHandler) GetSelfRealtime(c *gin.Context) {
master, exists := c.Get("master") master, exists := c.Get("master")
@@ -136,7 +136,7 @@ type MasterRealtimeSummaryView struct {
// @Produce json // @Produce json
// @Security AdminAuth // @Security AdminAuth
// @Success 200 {object} ResponseEnvelope{data=SystemRealtimeView} // @Success 200 {object} ResponseEnvelope{data=SystemRealtimeView}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/realtime [get] // @Router /admin/realtime [get]
func (h *AdminHandler) GetAdminRealtime(c *gin.Context) { func (h *AdminHandler) GetAdminRealtime(c *gin.Context) {
if h.statsService == nil { if h.statsService == nil {

View File

@@ -14,3 +14,6 @@ type ResponseEnvelope struct {
TraceID string `json:"trace_id" example:"a1b2c3d4e5f6g7h8"` TraceID string `json:"trace_id" example:"a1b2c3d4e5f6g7h8"`
Details any `json:"details,omitempty" swaggertype:"object"` Details any `json:"details,omitempty" swaggertype:"object"`
} }
// MapData represents a generic JSON object for documentation purposes.
type MapData map[string]any

View File

@@ -42,9 +42,9 @@ type MasterUsageStatsResponse struct {
// @Param since query int false "unix seconds" // @Param since query int false "unix seconds"
// @Param until query int false "unix seconds" // @Param until query int false "unix seconds"
// @Success 200 {object} ResponseEnvelope{data=MasterUsageStatsResponse} // @Success 200 {object} ResponseEnvelope{data=MasterUsageStatsResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 401 {object} ResponseEnvelope{data=gin.H} // @Failure 401 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /v1/stats [get] // @Router /v1/stats [get]
func (h *MasterHandler) GetSelfStats(c *gin.Context) { func (h *MasterHandler) GetSelfStats(c *gin.Context) {
master, exists := c.Get("master") master, exists := c.Get("master")
@@ -148,8 +148,8 @@ type AdminUsageStatsResponse struct {
// @Param since query int false "unix seconds" // @Param since query int false "unix seconds"
// @Param until query int false "unix seconds" // @Param until query int false "unix seconds"
// @Success 200 {object} ResponseEnvelope{data=AdminUsageStatsResponse} // @Success 200 {object} ResponseEnvelope{data=AdminUsageStatsResponse}
// @Failure 400 {object} ResponseEnvelope{data=gin.H} // @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=gin.H} // @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/stats [get] // @Router /admin/stats [get]
func (h *AdminHandler) GetAdminStats(c *gin.Context) { func (h *AdminHandler) GetAdminStats(c *gin.Context) {
rng, err := parseStatsRange(c) rng, err := parseStatsRange(c)