From aafcaf4810944b68270a930ba051f0a7956297c0 Mon Sep 17 00:00:00 2001 From: pham Date: Mon, 20 Apr 2026 22:33:29 +0800 Subject: [PATCH] remove deprecated data management admin routes --- backend/cmd/server/wire_gen.go | 4 +- .../handler/admin/data_management_handler.go | 545 ------------------ .../admin/data_management_handler_test.go | 78 --- backend/internal/handler/handler.go | 1 - backend/internal/handler/wire.go | 3 - backend/internal/server/routes/admin.go | 24 - .../server/routes/admin_routes_test.go | 3 + 7 files changed, 4 insertions(+), 654 deletions(-) delete mode 100644 backend/internal/handler/admin/data_management_handler.go delete mode 100644 backend/internal/handler/admin/data_management_handler_test.go diff --git a/backend/cmd/server/wire_gen.go b/backend/cmd/server/wire_gen.go index 738393a0..1aff823f 100644 --- a/backend/cmd/server/wire_gen.go +++ b/backend/cmd/server/wire_gen.go @@ -148,8 +148,6 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { crsSyncService := service.NewCRSSyncService(accountRepository, proxyRepository, oAuthService, openAIOAuthService, geminiOAuthService, configConfig) accountHandler := admin.NewAccountHandler(adminService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, rateLimitService, accountUsageService, accountTestService, concurrencyService, crsSyncService, sessionLimitCache, rpmCache, compositeTokenCacheInvalidator) adminAnnouncementHandler := admin.NewAnnouncementHandler(announcementService) - dataManagementService := service.NewDataManagementService() - dataManagementHandler := admin.NewDataManagementHandler(dataManagementService) backupObjectStoreFactory := repository.NewS3BackupStoreFactory() dbDumper := repository.NewPgDumper(configConfig) backupService := service.ProvideBackupService(settingRepository, configConfig, secretEncryptor, backupObjectStoreFactory, dbDumper) @@ -224,7 +222,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { soraQuotaService := service.NewSoraQuotaService(settingService) soraGenerationService := service.NewSoraGenerationService(soraGenerationRepository, soraS3Storage, soraQuotaService) soraHandler := admin.NewSoraHandler(soraGenerationService, soraQuotaService, userRepository) - adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, adminAnnouncementHandler, dataManagementHandler, backupHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, promoHandler, settingHandler, opsHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler, userAttributeHandler, errorPassthroughHandler, tlsFingerprintProfileHandler, adminAPIKeyHandler, scheduledTestHandler, channelHandler, paymentHandler, soraHandler) + adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, adminAnnouncementHandler, backupHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, promoHandler, settingHandler, opsHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler, userAttributeHandler, errorPassthroughHandler, tlsFingerprintProfileHandler, adminAPIKeyHandler, scheduledTestHandler, channelHandler, paymentHandler, soraHandler) usageRecordWorkerPool := service.NewUsageRecordWorkerPool(configConfig) userMsgQueueCache := repository.NewUserMsgQueueCache(redisClient) userMessageQueueService := service.ProvideUserMessageQueueService(userMsgQueueCache, rpmCache, configConfig) diff --git a/backend/internal/handler/admin/data_management_handler.go b/backend/internal/handler/admin/data_management_handler.go deleted file mode 100644 index 02fc766f..00000000 --- a/backend/internal/handler/admin/data_management_handler.go +++ /dev/null @@ -1,545 +0,0 @@ -package admin - -import ( - "context" - "strconv" - "strings" - - infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors" - "github.com/Wei-Shaw/sub2api/internal/pkg/response" - middleware2 "github.com/Wei-Shaw/sub2api/internal/server/middleware" - "github.com/Wei-Shaw/sub2api/internal/service" - - "github.com/gin-gonic/gin" -) - -type DataManagementHandler struct { - dataManagementService dataManagementService -} - -func NewDataManagementHandler(dataManagementService *service.DataManagementService) *DataManagementHandler { - return &DataManagementHandler{dataManagementService: dataManagementService} -} - -type dataManagementService interface { - GetConfig(ctx context.Context) (service.DataManagementConfig, error) - UpdateConfig(ctx context.Context, cfg service.DataManagementConfig) (service.DataManagementConfig, error) - ValidateS3(ctx context.Context, cfg service.DataManagementS3Config) (service.DataManagementTestS3Result, error) - CreateBackupJob(ctx context.Context, input service.DataManagementCreateBackupJobInput) (service.DataManagementBackupJob, error) - ListSourceProfiles(ctx context.Context, sourceType string) ([]service.DataManagementSourceProfile, error) - CreateSourceProfile(ctx context.Context, input service.DataManagementCreateSourceProfileInput) (service.DataManagementSourceProfile, error) - UpdateSourceProfile(ctx context.Context, input service.DataManagementUpdateSourceProfileInput) (service.DataManagementSourceProfile, error) - DeleteSourceProfile(ctx context.Context, sourceType, profileID string) error - SetActiveSourceProfile(ctx context.Context, sourceType, profileID string) (service.DataManagementSourceProfile, error) - ListS3Profiles(ctx context.Context) ([]service.DataManagementS3Profile, error) - CreateS3Profile(ctx context.Context, input service.DataManagementCreateS3ProfileInput) (service.DataManagementS3Profile, error) - UpdateS3Profile(ctx context.Context, input service.DataManagementUpdateS3ProfileInput) (service.DataManagementS3Profile, error) - DeleteS3Profile(ctx context.Context, profileID string) error - SetActiveS3Profile(ctx context.Context, profileID string) (service.DataManagementS3Profile, error) - ListBackupJobs(ctx context.Context, input service.DataManagementListBackupJobsInput) (service.DataManagementListBackupJobsResult, error) - GetBackupJob(ctx context.Context, jobID string) (service.DataManagementBackupJob, error) - EnsureAgentEnabled(ctx context.Context) error - GetAgentHealth(ctx context.Context) service.DataManagementAgentHealth -} - -type TestS3ConnectionRequest struct { - Endpoint string `json:"endpoint"` - Region string `json:"region" binding:"required"` - Bucket string `json:"bucket" binding:"required"` - AccessKeyID string `json:"access_key_id"` - SecretAccessKey string `json:"secret_access_key"` - Prefix string `json:"prefix"` - ForcePathStyle bool `json:"force_path_style"` - UseSSL bool `json:"use_ssl"` -} - -type CreateBackupJobRequest struct { - BackupType string `json:"backup_type" binding:"required,oneof=postgres redis full"` - UploadToS3 bool `json:"upload_to_s3"` - S3ProfileID string `json:"s3_profile_id"` - PostgresID string `json:"postgres_profile_id"` - RedisID string `json:"redis_profile_id"` - IdempotencyKey string `json:"idempotency_key"` -} - -type CreateSourceProfileRequest struct { - ProfileID string `json:"profile_id" binding:"required"` - Name string `json:"name" binding:"required"` - Config service.DataManagementSourceConfig `json:"config" binding:"required"` - SetActive bool `json:"set_active"` -} - -type UpdateSourceProfileRequest struct { - Name string `json:"name" binding:"required"` - Config service.DataManagementSourceConfig `json:"config" binding:"required"` -} - -type CreateS3ProfileRequest struct { - ProfileID string `json:"profile_id" binding:"required"` - Name string `json:"name" binding:"required"` - Enabled bool `json:"enabled"` - Endpoint string `json:"endpoint"` - Region string `json:"region"` - Bucket string `json:"bucket"` - AccessKeyID string `json:"access_key_id"` - SecretAccessKey string `json:"secret_access_key"` - Prefix string `json:"prefix"` - ForcePathStyle bool `json:"force_path_style"` - UseSSL bool `json:"use_ssl"` - SetActive bool `json:"set_active"` -} - -type UpdateS3ProfileRequest struct { - Name string `json:"name" binding:"required"` - Enabled bool `json:"enabled"` - Endpoint string `json:"endpoint"` - Region string `json:"region"` - Bucket string `json:"bucket"` - AccessKeyID string `json:"access_key_id"` - SecretAccessKey string `json:"secret_access_key"` - Prefix string `json:"prefix"` - ForcePathStyle bool `json:"force_path_style"` - UseSSL bool `json:"use_ssl"` -} - -func (h *DataManagementHandler) GetAgentHealth(c *gin.Context) { - health := h.getAgentHealth(c) - payload := gin.H{ - "enabled": health.Enabled, - "reason": health.Reason, - "socket_path": health.SocketPath, - } - if health.Agent != nil { - payload["agent"] = gin.H{ - "status": health.Agent.Status, - "version": health.Agent.Version, - "uptime_seconds": health.Agent.UptimeSeconds, - } - } - response.Success(c, payload) -} - -func (h *DataManagementHandler) GetConfig(c *gin.Context) { - if !h.requireAgentEnabled(c) { - return - } - cfg, err := h.dataManagementService.GetConfig(c.Request.Context()) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, cfg) -} - -func (h *DataManagementHandler) UpdateConfig(c *gin.Context) { - var req service.DataManagementConfig - if err := c.ShouldBindJSON(&req); err != nil { - response.BadRequest(c, "Invalid request: "+err.Error()) - return - } - - if !h.requireAgentEnabled(c) { - return - } - cfg, err := h.dataManagementService.UpdateConfig(c.Request.Context(), req) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, cfg) -} - -func (h *DataManagementHandler) TestS3(c *gin.Context) { - var req TestS3ConnectionRequest - if err := c.ShouldBindJSON(&req); err != nil { - response.BadRequest(c, "Invalid request: "+err.Error()) - return - } - - if !h.requireAgentEnabled(c) { - return - } - result, err := h.dataManagementService.ValidateS3(c.Request.Context(), service.DataManagementS3Config{ - Enabled: true, - Endpoint: req.Endpoint, - Region: req.Region, - Bucket: req.Bucket, - AccessKeyID: req.AccessKeyID, - SecretAccessKey: req.SecretAccessKey, - Prefix: req.Prefix, - ForcePathStyle: req.ForcePathStyle, - UseSSL: req.UseSSL, - }) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, gin.H{"ok": result.OK, "message": result.Message}) -} - -func (h *DataManagementHandler) CreateBackupJob(c *gin.Context) { - var req CreateBackupJobRequest - if err := c.ShouldBindJSON(&req); err != nil { - response.BadRequest(c, "Invalid request: "+err.Error()) - return - } - - req.IdempotencyKey = normalizeBackupIdempotencyKey(c.GetHeader("X-Idempotency-Key"), req.IdempotencyKey) - if !h.requireAgentEnabled(c) { - return - } - - triggeredBy := "admin:unknown" - if subject, ok := middleware2.GetAuthSubjectFromContext(c); ok { - triggeredBy = "admin:" + strconv.FormatInt(subject.UserID, 10) - } - job, err := h.dataManagementService.CreateBackupJob(c.Request.Context(), service.DataManagementCreateBackupJobInput{ - BackupType: req.BackupType, - UploadToS3: req.UploadToS3, - S3ProfileID: req.S3ProfileID, - PostgresID: req.PostgresID, - RedisID: req.RedisID, - TriggeredBy: triggeredBy, - IdempotencyKey: req.IdempotencyKey, - }) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, gin.H{"job_id": job.JobID, "status": job.Status}) -} - -func (h *DataManagementHandler) ListSourceProfiles(c *gin.Context) { - sourceType := strings.TrimSpace(c.Param("source_type")) - if sourceType == "" { - response.BadRequest(c, "Invalid source_type") - return - } - if sourceType != "postgres" && sourceType != "redis" { - response.BadRequest(c, "source_type must be postgres or redis") - return - } - - if !h.requireAgentEnabled(c) { - return - } - items, err := h.dataManagementService.ListSourceProfiles(c.Request.Context(), sourceType) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, gin.H{"items": items}) -} - -func (h *DataManagementHandler) CreateSourceProfile(c *gin.Context) { - sourceType := strings.TrimSpace(c.Param("source_type")) - if sourceType != "postgres" && sourceType != "redis" { - response.BadRequest(c, "source_type must be postgres or redis") - return - } - - var req CreateSourceProfileRequest - if err := c.ShouldBindJSON(&req); err != nil { - response.BadRequest(c, "Invalid request: "+err.Error()) - return - } - - if !h.requireAgentEnabled(c) { - return - } - profile, err := h.dataManagementService.CreateSourceProfile(c.Request.Context(), service.DataManagementCreateSourceProfileInput{ - SourceType: sourceType, - ProfileID: req.ProfileID, - Name: req.Name, - Config: req.Config, - SetActive: req.SetActive, - }) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, profile) -} - -func (h *DataManagementHandler) UpdateSourceProfile(c *gin.Context) { - sourceType := strings.TrimSpace(c.Param("source_type")) - if sourceType != "postgres" && sourceType != "redis" { - response.BadRequest(c, "source_type must be postgres or redis") - return - } - profileID := strings.TrimSpace(c.Param("profile_id")) - if profileID == "" { - response.BadRequest(c, "Invalid profile_id") - return - } - - var req UpdateSourceProfileRequest - if err := c.ShouldBindJSON(&req); err != nil { - response.BadRequest(c, "Invalid request: "+err.Error()) - return - } - - if !h.requireAgentEnabled(c) { - return - } - profile, err := h.dataManagementService.UpdateSourceProfile(c.Request.Context(), service.DataManagementUpdateSourceProfileInput{ - SourceType: sourceType, - ProfileID: profileID, - Name: req.Name, - Config: req.Config, - }) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, profile) -} - -func (h *DataManagementHandler) DeleteSourceProfile(c *gin.Context) { - sourceType := strings.TrimSpace(c.Param("source_type")) - if sourceType != "postgres" && sourceType != "redis" { - response.BadRequest(c, "source_type must be postgres or redis") - return - } - profileID := strings.TrimSpace(c.Param("profile_id")) - if profileID == "" { - response.BadRequest(c, "Invalid profile_id") - return - } - - if !h.requireAgentEnabled(c) { - return - } - if err := h.dataManagementService.DeleteSourceProfile(c.Request.Context(), sourceType, profileID); err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, gin.H{"deleted": true}) -} - -func (h *DataManagementHandler) SetActiveSourceProfile(c *gin.Context) { - sourceType := strings.TrimSpace(c.Param("source_type")) - if sourceType != "postgres" && sourceType != "redis" { - response.BadRequest(c, "source_type must be postgres or redis") - return - } - profileID := strings.TrimSpace(c.Param("profile_id")) - if profileID == "" { - response.BadRequest(c, "Invalid profile_id") - return - } - - if !h.requireAgentEnabled(c) { - return - } - profile, err := h.dataManagementService.SetActiveSourceProfile(c.Request.Context(), sourceType, profileID) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, profile) -} - -func (h *DataManagementHandler) ListS3Profiles(c *gin.Context) { - if !h.requireAgentEnabled(c) { - return - } - - items, err := h.dataManagementService.ListS3Profiles(c.Request.Context()) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, gin.H{"items": items}) -} - -func (h *DataManagementHandler) CreateS3Profile(c *gin.Context) { - var req CreateS3ProfileRequest - if err := c.ShouldBindJSON(&req); err != nil { - response.BadRequest(c, "Invalid request: "+err.Error()) - return - } - - if !h.requireAgentEnabled(c) { - return - } - - profile, err := h.dataManagementService.CreateS3Profile(c.Request.Context(), service.DataManagementCreateS3ProfileInput{ - ProfileID: req.ProfileID, - Name: req.Name, - SetActive: req.SetActive, - S3: service.DataManagementS3Config{ - Enabled: req.Enabled, - Endpoint: req.Endpoint, - Region: req.Region, - Bucket: req.Bucket, - AccessKeyID: req.AccessKeyID, - SecretAccessKey: req.SecretAccessKey, - Prefix: req.Prefix, - ForcePathStyle: req.ForcePathStyle, - UseSSL: req.UseSSL, - }, - }) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, profile) -} - -func (h *DataManagementHandler) UpdateS3Profile(c *gin.Context) { - var req UpdateS3ProfileRequest - if err := c.ShouldBindJSON(&req); err != nil { - response.BadRequest(c, "Invalid request: "+err.Error()) - return - } - - profileID := strings.TrimSpace(c.Param("profile_id")) - if profileID == "" { - response.BadRequest(c, "Invalid profile_id") - return - } - - if !h.requireAgentEnabled(c) { - return - } - - profile, err := h.dataManagementService.UpdateS3Profile(c.Request.Context(), service.DataManagementUpdateS3ProfileInput{ - ProfileID: profileID, - Name: req.Name, - S3: service.DataManagementS3Config{ - Enabled: req.Enabled, - Endpoint: req.Endpoint, - Region: req.Region, - Bucket: req.Bucket, - AccessKeyID: req.AccessKeyID, - SecretAccessKey: req.SecretAccessKey, - Prefix: req.Prefix, - ForcePathStyle: req.ForcePathStyle, - UseSSL: req.UseSSL, - }, - }) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, profile) -} - -func (h *DataManagementHandler) DeleteS3Profile(c *gin.Context) { - profileID := strings.TrimSpace(c.Param("profile_id")) - if profileID == "" { - response.BadRequest(c, "Invalid profile_id") - return - } - - if !h.requireAgentEnabled(c) { - return - } - if err := h.dataManagementService.DeleteS3Profile(c.Request.Context(), profileID); err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, gin.H{"deleted": true}) -} - -func (h *DataManagementHandler) SetActiveS3Profile(c *gin.Context) { - profileID := strings.TrimSpace(c.Param("profile_id")) - if profileID == "" { - response.BadRequest(c, "Invalid profile_id") - return - } - - if !h.requireAgentEnabled(c) { - return - } - profile, err := h.dataManagementService.SetActiveS3Profile(c.Request.Context(), profileID) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, profile) -} - -func (h *DataManagementHandler) ListBackupJobs(c *gin.Context) { - if !h.requireAgentEnabled(c) { - return - } - - pageSize := int32(20) - if raw := strings.TrimSpace(c.Query("page_size")); raw != "" { - v, err := strconv.Atoi(raw) - if err != nil || v <= 0 { - response.BadRequest(c, "Invalid page_size") - return - } - pageSize = int32(v) - } - - result, err := h.dataManagementService.ListBackupJobs(c.Request.Context(), service.DataManagementListBackupJobsInput{ - PageSize: pageSize, - PageToken: c.Query("page_token"), - Status: c.Query("status"), - BackupType: c.Query("backup_type"), - }) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, result) -} - -func (h *DataManagementHandler) GetBackupJob(c *gin.Context) { - jobID := strings.TrimSpace(c.Param("job_id")) - if jobID == "" { - response.BadRequest(c, "Invalid backup job ID") - return - } - - if !h.requireAgentEnabled(c) { - return - } - job, err := h.dataManagementService.GetBackupJob(c.Request.Context(), jobID) - if err != nil { - response.ErrorFrom(c, err) - return - } - response.Success(c, job) -} - -func (h *DataManagementHandler) requireAgentEnabled(c *gin.Context) bool { - if h.dataManagementService == nil { - err := infraerrors.ServiceUnavailable( - service.DataManagementAgentUnavailableReason, - "data management agent service is not configured", - ).WithMetadata(map[string]string{"socket_path": service.DefaultDataManagementAgentSocketPath}) - response.ErrorFrom(c, err) - return false - } - - if err := h.dataManagementService.EnsureAgentEnabled(c.Request.Context()); err != nil { - response.ErrorFrom(c, err) - return false - } - - return true -} - -func (h *DataManagementHandler) getAgentHealth(c *gin.Context) service.DataManagementAgentHealth { - if h.dataManagementService == nil { - return service.DataManagementAgentHealth{ - Enabled: false, - Reason: service.DataManagementAgentUnavailableReason, - SocketPath: service.DefaultDataManagementAgentSocketPath, - } - } - return h.dataManagementService.GetAgentHealth(c.Request.Context()) -} - -func normalizeBackupIdempotencyKey(headerValue, bodyValue string) string { - headerKey := strings.TrimSpace(headerValue) - if headerKey != "" { - return headerKey - } - return strings.TrimSpace(bodyValue) -} diff --git a/backend/internal/handler/admin/data_management_handler_test.go b/backend/internal/handler/admin/data_management_handler_test.go deleted file mode 100644 index ce8ee835..00000000 --- a/backend/internal/handler/admin/data_management_handler_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package admin - -import ( - "encoding/json" - "net/http" - "net/http/httptest" - "path/filepath" - "testing" - "time" - - "github.com/Wei-Shaw/sub2api/internal/service" - "github.com/gin-gonic/gin" - "github.com/stretchr/testify/require" -) - -type apiEnvelope struct { - Code int `json:"code"` - Message string `json:"message"` - Reason string `json:"reason"` - Data json.RawMessage `json:"data"` -} - -func TestDataManagementHandler_AgentHealthAlways200(t *testing.T) { - gin.SetMode(gin.TestMode) - - svc := service.NewDataManagementServiceWithOptions(filepath.Join(t.TempDir(), "missing.sock"), 50*time.Millisecond) - h := NewDataManagementHandler(svc) - - r := gin.New() - r.GET("/api/v1/admin/data-management/agent/health", h.GetAgentHealth) - - rec := httptest.NewRecorder() - req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/data-management/agent/health", nil) - r.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Code) - - var envelope apiEnvelope - require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &envelope)) - require.Equal(t, 0, envelope.Code) - - var data struct { - Enabled bool `json:"enabled"` - Reason string `json:"reason"` - SocketPath string `json:"socket_path"` - } - require.NoError(t, json.Unmarshal(envelope.Data, &data)) - require.False(t, data.Enabled) - require.Equal(t, service.DataManagementDeprecatedReason, data.Reason) - require.Equal(t, svc.SocketPath(), data.SocketPath) -} - -func TestDataManagementHandler_NonHealthRouteReturns503WhenDisabled(t *testing.T) { - gin.SetMode(gin.TestMode) - - svc := service.NewDataManagementServiceWithOptions(filepath.Join(t.TempDir(), "missing.sock"), 50*time.Millisecond) - h := NewDataManagementHandler(svc) - - r := gin.New() - r.GET("/api/v1/admin/data-management/config", h.GetConfig) - - rec := httptest.NewRecorder() - req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/data-management/config", nil) - r.ServeHTTP(rec, req) - - require.Equal(t, http.StatusServiceUnavailable, rec.Code) - - var envelope apiEnvelope - require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &envelope)) - require.Equal(t, http.StatusServiceUnavailable, envelope.Code) - require.Equal(t, service.DataManagementDeprecatedReason, envelope.Reason) -} - -func TestNormalizeBackupIdempotencyKey(t *testing.T) { - require.Equal(t, "from-header", normalizeBackupIdempotencyKey("from-header", "from-body")) - require.Equal(t, "from-body", normalizeBackupIdempotencyKey(" ", " from-body ")) - require.Equal(t, "", normalizeBackupIdempotencyKey("", "")) -} diff --git a/backend/internal/handler/handler.go b/backend/internal/handler/handler.go index 6579f7fe..9560f1ff 100644 --- a/backend/internal/handler/handler.go +++ b/backend/internal/handler/handler.go @@ -11,7 +11,6 @@ type AdminHandlers struct { Group *admin.GroupHandler Account *admin.AccountHandler Announcement *admin.AnnouncementHandler - DataManagement *admin.DataManagementHandler Backup *admin.BackupHandler OAuth *admin.OAuthHandler OpenAIOAuth *admin.OpenAIOAuthHandler diff --git a/backend/internal/handler/wire.go b/backend/internal/handler/wire.go index 2358ac04..9a2290ea 100644 --- a/backend/internal/handler/wire.go +++ b/backend/internal/handler/wire.go @@ -14,7 +14,6 @@ func ProvideAdminHandlers( groupHandler *admin.GroupHandler, accountHandler *admin.AccountHandler, announcementHandler *admin.AnnouncementHandler, - dataManagementHandler *admin.DataManagementHandler, backupHandler *admin.BackupHandler, oauthHandler *admin.OAuthHandler, openaiOAuthHandler *admin.OpenAIOAuthHandler, @@ -43,7 +42,6 @@ func ProvideAdminHandlers( Group: groupHandler, Account: accountHandler, Announcement: announcementHandler, - DataManagement: dataManagementHandler, Backup: backupHandler, OAuth: oauthHandler, OpenAIOAuth: openaiOAuthHandler, @@ -144,7 +142,6 @@ var ProviderSet = wire.NewSet( admin.NewGroupHandler, admin.NewAccountHandler, admin.NewAnnouncementHandler, - admin.NewDataManagementHandler, admin.NewBackupHandler, admin.NewOAuthHandler, admin.NewOpenAIOAuthHandler, diff --git a/backend/internal/server/routes/admin.go b/backend/internal/server/routes/admin.go index c8c0f4a7..47dde749 100644 --- a/backend/internal/server/routes/admin.go +++ b/backend/internal/server/routes/admin.go @@ -54,7 +54,6 @@ func RegisterAdminRoutes( registerSettingsRoutes(admin, h) // 数据管理 - registerDataManagementRoutes(admin, h) // 数据库备份恢复 registerBackupRoutes(admin, h) @@ -425,29 +424,6 @@ func registerSettingsRoutes(admin *gin.RouterGroup, h *handler.Handlers) { } } -func registerDataManagementRoutes(admin *gin.RouterGroup, h *handler.Handlers) { - dataManagement := admin.Group("/data-management") - { - dataManagement.GET("/agent/health", h.Admin.DataManagement.GetAgentHealth) - dataManagement.GET("/config", h.Admin.DataManagement.GetConfig) - dataManagement.PUT("/config", h.Admin.DataManagement.UpdateConfig) - dataManagement.GET("/sources/:source_type/profiles", h.Admin.DataManagement.ListSourceProfiles) - dataManagement.POST("/sources/:source_type/profiles", h.Admin.DataManagement.CreateSourceProfile) - dataManagement.PUT("/sources/:source_type/profiles/:profile_id", h.Admin.DataManagement.UpdateSourceProfile) - dataManagement.DELETE("/sources/:source_type/profiles/:profile_id", h.Admin.DataManagement.DeleteSourceProfile) - dataManagement.POST("/sources/:source_type/profiles/:profile_id/activate", h.Admin.DataManagement.SetActiveSourceProfile) - dataManagement.POST("/s3/test", h.Admin.DataManagement.TestS3) - dataManagement.GET("/s3/profiles", h.Admin.DataManagement.ListS3Profiles) - dataManagement.POST("/s3/profiles", h.Admin.DataManagement.CreateS3Profile) - dataManagement.PUT("/s3/profiles/:profile_id", h.Admin.DataManagement.UpdateS3Profile) - dataManagement.DELETE("/s3/profiles/:profile_id", h.Admin.DataManagement.DeleteS3Profile) - dataManagement.POST("/s3/profiles/:profile_id/activate", h.Admin.DataManagement.SetActiveS3Profile) - dataManagement.POST("/backups", h.Admin.DataManagement.CreateBackupJob) - dataManagement.GET("/backups", h.Admin.DataManagement.ListBackupJobs) - dataManagement.GET("/backups/:job_id", h.Admin.DataManagement.GetBackupJob) - } -} - func registerBackupRoutes(admin *gin.RouterGroup, h *handler.Handlers) { backup := admin.Group("/backups") { diff --git a/backend/internal/server/routes/admin_routes_test.go b/backend/internal/server/routes/admin_routes_test.go index 6df3ac8a..7a6fc894 100644 --- a/backend/internal/server/routes/admin_routes_test.go +++ b/backend/internal/server/routes/admin_routes_test.go @@ -33,6 +33,9 @@ func TestRegisterAdminRoutes_OmitsDeprecatedMockEndpoints(t *testing.T) { "GET /api/v1/admin/users/:id/usage", "GET /api/v1/admin/proxies/:id/stats", "GET /api/v1/admin/redeem-codes/stats", + "GET /api/v1/admin/data-management/agent/health", + "GET /api/v1/admin/data-management/config", + "POST /api/v1/admin/data-management/backups", } for _, route := range deprecatedRoutes {