Files
geo/server/internal/ops/transport/kol_subscription_handler.go
T
root 9bb7144593 refactor(kol-admin): move subscription admin endpoints from tenant-api to ops-api
Approving / manually binding / revoking KOL subscriptions belonged to the
operations console, not the tenant-admin role on tenant-api. Add a fresh
KolSubscriptionService + repository + handlers under the ops module with
its own list/manual-bind/approve/revoke routes, wire a Redis-backed cache
into ops-api so admin actions can invalidate tenant prompt caches, and
delete the tenant-side admin service/handler now that ops-web owns the UI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 22:07:25 +08:00

118 lines
2.9 KiB
Go

package transport
import (
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/geo-platform/tenant-api/internal/ops/app"
"github.com/geo-platform/tenant-api/internal/shared/response"
)
type approveKolSubscriptionRequest struct {
EndAt *time.Time `json:"end_at"`
}
type manualBindKolSubscriptionRequest struct {
Phone string `json:"phone" binding:"required"`
PackageID int64 `json:"package_id" binding:"required"`
EndAt *time.Time `json:"end_at"`
}
func listKolSubscriptionsHandler(svc *app.KolSubscriptionService) gin.HandlerFunc {
return func(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
result, err := svc.List(c.Request.Context(), app.KolSubscriptionListInput{
Keyword: c.Query("keyword"),
Status: c.Query("status"),
Page: page,
Size: size,
})
if err != nil {
response.Error(c, err)
return
}
response.Success(c, result)
}
}
func listKolSubscriptionPackagesHandler(svc *app.KolSubscriptionService) gin.HandlerFunc {
return func(c *gin.Context) {
size, _ := strconv.Atoi(c.DefaultQuery("size", "50"))
result, err := svc.ListPackages(c.Request.Context(), app.KolPackageListInput{
Keyword: c.Query("keyword"),
Size: size,
})
if err != nil {
response.Error(c, err)
return
}
response.Success(c, result)
}
}
func manualBindKolSubscriptionHandler(svc *app.KolSubscriptionService) gin.HandlerFunc {
return func(c *gin.Context) {
var body manualBindKolSubscriptionRequest
if err := c.ShouldBindJSON(&body); err != nil {
response.Error(c, response.ErrBadRequest(40000, "invalid_payload", err.Error()))
return
}
detail, err := svc.ManualBind(c.Request.Context(), actorFromGin(c), app.KolSubscriptionManualBindInput{
Phone: body.Phone,
PackageID: body.PackageID,
EndAt: body.EndAt,
})
if err != nil {
response.Error(c, err)
return
}
response.Success(c, detail)
}
}
func approveKolSubscriptionHandler(svc *app.KolSubscriptionService) gin.HandlerFunc {
return func(c *gin.Context) {
id, err := parseIDParam(c)
if err != nil {
response.Error(c, err)
return
}
var body approveKolSubscriptionRequest
if c.Request.ContentLength > 0 {
if err := c.ShouldBindJSON(&body); err != nil {
response.Error(c, response.ErrBadRequest(40000, "invalid_payload", err.Error()))
return
}
}
detail, err := svc.Approve(c.Request.Context(), actorFromGin(c), id, body.EndAt)
if err != nil {
response.Error(c, err)
return
}
response.Success(c, detail)
}
}
func revokeKolSubscriptionHandler(svc *app.KolSubscriptionService) gin.HandlerFunc {
return func(c *gin.Context) {
id, err := parseIDParam(c)
if err != nil {
response.Error(c, err)
return
}
detail, err := svc.Revoke(c.Request.Context(), actorFromGin(c), id)
if err != nil {
response.Error(c, err)
return
}
response.Success(c, detail)
}
}