Files
geo/server/internal/ops/transport/router.go
T
root 7b4d7ccf68 feat(ops): add job center for cross-source job operations
Provide a unified ops console for inspecting, retrying and cancelling
jobs across generation, template/kol assist, knowledge parse, desktop
publish/task, compliance review and monitoring collect sources. Wires
RabbitMQ for retry republish and consolidates the desktop_publish_jobs
columns into the base migration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 12:56:39 +08:00

129 lines
6.1 KiB
Go

package transport
import (
"github.com/gin-gonic/gin"
"github.com/jackc/pgx/v5/pgxpool"
"go.uber.org/zap"
"github.com/geo-platform/tenant-api/internal/ops/app"
"github.com/geo-platform/tenant-api/internal/shared/middleware"
"github.com/geo-platform/tenant-api/internal/shared/response"
)
type Deps struct {
Engine *gin.Engine
Logger *zap.Logger
DB *pgxpool.Pool
MonitoringDB *pgxpool.Pool
Issuer *app.TokenIssuer
Auth *app.AuthService
Accounts *app.AccountService
AdminUsers *app.AdminUserService
Jobs *app.JobService
KolSubs *app.KolSubscriptionService
Audits *app.AuditService
SiteDomains *app.SiteDomainMappingService
Compliance *app.ComplianceService
}
func RegisterRoutes(d Deps) {
d.Engine.Use(
middleware.Recovery(d.Logger),
middleware.RequestID(),
middleware.Logger(d.Logger),
middleware.CORS(),
)
d.Engine.GET("/api/health/live", func(c *gin.Context) {
response.Success(c, gin.H{"status": "alive"})
})
d.Engine.GET("/api/health/ready", func(c *gin.Context) {
if err := d.DB.Ping(c.Request.Context()); err != nil {
response.Error(c, response.ErrServiceUnavailable(50301, "postgres_unavailable", "数据库不可达"))
return
}
if d.MonitoringDB != nil {
if err := d.MonitoringDB.Ping(c.Request.Context()); err != nil {
response.Error(c, response.ErrServiceUnavailable(50303, "monitoring_postgres_unavailable", "监控数据库不可达"))
return
}
}
response.Success(c, gin.H{"status": "ready"})
})
api := d.Engine.Group("/api/ops")
{
api.POST("/auth/login", loginHandler(d.Auth))
}
authed := api.Group("")
authed.Use(authMiddleware(d.Issuer))
{
authed.GET("/auth/me", meHandler(d.Accounts))
authed.POST("/auth/password", changeOwnPasswordHandler(d.Accounts))
authed.GET("/accounts", listAccountsHandler(d.Accounts))
authed.POST("/accounts", createAccountHandler(d.Accounts))
authed.GET("/accounts/:id", getAccountHandler(d.Accounts))
authed.PATCH("/accounts/:id", updateAccountProfileHandler(d.Accounts))
authed.POST("/accounts/:id/status", setAccountStatusHandler(d.Accounts))
authed.POST("/accounts/:id/password", resetAccountPasswordHandler(d.Accounts))
authed.GET("/plans", listPlansHandler(d.AdminUsers))
authed.GET("/roles", listRolesHandler(d.AdminUsers))
authed.GET("/admin-users", listAdminUsersHandler(d.AdminUsers))
authed.POST("/admin-users", createAdminUserHandler(d.AdminUsers))
authed.GET("/admin-users/:id", getAdminUserHandler(d.AdminUsers))
authed.PATCH("/admin-users/:id", updateAdminUserHandler(d.AdminUsers))
authed.POST("/admin-users/:id/plan", changeAdminUserPlanHandler(d.AdminUsers))
authed.POST("/admin-users/:id/subscription-expiry", updateAdminUserSubscriptionExpiryHandler(d.AdminUsers))
authed.POST("/admin-users/:id/reset-plan-usage", resetAdminUserPlanUsageHandler(d.AdminUsers))
authed.POST("/admin-users/:id/role", changeAdminUserRoleHandler(d.AdminUsers))
authed.POST("/admin-users/:id/kol", setAdminUserKOLHandler(d.AdminUsers))
authed.POST("/admin-users/:id/status", setAdminUserStatusHandler(d.AdminUsers))
authed.POST("/admin-users/:id/password", resetAdminUserPasswordHandler(d.AdminUsers))
authed.POST("/admin-users/:id/reset-login-lock", resetAdminUserLoginLockHandler(d.AdminUsers))
authed.GET("/kol/packages", listKolSubscriptionPackagesHandler(d.KolSubs))
authed.GET("/kol/subscriptions", listKolSubscriptionsHandler(d.KolSubs))
authed.POST("/kol/subscriptions/manual-bind", manualBindKolSubscriptionHandler(d.KolSubs))
authed.POST("/kol/subscriptions/:id/approve", approveKolSubscriptionHandler(d.KolSubs))
authed.POST("/kol/subscriptions/:id/revoke", revokeKolSubscriptionHandler(d.KolSubs))
authed.GET("/audits", listAuditsHandler(d.Audits))
authed.GET("/jobs", listJobsHandler(d.Jobs))
authed.GET("/jobs/:source/:id", getJobHandler(d.Jobs))
authed.POST("/jobs/:source/:id/retry", retryJobHandler(d.Jobs))
authed.POST("/jobs/:source/:id/cancel", cancelJobHandler(d.Jobs))
authed.GET("/site-domain-mappings", listSiteDomainMappingsHandler(d.SiteDomains))
authed.POST("/site-domain-mappings", createSiteDomainMappingHandler(d.SiteDomains))
authed.PATCH("/site-domain-mappings/:id", updateSiteDomainMappingHandler(d.SiteDomains))
authed.POST("/site-domain-mappings/:id/active", setSiteDomainMappingActiveHandler(d.SiteDomains))
authed.DELETE("/site-domain-mappings/:id", deleteSiteDomainMappingHandler(d.SiteDomains))
compliance := authed.Group("/compliance")
compliance.GET("/dictionaries", listComplianceDictionariesHandler(d.Compliance))
compliance.POST("/dictionaries", createComplianceDictionaryHandler(d.Compliance))
compliance.PUT("/dictionaries/:id", updateComplianceDictionaryHandler(d.Compliance))
compliance.DELETE("/dictionaries/:id", deleteComplianceDictionaryHandler(d.Compliance))
compliance.GET("/dictionaries/:id/terms", listComplianceTermsHandler(d.Compliance))
compliance.POST("/dictionaries/:id/terms", createComplianceTermHandler(d.Compliance))
compliance.POST("/dictionaries/:id/terms:batch-import", batchImportComplianceTermsHandler(d.Compliance))
compliance.DELETE("/dictionaries/:id/terms/:term_id", deleteComplianceTermHandler(d.Compliance))
compliance.POST("/dictionaries/:id/publish", publishComplianceDictionaryHandler(d.Compliance))
compliance.POST("/dictionaries/:id/rollback", rollbackComplianceDictionaryHandler(d.Compliance))
compliance.GET("/policy/global", getGlobalCompliancePolicyHandler(d.Compliance))
compliance.PUT("/policy/global", updateGlobalCompliancePolicyHandler(d.Compliance))
compliance.POST("/policy/global/master-switch", setGlobalComplianceMasterSwitchHandler(d.Compliance))
compliance.GET("/manual-reviews", listComplianceManualReviewsHandler(d.Compliance))
compliance.GET("/manual-reviews/:id", getComplianceManualReviewHandler(d.Compliance))
compliance.POST("/manual-reviews/:id/approve", approveComplianceManualReviewHandler(d.Compliance))
compliance.POST("/manual-reviews/:id/reject", rejectComplianceManualReviewHandler(d.Compliance))
compliance.GET("/stats", complianceStatsHandler(d.Compliance))
compliance.GET("/records", listComplianceRecordsHandler(d.Compliance))
}
}