refactor(tenant): drop legacy plugin_installations, migrate monitoring to desktop_clients
Hard cutover from the browser-extension plugin flow to desktop clients: remove plugin_installations/plugin_sessions tables and related service, handler, router, and generated model code; migrate monitoring quotas and collector types to desktop_clients (UUID primary_client_id); recreate platform_access_snapshots keyed by client_id; update dev-seed and callback types accordingly; mark legacy design docs as historical. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/geo-platform/tenant-api/internal/bootstrap"
|
||||
"github.com/geo-platform/tenant-api/internal/shared/response"
|
||||
@@ -12,14 +11,12 @@ import (
|
||||
)
|
||||
|
||||
type MediaHandler struct {
|
||||
svc *app.MediaService
|
||||
logger *zap.Logger
|
||||
svc *app.MediaService
|
||||
}
|
||||
|
||||
func NewMediaHandler(a *bootstrap.App) *MediaHandler {
|
||||
return &MediaHandler{
|
||||
svc: app.NewMediaService(a.DB, a.Logger).WithCache(a.Cache),
|
||||
logger: a.Logger,
|
||||
svc: app.NewMediaService(a.DB),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,75 +29,6 @@ func (h *MediaHandler) ListPlatforms(c *gin.Context) {
|
||||
response.Success(c, data)
|
||||
}
|
||||
|
||||
func (h *MediaHandler) ListPlatformAccounts(c *gin.Context) {
|
||||
data, err := h.svc.ListPlatformAccounts(c.Request.Context())
|
||||
if err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, data)
|
||||
}
|
||||
|
||||
func (h *MediaHandler) DeletePlatformAccount(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_id", "platform account id must be a number"))
|
||||
return
|
||||
}
|
||||
if err := h.svc.DeletePlatformAccount(c.Request.Context(), id); err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
func (h *MediaHandler) CreatePluginSession(c *gin.Context) {
|
||||
var req app.CreatePluginSessionRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error()))
|
||||
return
|
||||
}
|
||||
data, err := h.svc.CreatePluginSession(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, data)
|
||||
}
|
||||
|
||||
func (h *MediaHandler) RegisterPluginInstallation(c *gin.Context) {
|
||||
var req app.RegisterPluginInstallationRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error()))
|
||||
return
|
||||
}
|
||||
data, err := h.svc.RegisterPluginInstallation(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, data)
|
||||
}
|
||||
|
||||
func (h *MediaHandler) CreatePublishBatch(c *gin.Context) {
|
||||
articleID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_id", "article id must be a number"))
|
||||
return
|
||||
}
|
||||
var req app.CreatePublishBatchRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error()))
|
||||
return
|
||||
}
|
||||
data, err := h.svc.CreatePublishBatch(c.Request.Context(), articleID, req)
|
||||
if err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.SuccessWithStatus(c, 201, data)
|
||||
}
|
||||
|
||||
func (h *MediaHandler) ListPublishRecords(c *gin.Context) {
|
||||
articleID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -114,61 +42,3 @@ func (h *MediaHandler) ListPublishRecords(c *gin.Context) {
|
||||
}
|
||||
response.Success(c, data)
|
||||
}
|
||||
|
||||
func (h *MediaHandler) PluginBindCallback(c *gin.Context) {
|
||||
var req app.PluginBindCallbackRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error()))
|
||||
return
|
||||
}
|
||||
data, err := h.svc.HandleBindCallback(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
if h.logger != nil {
|
||||
appErr := response.Normalize(err)
|
||||
h.logger.Warn("publisher bind callback failed",
|
||||
zap.String("request_id", c.GetString("request_id")),
|
||||
zap.Int64("plugin_session_id", req.PluginSessionID),
|
||||
zap.String("platform_id", req.PlatformID),
|
||||
zap.String("platform_uid", req.PlatformUID),
|
||||
zap.Int("code", appErr.Code),
|
||||
zap.String("message", appErr.Message),
|
||||
zap.String("detail", appErr.Detail),
|
||||
)
|
||||
}
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, data)
|
||||
}
|
||||
|
||||
func (h *MediaHandler) PluginPublishCallback(c *gin.Context) {
|
||||
var req app.PluginPublishCallbackRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error()))
|
||||
return
|
||||
}
|
||||
data, err := h.svc.HandlePublishCallback(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
if h.logger != nil {
|
||||
appErr := response.Normalize(err)
|
||||
h.logger.Warn("publisher publish callback failed",
|
||||
zap.String("request_id", c.GetString("request_id")),
|
||||
zap.Int64("plugin_session_id", req.PluginSessionID),
|
||||
zap.Int64("publish_record_id", req.PublishRecordID),
|
||||
zap.Int64("platform_account_id", req.PlatformAccountID),
|
||||
zap.Int64("article_id", req.ArticleID),
|
||||
zap.String("platform_id", req.PlatformID),
|
||||
zap.String("status", req.Status),
|
||||
zap.Stringp("error_message", req.ErrorMessage),
|
||||
zap.Int("code", appErr.Code),
|
||||
zap.String("message", appErr.Message),
|
||||
zap.String("detail", appErr.Detail),
|
||||
zap.Any("request_payload", req.RequestPayload),
|
||||
zap.Any("response_payload", req.ResponsePayload),
|
||||
)
|
||||
}
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, data)
|
||||
}
|
||||
|
||||
@@ -16,10 +16,7 @@ func RegisterRoutes(app *bootstrap.App) {
|
||||
publicAssets := NewAssetHandler(app)
|
||||
app.Engine.GET("/api/public/assets/:token", publicAssets.Serve)
|
||||
|
||||
pluginHandler := NewMediaHandler(app)
|
||||
callbacks := app.Engine.Group("/api/callback/plugin")
|
||||
callbacks.POST("/bind", pluginHandler.PluginBindCallback)
|
||||
callbacks.POST("/publish", pluginHandler.PluginPublishCallback)
|
||||
mediaHandler := NewMediaHandler(app)
|
||||
|
||||
protected := app.Engine.Group("/api")
|
||||
protected.Use(auth.Middleware(app.JWT, app.Sessions))
|
||||
@@ -65,7 +62,7 @@ func RegisterRoutes(app *bootstrap.App) {
|
||||
tenantProtected.POST("/publish-jobs", publishJobHandler.Create)
|
||||
|
||||
media := tenantProtected.Group("/media")
|
||||
media.GET("/platforms", pluginHandler.ListPlatforms)
|
||||
media.GET("/platforms", mediaHandler.ListPlatforms)
|
||||
|
||||
workspace := tenantProtected.Group("/workspace")
|
||||
wsHandler := NewWorkspaceHandler(app)
|
||||
@@ -149,8 +146,7 @@ func RegisterRoutes(app *bootstrap.App) {
|
||||
articles.PUT("/:id", artHandler.Update)
|
||||
articles.GET("/:id/stream", artHandler.Stream)
|
||||
articles.GET("/:id/versions", artHandler.Versions)
|
||||
articles.GET("/:id/publish-records", pluginHandler.ListPublishRecords)
|
||||
articles.POST("/:id/publish-batches", pluginHandler.CreatePublishBatch)
|
||||
articles.GET("/:id/publish-records", mediaHandler.ListPublishRecords)
|
||||
articles.DELETE("/:id", artHandler.Delete)
|
||||
|
||||
brands := tenantProtected.Group("/brands")
|
||||
|
||||
Reference in New Issue
Block a user