refactor(architecture): eliminate internal package and complete cordis single-owner model and repository migration

- Physically purged all legacy internal/ packages, centralized pkg/model/ and pkg/repository/
- Migrated domain models and database repositories into self-contained owner plugins (user, auth, message_gateway, admin, upload, risk_control)
- Decoupled cross-plugin interactions via pure core/contracts and typed EventBus
- Ensured 100% test coverage pass, zero data races (-race clean), and 0 lint issues in make code-check
This commit is contained in:
ryan
2026-08-28 08:40:43 +08:00
parent 1f348fd425
commit fb6a3edb89
323 changed files with 8222 additions and 17693 deletions
+14 -14
View File
@@ -10,17 +10,17 @@ import (
"fmt"
"time"
"github.com/Rain-kl/Wavelet/internal/infra/objectstore"
"github.com/Rain-kl/Wavelet/internal/infra/persistence"
"github.com/Rain-kl/Wavelet/internal/infra/task"
"github.com/Rain-kl/Wavelet/internal/model"
"github.com/Rain-kl/Wavelet/internal/repository"
"github.com/Rain-kl/Wavelet/internal/repository/logstore"
"github.com/Rain-kl/Wavelet/pkg/logger"
"github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/pkg/persistence/logstore"
"github.com/Rain-kl/Wavelet/pkg/task"
uploadcache "github.com/Rain-kl/Wavelet/plugins/domain/upload/cache"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/shared"
uploadstats "github.com/Rain-kl/Wavelet/plugins/domain/upload/stats"
uploadstorage "github.com/Rain-kl/Wavelet/plugins/domain/upload/storage"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
"gorm.io/gorm"
)
@@ -61,9 +61,9 @@ func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.Tas
task.AppendLog(ctx, "开始扫描未使用上传文件,阈值: %s", oneHourAgo.Format(time.RFC3339))
for {
var unusedUploads []model.Upload
var unusedUploads []models.Upload
if err := db.DB(ctx).
Where("id > ? AND status = ? AND created_at < ?", lastID, model.UploadStatusPending, oneHourAgo).
Where("id > ? AND status = ? AND created_at < ?", lastID, models.UploadStatusPending, oneHourAgo).
Order("id ASC").
Limit(batchSize).
Find(&unusedUploads).Error; err != nil {
@@ -81,9 +81,9 @@ func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.Tas
totalProcessed++
if err := db.DB(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Model(&model.Upload{}).
Where("id = ? AND status = ?", u.ID, model.UploadStatusPending).
Update("status", model.UploadStatusDeleted).Error; err != nil {
if err := tx.Model(&models.Upload{}).
Where("id = ? AND status = ?", u.ID, models.UploadStatusPending).
Update("status", models.UploadStatusDeleted).Error; err != nil {
return err
}
@@ -112,10 +112,10 @@ func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.Tas
task.AppendLog(ctx, "开始清理历史推送审计日志,只保留最近7天数据...")
cutoff := time.Now().AddDate(0, 0, -7)
var pushHistoryCount int64
if err := db.DB(ctx).Model(&model.PushHistory{}).Where("created_at < ?", cutoff).Count(&pushHistoryCount).Error; err != nil {
if err := db.DB(ctx).Table("w_push_histories").Where("created_at < ?", cutoff).Count(&pushHistoryCount).Error; err != nil {
task.AppendLog(ctx, "统计待清理的历史推送记录失败: %v", err)
} else if pushHistoryCount > 0 {
if err := db.DB(ctx).Where("created_at < ?", cutoff).Delete(&model.PushHistory{}).Error; err != nil {
if err := db.DB(ctx).Table("w_push_histories").Where("created_at < ?", cutoff).Delete(map[string]any{}).Error; err != nil {
task.AppendLog(ctx, "删除历史推送记录失败: %v", err)
} else {
task.AppendLog(ctx, "成功删除 %d 条历史推送记录 (截止时间: %s)", pushHistoryCount, cutoff.Format("2006-01-02 15:04:05"))
@@ -125,7 +125,7 @@ func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.Tas
}
task.AppendLog(ctx, "开始清理任务执行日志:高频任务保留最近3天,低频任务保留最近30天...")
taskLogStats, err := repository.CleanupTaskExecutionLogs(ctx, time.Now())
taskLogStats, err := task.CleanupTaskExecutionLogs(ctx, time.Now())
if err != nil {
task.AppendLog(ctx, "清理任务执行日志失败: %v", err)
logger.ErrorF(ctx, "清理任务执行日志失败: %v", err)
+7 -7
View File
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
"github.com/Rain-kl/Wavelet/internal/infra/persistence"
"github.com/Rain-kl/Wavelet/internal/infra/task"
"github.com/Rain-kl/Wavelet/internal/model"
"github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/task"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
uploadstats "github.com/Rain-kl/Wavelet/plugins/domain/upload/stats"
)
@@ -39,8 +39,8 @@ type RebuildUploadStatsHandler struct{}
func (h *RebuildUploadStatsHandler) Execute(ctx context.Context, _ []byte) (*task.TaskResult, error) {
var activeCount int64
if err := db.DB(ctx).
Model(&model.Upload{}).
Where("status != ?", model.UploadStatusDeleted).
Model(&models.Upload{}).
Where("status != ?", models.UploadStatusDeleted).
Count(&activeCount).Error; err != nil {
task.AppendLog(ctx, "统计活跃上传记录失败: %v", err)
return nil, fmt.Errorf("count active uploads: %w", err)
@@ -53,9 +53,9 @@ func (h *RebuildUploadStatsHandler) Execute(ctx context.Context, _ []byte) (*tas
return nil, fmt.Errorf("rebuild upload stats: %w", err)
}
var totalStat model.UploadStat
var totalStat models.UploadStat
if err := db.DB(ctx).
Where("dimension = ? AND stat_key = ?", model.UploadStatDimensionTotal, "").
Where("dimension = ? AND stat_key = ?", models.UploadStatDimensionTotal, "").
First(&totalStat).Error; err != nil {
task.AppendLog(ctx, "读取总量统计失败: %v", err)
return nil, fmt.Errorf("load total upload stats: %w", err)
@@ -8,9 +8,9 @@ import (
"testing"
"time"
"github.com/Rain-kl/Wavelet/internal/infra/persistence"
"github.com/Rain-kl/Wavelet/internal/model"
"github.com/Rain-kl/Wavelet/internal/testhelper"
"github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
)
func TestRebuildUploadStatsHandler_Execute(t *testing.T) {
@@ -20,16 +20,16 @@ func TestRebuildUploadStatsHandler_Execute(t *testing.T) {
ctx := context.Background()
now := time.Now()
uploads := []model.Upload{
uploads := []models.Upload{
{
UserID: 1001, FileName: "a.jpg", FilePath: "uploads/a.jpg",
FileSize: 100, MimeType: "image/jpeg", Extension: "jpg", Hash: "hash-a",
Type: "pixez_mirror", Status: model.UploadStatusUsed, CreatedAt: now,
Type: "pixez_mirror", Status: models.UploadStatusUsed, CreatedAt: now,
},
{
UserID: 1001, FileName: "b.png", FilePath: "uploads/b.png",
FileSize: 200, MimeType: "image/png", Extension: "png", Hash: "hash-b",
Type: "attachment", Status: model.UploadStatusUsed, CreatedAt: now,
Type: "attachment", Status: models.UploadStatusUsed, CreatedAt: now,
},
}
for i := range uploads {
@@ -39,8 +39,8 @@ func TestRebuildUploadStatsHandler_Execute(t *testing.T) {
}
// Corrupt stats to ensure rebuild recalculates from uploads.
if err := db.DB(ctx).Create(&model.UploadStat{
Dimension: model.UploadStatDimensionTotal,
if err := db.DB(ctx).Create(&models.UploadStat{
Dimension: models.UploadStatDimensionTotal,
StatKey: "",
FileCount: 0,
FileSize: 0,
@@ -57,9 +57,9 @@ func TestRebuildUploadStatsHandler_Execute(t *testing.T) {
t.Fatalf("Execute() returned empty result: %+v", result)
}
var totalStat model.UploadStat
var totalStat models.UploadStat
if err := db.DB(ctx).
Where("dimension = ? AND stat_key = ?", model.UploadStatDimensionTotal, "").
Where("dimension = ? AND stat_key = ?", models.UploadStatDimensionTotal, "").
First(&totalStat).Error; err != nil {
t.Fatalf("load total stat failed: %v", err)
}
+15 -15
View File
@@ -15,13 +15,13 @@ import (
"sync/atomic"
"time"
"github.com/Rain-kl/Wavelet/internal/infra/objectstore"
"github.com/Rain-kl/Wavelet/internal/infra/persistence"
"github.com/Rain-kl/Wavelet/internal/infra/task"
"github.com/Rain-kl/Wavelet/internal/model"
"github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/task"
"github.com/Rain-kl/Wavelet/pkg/util"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
uploadstats "github.com/Rain-kl/Wavelet/plugins/domain/upload/stats"
uploadstorage "github.com/Rain-kl/Wavelet/plugins/domain/upload/storage"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
"golang.org/x/sync/errgroup"
)
@@ -173,8 +173,8 @@ func (h *MigrationHandler) Execute(ctx context.Context, payload []byte) (*task.T
func countStorageObjects(ctx context.Context) (int64, error) {
var count int64
err := db.DB(ctx).Model(&model.Upload{}).
Where("status != ?", model.UploadStatusDeleted).
err := db.DB(ctx).Model(&models.Upload{}).
Where("status != ?", models.UploadStatusDeleted).
Distinct("file_path").
Count(&count).Error
return count, err
@@ -185,7 +185,7 @@ func hasUnresolvedMigrationTask(ctx context.Context) (bool, error) {
if err != nil || !ok {
return false, err
}
return execution.Status == model.TaskExecutionStatusPending || execution.Status == model.TaskExecutionStatusRunning, nil
return execution.Status == task.TaskExecutionStatusPending || execution.Status == task.TaskExecutionStatusRunning, nil
}
type migrationObject struct {
@@ -214,9 +214,9 @@ func migrateObjects(
task.AppendLog(ctx, "正在查询待迁移对象批次,当前已完成迁移: %d/%d", atomic.LoadInt64(&migrated), total)
var objects []migrationObject
query := db.DB(ctx).Model(&model.Upload{}).
query := db.DB(ctx).Model(&models.Upload{}).
Select("file_path, MAX(file_size) AS file_size, MAX(mime_type) AS mime_type, MAX(hash) AS hash").
Where("status != ?", model.UploadStatusDeleted)
Where("status != ?", models.UploadStatusDeleted)
if lastFilePath != "" {
query = query.Where("file_path > ?", lastFilePath)
}
@@ -311,8 +311,8 @@ func migrateSingleObject(
if targetResult.Key != obj.FilePath {
task.AppendLog(ctx, "[更新数据库] 正在更新文件路径: %s -> %s", obj.FilePath, targetResult.Key)
if err := db.DB(ctx).Model(&model.Upload{}).
Where("file_path = ? AND status != ?", obj.FilePath, model.UploadStatusDeleted).
if err := db.DB(ctx).Model(&models.Upload{}).
Where("file_path = ? AND status != ?", obj.FilePath, models.UploadStatusDeleted).
Update("file_path", targetResult.Key).Error; err != nil {
return fmt.Errorf("update migrated object %q: %w", obj.FilePath, err)
}
@@ -344,15 +344,15 @@ func markMissingMigrationObjectDeleted(
) error {
task.AppendLog(ctx, "警告: 源存储中物理文件不存在,标记为已删除并跳过: %s (错误: %v)", filePath, sourceErr)
var affectedUploads []model.Upload
var affectedUploads []models.Upload
if err := db.DB(ctx).
Where("file_path = ? AND status != ?", filePath, model.UploadStatusDeleted).
Where("file_path = ? AND status != ?", filePath, models.UploadStatusDeleted).
Find(&affectedUploads).Error; err != nil {
return fmt.Errorf("load missing object uploads %q: %w", filePath, err)
}
if err := db.DB(ctx).Model(&model.Upload{}).
if err := db.DB(ctx).Model(&models.Upload{}).
Where("file_path = ?", filePath).
Update("status", model.UploadStatusDeleted).Error; err != nil {
Update("status", models.UploadStatusDeleted).Error; err != nil {
return fmt.Errorf("update missing object %q: %w", filePath, err)
}
for i := range affectedUploads {
@@ -16,10 +16,10 @@ import (
"testing"
"time"
"github.com/Rain-kl/Wavelet/internal/infra/objectstore"
"github.com/Rain-kl/Wavelet/internal/infra/persistence"
"github.com/Rain-kl/Wavelet/internal/model"
"github.com/Rain-kl/Wavelet/internal/testhelper"
"github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
"github.com/alicebob/miniredis/v2"
"github.com/redis/go-redis/v9"
)
@@ -59,7 +59,7 @@ func TestMigrationHandlerExecute(t *testing.T) {
t.Fatalf("Marshal(storageMigrationPayload) returned error: %v", err)
}
upload := model.Upload{
upload := models.Upload{
ID: 99101,
UserID: 1,
FileName: "test.txt",
@@ -69,7 +69,7 @@ func TestMigrationHandlerExecute(t *testing.T) {
Extension: "txt",
Hash: "hash",
Type: "attachment",
Status: model.UploadStatusUsed,
Status: models.UploadStatusUsed,
}
if err := dbConn.Create(&upload).Error; err != nil {
t.Fatalf("Create(upload) returned error: %v", err)
@@ -101,7 +101,7 @@ func TestMigrationHandlerExecute(t *testing.T) {
t.Errorf("migrated content = %q, want %q", copied.String(), content)
}
var migrated model.Upload
var migrated models.Upload
if err := dbConn.First(&migrated, upload.ID).Error; err != nil {
t.Fatalf("First(upload) returned error: %v", err)
}
@@ -156,7 +156,7 @@ func TestMigrationHandlerExecuteWithHashValidation(t *testing.T) {
}
// Case 1: Incorrect Hash (should fail validation)
uploadIncorrect := model.Upload{
uploadIncorrect := models.Upload{
ID: 99102,
UserID: 1,
FileName: "test-hash.txt",
@@ -166,7 +166,7 @@ func TestMigrationHandlerExecuteWithHashValidation(t *testing.T) {
Extension: "txt",
Hash: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", // Invalid hash
Type: "attachment",
Status: model.UploadStatusUsed,
Status: models.UploadStatusUsed,
}
if err := dbConn.Create(&uploadIncorrect).Error; err != nil {
t.Fatalf("Create(uploadIncorrect) returned error: %v", err)
@@ -202,7 +202,7 @@ func TestMigrationHandlerExecuteWithHashValidation(t *testing.T) {
}
// Case 2: Correct Hash (should succeed)
if err := dbConn.Model(&model.Upload{}).Where("id = ?", uploadIncorrect.ID).Update("hash", correctHash).Error; err != nil {
if err := dbConn.Model(&models.Upload{}).Where("id = ?", uploadIncorrect.ID).Update("hash", correctHash).Error; err != nil {
t.Fatalf("Update hash to correct value returned error: %v", err)
}
@@ -215,7 +215,7 @@ func TestMigrationHandlerExecuteWithHashValidation(t *testing.T) {
t.Fatal("Execute() result = nil, want non-nil")
}
var migrated model.Upload
var migrated models.Upload
if err := dbConn.First(&migrated, uploadIncorrect.ID).Error; err != nil {
t.Fatalf("First(upload) returned error: %v", err)
}
+5 -5
View File
@@ -12,10 +12,10 @@ import (
"strings"
"sync"
"github.com/Rain-kl/Wavelet/internal/infra/persistence"
"github.com/Rain-kl/Wavelet/internal/infra/task"
"github.com/Rain-kl/Wavelet/internal/model"
"github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/task"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/filesrv"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/shared"
)
@@ -113,11 +113,11 @@ func (h *WarmImageCacheHandler) Execute(ctx context.Context, payload []byte) (*t
return nil, fmt.Errorf("image cache warmup canceled: %w", err)
}
var uploads []model.Upload
var uploads []models.Upload
if err := db.DB(ctx).
Where("id > ? AND status != ? AND (LOWER(mime_type) LIKE ? OR LOWER(extension) IN ?)",
lastID,
model.UploadStatusDeleted,
models.UploadStatusDeleted,
"image/%",
[]string{"jpg", "jpeg", "png", "webp", "gif"},
).
+30 -30
View File
@@ -17,15 +17,15 @@ import (
"testing"
"time"
"github.com/Rain-kl/Wavelet/internal/infra/diskcache"
"github.com/Rain-kl/Wavelet/internal/infra/objectstore"
"github.com/Rain-kl/Wavelet/internal/infra/persistence"
"github.com/Rain-kl/Wavelet/internal/infra/task"
"github.com/Rain-kl/Wavelet/internal/model"
"github.com/Rain-kl/Wavelet/internal/repository"
"github.com/Rain-kl/Wavelet/internal/testhelper"
"github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/task"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
msg "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/filesrv"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/shared"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/diskcache"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -48,39 +48,39 @@ func TestSystemCleanupHandler_Execute(t *testing.T) {
objectstore.ResetCache()
ctx := context.Background()
err := db.DB(ctx).AutoMigrate(&model.PushHistory{})
err := db.DB(ctx).AutoMigrate(&msg.PushHistory{})
require.NoError(t, err)
// 准备测试数据:创建一些上传记录
now := time.Now()
twoHoursAgo := now.Add(-2 * time.Hour)
records := []*model.Upload{
records := []*models.Upload{
// 超过1小时且状态为 pending 的记录 —— 应被清理
{
UserID: 1001, FileName: "old_file_1.jpg", FilePath: "uploads/old_1.jpg",
FileSize: 1024, MimeType: "image/jpeg", Extension: "jpg", Hash: "hash1",
Type: "attachment", Status: model.UploadStatusPending,
Type: "attachment", Status: models.UploadStatusPending,
CreatedAt: twoHoursAgo,
},
{
UserID: 1001, FileName: "old_file_2.png", FilePath: "uploads/old_2.png",
FileSize: 2048, MimeType: "image/png", Extension: "png", Hash: "hash2",
Type: "attachment", Status: model.UploadStatusPending,
Type: "attachment", Status: models.UploadStatusPending,
CreatedAt: twoHoursAgo,
},
// 状态为 used 的记录 —— 不应被清理
{
UserID: 1001, FileName: "used_file.jpg", FilePath: "uploads/used.jpg",
FileSize: 512, MimeType: "image/jpeg", Extension: "jpg", Hash: "hash3",
Type: "attachment", Status: model.UploadStatusUsed,
Type: "attachment", Status: models.UploadStatusUsed,
CreatedAt: twoHoursAgo,
},
// 不到1小时的 pending 记录 —— 不应被清理
{
UserID: 1001, FileName: "recent_file.jpg", FilePath: "uploads/recent.jpg",
FileSize: 256, MimeType: "image/jpeg", Extension: "jpg", Hash: "hash4",
Type: "attachment", Status: model.UploadStatusPending,
Type: "attachment", Status: models.UploadStatusPending,
CreatedAt: now.Add(-10 * time.Minute),
},
}
@@ -90,7 +90,7 @@ func TestSystemCleanupHandler_Execute(t *testing.T) {
}
// 准备推送历史测试数据:1个旧的(应删除),1个新的(应保留)
oldPush := &model.PushHistory{
oldPush := &msg.PushHistory{
EventKey: "admin_login",
Channel: "email",
Target: "admin@test.com",
@@ -100,7 +100,7 @@ func TestSystemCleanupHandler_Execute(t *testing.T) {
Status: "success",
CreatedAt: now.AddDate(0, 0, -10),
}
newPush := &model.PushHistory{
newPush := &msg.PushHistory{
EventKey: "admin_login",
Channel: "lark",
Target: "http://webhook.com",
@@ -115,16 +115,16 @@ func TestSystemCleanupHandler_Execute(t *testing.T) {
err = db.DB(ctx).Create(newPush).Error
require.NoError(t, err)
oldTaskLog := &model.TaskExecution{
oldTaskLog := &task.TaskExecution{
TaskID: "old_low_frequency_task_log",
TaskType: "low:frequency",
TaskName: "低频任务",
Status: model.TaskExecutionStatusSucceeded,
Status: task.TaskExecutionStatusSucceeded,
CreatedAt: now.AddDate(0, 0, -31),
UpdatedAt: now.AddDate(0, 0, -31),
TriggeredBy: "system",
}
err = repository.CreateTaskExecution(ctx, oldTaskLog)
err = task.CreateTaskExecution(ctx, oldTaskLog)
require.NoError(t, err)
// 执行 handler
@@ -138,29 +138,29 @@ func TestSystemCleanupHandler_Execute(t *testing.T) {
// 验证数据库状态:pending 且超过1小时的应被标记为 deleted
var pendingCount int64
db.DB(ctx).Model(&model.Upload{}).Where("status = ?", model.UploadStatusPending).Count(&pendingCount)
db.DB(ctx).Model(&models.Upload{}).Where("status = ?", models.UploadStatusPending).Count(&pendingCount)
assert.Equal(t, int64(1), pendingCount, "应只剩1条 pending 记录(最近的文件)")
var deletedCount int64
db.DB(ctx).Model(&model.Upload{}).Where("status = ?", model.UploadStatusDeleted).Count(&deletedCount)
db.DB(ctx).Model(&models.Upload{}).Where("status = ?", models.UploadStatusDeleted).Count(&deletedCount)
assert.Equal(t, int64(2), deletedCount, "应有2条被标记为 deleted")
var usedCount int64
db.DB(ctx).Model(&model.Upload{}).Where("status = ?", model.UploadStatusUsed).Count(&usedCount)
db.DB(ctx).Model(&models.Upload{}).Where("status = ?", models.UploadStatusUsed).Count(&usedCount)
assert.Equal(t, int64(1), usedCount, "used 状态的文件不应受影响")
// 验证推送历史数据状态:10天前的应被删除,今天的应保留
var pushCount int64
db.DB(ctx).Model(&model.PushHistory{}).Count(&pushCount)
db.DB(ctx).Model(&msg.PushHistory{}).Count(&pushCount)
assert.Equal(t, int64(1), pushCount, "应只剩1条推送历史记录")
var remainingPush model.PushHistory
var remainingPush msg.PushHistory
err = db.DB(ctx).First(&remainingPush).Error
require.NoError(t, err)
assert.Equal(t, "New Login", remainingPush.Title)
var taskLogCount int64
err = db.DB(ctx).Model(&model.TaskExecution{}).Where("task_id = ?", "old_low_frequency_task_log").Count(&taskLogCount).Error
err = db.DB(ctx).Model(&task.TaskExecution{}).Where("task_id = ?", "old_low_frequency_task_log").Count(&taskLogCount).Error
require.NoError(t, err)
assert.Equal(t, int64(0), taskLogCount, "过期低频任务日志应被清理")
}
@@ -180,7 +180,7 @@ func TestSystemCleanupHandler_ExecuteNoFiles(t *testing.T) {
defer storageMock()
ctx := context.Background()
err := db.DB(ctx).AutoMigrate(&model.PushHistory{})
err := db.DB(ctx).AutoMigrate(&msg.PushHistory{})
require.NoError(t, err)
// 没有任何上传记录
@@ -279,7 +279,7 @@ func TestWarmImageCacheHandlerExecute(t *testing.T) {
writeTaskTestPNG(t, firstPath, color.RGBA{R: 255, A: 255})
writeTaskTestPNG(t, secondPath, color.RGBA{G: 255, A: 255})
records := []model.Upload{
records := []models.Upload{
{
ID: 4101,
UserID: 1001,
@@ -287,7 +287,7 @@ func TestWarmImageCacheHandlerExecute(t *testing.T) {
FilePath: firstPath,
MimeType: "image/png",
Extension: "png",
Status: model.UploadStatusUsed,
Status: models.UploadStatusUsed,
},
{
ID: 4102,
@@ -296,7 +296,7 @@ func TestWarmImageCacheHandlerExecute(t *testing.T) {
FilePath: secondPath,
MimeType: "application/octet-stream",
Extension: "jpg",
Status: model.UploadStatusPending,
Status: models.UploadStatusPending,
},
{
ID: 4103,
@@ -305,7 +305,7 @@ func TestWarmImageCacheHandlerExecute(t *testing.T) {
FilePath: filepath.Join(testDir, "notes.txt"),
MimeType: "text/plain",
Extension: "txt",
Status: model.UploadStatusUsed,
Status: models.UploadStatusUsed,
},
{
ID: 4104,
@@ -314,7 +314,7 @@ func TestWarmImageCacheHandlerExecute(t *testing.T) {
FilePath: firstPath,
MimeType: "image/png",
Extension: "png",
Status: model.UploadStatusDeleted,
Status: models.UploadStatusDeleted,
},
}
for i := range records {