package transport import ( "github.com/geo-platform/tenant-api/internal/bootstrap" "github.com/geo-platform/tenant-api/internal/shared/auth" "github.com/geo-platform/tenant-api/internal/shared/middleware" ) func RegisterRoutes(app *bootstrap.App) { authAPI := app.Engine.Group("/api/auth") authHandler := NewAuthHandler(app) authAPI.POST("/login", authHandler.Login) authAPI.POST("/refresh", authHandler.Refresh) 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) monitoringCallbackHandler := NewMonitoringCallbackHandler(app) monitoringPlugin := app.Engine.Group("/api/plugin/monitoring") monitoringPlugin.POST("/heartbeat", monitoringCallbackHandler.Heartbeat) monitoringPlugin.POST("/tasks/lease", monitoringCallbackHandler.LeaseTasks) monitoringPlugin.POST("/tasks/resume", monitoringCallbackHandler.ResumeTasks) monitoringPlugin.POST("/tasks/:id/result", monitoringCallbackHandler.TaskResult) monitoringPlugin.POST("/tasks/:id/skip", monitoringCallbackHandler.SkipTask) protected := app.Engine.Group("/api") protected.Use(auth.Middleware(app.JWT, app.Sessions)) protected.Use(middleware.TenantScope()) protected.GET("/auth/me", authHandler.Me) protected.POST("/auth/logout", authHandler.Logout) workspace := protected.Group("/tenant/workspace") wsHandler := NewWorkspaceHandler(app) workspace.GET("/overview", wsHandler.Overview) workspace.GET("/recent-articles", wsHandler.RecentArticles) workspace.GET("/quota-summary", wsHandler.QuotaSummary) workspace.GET("/template-cards", wsHandler.TemplateCards) workspace.GET("/kol-cards", wsHandler.KolCards) templates := protected.Group("/tenant/templates") tplHandler := NewTemplateHandler(app) templates.GET("", tplHandler.List) templates.GET("/:id", tplHandler.Detail) templates.POST("/:id/drafts", tplHandler.SaveDraft) templates.POST("/:id/analyze-tasks", tplHandler.CreateAnalyzeTask) templates.GET("/:id/analyze_task_result", tplHandler.GetAnalyzeTaskResult) templates.POST("/:id/title-tasks", tplHandler.CreateTitleTask) templates.GET("/:id/gen_title_task_result", tplHandler.GetTitleTaskResult) templates.POST("/:id/outline-tasks", tplHandler.CreateOutlineTask) templates.GET("/:id/gen_outline_task_result", tplHandler.GetOutlineTaskResult) templates.POST("/:id/generate", tplHandler.Generate) kolManage := protected.Group("/tenant/kol/manage") kolManageHandler := NewKolManageHandler(app) kolManage.GET("/profile", kolManageHandler.GetProfile) kolManage.GET("/packages", kolManageHandler.ListPackages) kolManage.POST("/packages", kolManageHandler.CreatePackage) kolManage.PUT("/packages/:id", kolManageHandler.UpdatePackage) kolManage.DELETE("/packages/:id", kolManageHandler.DeletePackage) kolManage.PUT("/packages/:id/publish", kolManageHandler.PublishPackage) kolManage.PUT("/packages/:id/archive", kolManageHandler.ArchivePackage) kolManage.GET("/packages/:id/prompts", kolManageHandler.ListPrompts) kolManage.POST("/packages/:id/prompts", kolManageHandler.CreatePrompt) kolManage.GET("/prompts/:id", kolManageHandler.GetPromptLatest) kolManage.PUT("/prompts/:id", kolManageHandler.UpdatePromptMetadata) kolManage.DELETE("/prompts/:id", kolManageHandler.DeletePrompt) kolManage.POST("/prompts/:id/save", kolManageHandler.SavePrompt) kolManage.POST("/prompts/:id/publish", kolManageHandler.PublishPrompt) kolManage.PUT("/prompts/:id/activate", kolManageHandler.ActivatePrompt) kolManage.PUT("/prompts/:id/archive", kolManageHandler.ArchivePrompt) kolManage.POST("/assist", kolManageHandler.AssistSubmit) kolManage.GET("/assist/:id", kolManageHandler.AssistGet) kolDash := protected.Group("/tenant/kol/dashboard") kolDashboardHandler := NewKolDashboardHandler(app) kolDash.GET("/overview", kolDashboardHandler.Overview) kolDash.GET("/packages", kolDashboardHandler.Packages) kolDash.GET("/trend", kolDashboardHandler.Trend) kolMarketplace := protected.Group("/tenant/kol/marketplace") kolMarketplaceHandler := NewKolMarketplaceHandler(app) kolMarketplace.GET("/packages", kolMarketplaceHandler.ListPackages) kolMarketplace.GET("/packages/:id", kolMarketplaceHandler.GetPackage) kolMarketplace.POST("/packages/:id/subscribe", kolMarketplaceHandler.Subscribe) kolSubscriptions := protected.Group("/tenant/kol") kolSubscriptions.GET("/subscriptions", kolMarketplaceHandler.ListSubscriptions) kolSubscriptions.GET("/subscription-prompts", kolMarketplaceHandler.ListSubscriptionPrompts) kolSubscriptions.GET("/subscription-prompts/:id/schema", kolMarketplaceHandler.SubscriptionPromptSchema) kolSubscriptions.POST("/subscription-prompts/:id/generate", kolMarketplaceHandler.Generate) // V1 compromise: these admin operations live on tenant-api and are gated by // tenant_role=tenant_admin until the platform-api/module is built. kolAdmin := protected.Group("/tenant/kol/admin") kolAdminHandler := NewKolAdminHandler(app) kolAdmin.PUT("/subscriptions/:id/approve", kolAdminHandler.ApproveSubscription) kolAdmin.POST("/subscriptions", kolAdminHandler.ManualBind) kolAdmin.PUT("/subscriptions/:id/revoke", kolAdminHandler.RevokeSubscription) articles := protected.Group("/tenant/articles") artHandler := NewArticleHandler(app) articles.GET("", artHandler.List) articles.POST("", artHandler.Create) articles.POST("/generate-from-rule", artHandler.GenerateFromRule) articles.POST("/:id/images", artHandler.UploadImage) articles.POST("/:id/selection-optimize/stream", artHandler.OptimizeSelectionStream) articles.GET("/:id", artHandler.Detail) 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.DELETE("/:id", artHandler.Delete) media := protected.Group("/tenant/media") media.GET("/platforms", pluginHandler.ListPlatforms) media.GET("/platform-accounts", pluginHandler.ListPlatformAccounts) media.POST("/plugin-installations/register", pluginHandler.RegisterPluginInstallation) media.POST("/plugin-sessions", pluginHandler.CreatePluginSession) media.DELETE("/platform-accounts/:id", pluginHandler.DeletePlatformAccount) brands := protected.Group("/tenant/brands") brandHandler := NewBrandHandler(app) brands.GET("", brandHandler.List) brands.GET("/library-summary", brandHandler.Summary) brands.POST("", brandHandler.Create) brands.GET("/:id", brandHandler.Detail) brands.PUT("/:id", brandHandler.Update) brands.DELETE("/:id", brandHandler.Delete) brands.GET("/:id/keywords", brandHandler.ListKeywords) brands.POST("/:id/keywords", brandHandler.CreateKeyword) brands.PUT("/:id/keywords/:kid", brandHandler.UpdateKeyword) brands.DELETE("/:id/keywords/:kid", brandHandler.DeleteKeyword) brands.GET("/:id/questions", brandHandler.ListQuestions) brands.POST("/:id/questions", brandHandler.CreateQuestion) brands.PUT("/:id/questions/:qid", brandHandler.UpdateQuestion) brands.DELETE("/:id/questions/:qid", brandHandler.DeleteQuestion) brands.GET("/:id/competitors", brandHandler.ListCompetitors) brands.POST("/:id/competitors", brandHandler.CreateCompetitor) brands.PUT("/:id/competitors/:cid", brandHandler.UpdateCompetitor) brands.DELETE("/:id/competitors/:cid", brandHandler.DeleteCompetitor) monitoring := protected.Group("/tenant/monitoring") monitoringHandler := NewMonitoringHandler(app) monitoring.GET("/dashboard/composite", monitoringHandler.DashboardComposite) monitoring.GET("/brands/:brand_id/questions/:question_id/detail", monitoringHandler.QuestionDetail) monitoring.POST("/brands/:brand_id/collect-now", monitoringHandler.CollectNow) knowledge := protected.Group("/tenant/knowledge") knowledgeHandler := NewKnowledgeHandler(app) knowledge.GET("/groups", knowledgeHandler.ListGroups) knowledge.POST("/groups", knowledgeHandler.CreateGroup) knowledge.PUT("/groups/:gid", knowledgeHandler.UpdateGroup) knowledge.DELETE("/groups/:gid", knowledgeHandler.DeleteGroup) knowledge.GET("/items", knowledgeHandler.ListItems) knowledge.GET("/items/:id", knowledgeHandler.GetItemDetail) knowledge.POST("/items/text", knowledgeHandler.CreateTextItem) knowledge.POST("/items/url", knowledgeHandler.CreateURLItem) knowledge.POST("/items/file", knowledgeHandler.CreateFileItem) knowledge.DELETE("/items/:id", knowledgeHandler.DeleteItem) // Prompt Rules promptRules := protected.Group("/tenant/prompt-rules") prHandler := NewPromptRuleHandler(app) promptRules.GET("", prHandler.List) promptRules.GET("/simple", prHandler.ListSimple) promptRules.POST("", prHandler.Create) promptRules.GET("/:id", prHandler.Detail) promptRules.PUT("/:id", prHandler.Update) promptRules.DELETE("/:id", prHandler.Delete) promptRules.PUT("/:id/status", prHandler.ToggleStatus) // Prompt Rule Groups promptRules.GET("/groups", prHandler.ListGroups) promptRules.POST("/groups", prHandler.CreateGroup) promptRules.PUT("/groups/:gid", prHandler.UpdateGroup) promptRules.DELETE("/groups/:gid", prHandler.DeleteGroup) // Schedule Tasks schedules := protected.Group("/tenant/schedules") schHandler := NewScheduleTaskHandler(app) schedules.GET("", schHandler.List) schedules.POST("", schHandler.Create) schedules.GET("/:id", schHandler.Detail) schedules.PUT("/:id", schHandler.Update) schedules.DELETE("/:id", schHandler.Delete) schedules.PUT("/:id/status", schHandler.ToggleStatus) instantTasks := protected.Group("/tenant/instant-tasks") instHandler := NewInstantTaskHandler(app) instantTasks.GET("", instHandler.List) images := protected.Group("/tenant/images") imgHandler := NewImageHandler(app) images.GET("", imgHandler.ListImages) images.POST("", imgHandler.UploadImage) images.PUT("/:id", imgHandler.UpdateImage) images.GET("/:id/references", imgHandler.GetImageReferences) images.DELETE("/:id", imgHandler.DeleteImage) images.GET("/storage-usage", imgHandler.StorageUsage) imageFolders := protected.Group("/tenant/images/folders") imageFolders.GET("", imgHandler.ListFolders) imageFolders.POST("", imgHandler.CreateFolder) imageFolders.PUT("/:id", imgHandler.UpdateFolder) imageFolders.GET("/:id/delete-preview", imgHandler.FolderDeletePreview) imageFolders.DELETE("/:id", imgHandler.DeleteFolder) }