refactor(repository): 收敛 model/repository 分层为唯一持久化入口

将 OpenFlare 与平台业务的数据访问从 model 与 apps 直连迁入 repository,
model 仅保留实体与无 IO 规则;补充 code-check 架构守卫与开发规范。
This commit is contained in:
ryan
2026-07-24 17:00:17 +08:00
parent 23a5488203
commit 943818f7d4
184 changed files with 5592 additions and 4364 deletions
+10 -8
View File
@@ -11,6 +11,8 @@ import (
"strings"
"time"
"github.com/Rain-kl/Wavelet/internal/repository"
"github.com/Rain-kl/Wavelet/internal/apps/admin"
"github.com/Rain-kl/Wavelet/internal/infra/task"
"github.com/Rain-kl/Wavelet/internal/infra/task/scheduler"
@@ -119,7 +121,7 @@ func ListTaskExecutions(c *gin.Context) {
}
}
executions, total, err := model.ListTaskExecutions(c.Request.Context(), req)
executions, total, err := repository.ListTaskExecutions(c.Request.Context(), req)
if err != nil {
response.AbortInternal(c, err.Error())
return
@@ -153,7 +155,7 @@ func GetTaskExecution(c *gin.Context) {
return
}
execution, err := model.GetTaskExecutionByID(c.Request.Context(), id)
execution, err := repository.GetTaskExecutionByID(c.Request.Context(), id)
if err != nil {
response.AbortNotFound(c, TaskNotFound)
return
@@ -211,7 +213,7 @@ func RetryTask(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Router /api/v1/admin/tasks/schedules [get]
func ListSchedules(c *gin.Context) {
schedules, err := model.ListSchedules(c.Request.Context())
schedules, err := repository.ListSchedules(c.Request.Context())
if err != nil {
response.AbortInternal(c, err.Error())
return
@@ -289,7 +291,7 @@ func CreateSchedule(c *gin.Context) {
IsActive: *req.IsActive,
}
if err := model.CreateSchedule(c.Request.Context(), schedule); err != nil {
if err := repository.CreateSchedule(c.Request.Context(), schedule); err != nil {
response.AbortInternal(c, fmt.Sprintf("%s: %v", ScheduleSaveFailed, err))
return
}
@@ -341,7 +343,7 @@ func UpdateSchedule(c *gin.Context) {
}
// 检查定时任务是否存在
schedule, err := model.GetScheduleByID(c.Request.Context(), id)
schedule, err := repository.GetScheduleByID(c.Request.Context(), id)
if err != nil {
response.AbortNotFound(c, ScheduleNotFound)
return
@@ -381,7 +383,7 @@ func UpdateSchedule(c *gin.Context) {
schedule.Payload = string(validated)
schedule.IsActive = *req.IsActive
if err := model.UpdateSchedule(c.Request.Context(), schedule); err != nil {
if err := repository.UpdateSchedule(c.Request.Context(), schedule); err != nil {
response.AbortInternal(c, fmt.Sprintf("%s: %v", ScheduleSaveFailed, err))
return
}
@@ -422,7 +424,7 @@ func DeleteSchedule(c *gin.Context) {
response.AbortBadRequest(c, "无效的定时任务ID")
return
}
schedule, err := model.GetScheduleByID(c.Request.Context(), id)
schedule, err := repository.GetScheduleByID(c.Request.Context(), id)
if err != nil {
response.AbortNotFound(c, ScheduleNotFound)
return
@@ -432,7 +434,7 @@ func DeleteSchedule(c *gin.Context) {
return
}
if err := model.DeleteSchedule(c.Request.Context(), id); err != nil {
if err := repository.DeleteSchedule(c.Request.Context(), id); err != nil {
response.AbortInternal(c, fmt.Sprintf("%s: %v", ScheduleDeleteFailed, err))
return
}
+18 -16
View File
@@ -14,6 +14,8 @@ import (
"testing"
"time"
"github.com/Rain-kl/Wavelet/internal/repository"
"github.com/Rain-kl/Wavelet/internal/apps/oauth"
uploadtask "github.com/Rain-kl/Wavelet/internal/apps/upload/task"
"github.com/Rain-kl/Wavelet/internal/apps/user"
@@ -154,8 +156,8 @@ func TestInternalOnlyTaskAdminBoundaries(t *testing.T) {
Payload: "{}",
IsActive: true,
}
require.NoError(t, model.CreateSchedule(ctx, internalSchedule))
require.NoError(t, model.CreateSchedule(ctx, publicSchedule))
require.NoError(t, repository.CreateSchedule(ctx, internalSchedule))
require.NoError(t, repository.CreateSchedule(ctx, publicSchedule))
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/tasks/schedules", nil)
w := httptest.NewRecorder()
@@ -215,7 +217,7 @@ func TestInternalOnlyTaskAdminBoundaries(t *testing.T) {
Cron: "0 * * * *",
IsActive: true,
}
require.NoError(t, model.CreateSchedule(ctx, schedule))
require.NoError(t, repository.CreateSchedule(ctx, schedule))
isActive := false
body, err := json.Marshal(UpdateScheduleRequest{
Name: "尝试修改内部排程",
@@ -235,7 +237,7 @@ func TestInternalOnlyTaskAdminBoundaries(t *testing.T) {
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusBadRequest, w.Code)
unchanged, err := model.GetScheduleByID(ctx, schedule.ID)
unchanged, err := repository.GetScheduleByID(ctx, schedule.ID)
require.NoError(t, err)
assert.Equal(t, "系统内部排程", unchanged.Name)
assert.Equal(t, testInternalOnlyTaskType, unchanged.TaskType)
@@ -249,7 +251,7 @@ func TestInternalOnlyTaskAdminBoundaries(t *testing.T) {
Cron: "0 * * * *",
IsActive: true,
}
require.NoError(t, model.CreateSchedule(ctx, schedule))
require.NoError(t, repository.CreateSchedule(ctx, schedule))
isActive := true
body, err := json.Marshal(UpdateScheduleRequest{
Name: "尝试切入内部任务",
@@ -269,7 +271,7 @@ func TestInternalOnlyTaskAdminBoundaries(t *testing.T) {
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusBadRequest, w.Code)
unchanged, err := model.GetScheduleByID(ctx, schedule.ID)
unchanged, err := repository.GetScheduleByID(ctx, schedule.ID)
require.NoError(t, err)
assert.Equal(t, "公开排程", unchanged.Name)
assert.Equal(t, uploadtask.TaskTypeSystemCleanup, unchanged.TaskType)
@@ -282,7 +284,7 @@ func TestInternalOnlyTaskAdminBoundaries(t *testing.T) {
Cron: "*/5 * * * *",
IsActive: true,
}
require.NoError(t, model.CreateSchedule(ctx, schedule))
require.NoError(t, repository.CreateSchedule(ctx, schedule))
req := httptest.NewRequest(
http.MethodDelete,
fmt.Sprintf("/api/v1/admin/tasks/schedules/%d", schedule.ID),
@@ -296,7 +298,7 @@ func TestInternalOnlyTaskAdminBoundaries(t *testing.T) {
var resp response.Any
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
assert.Equal(t, InvalidTaskType, resp.ErrorMsg)
preserved, err := model.GetScheduleByID(ctx, schedule.ID)
preserved, err := repository.GetScheduleByID(ctx, schedule.ID)
require.NoError(t, err)
assert.Equal(t, testInternalOnlyTaskType, preserved.TaskType)
})
@@ -320,7 +322,7 @@ func TestInternalOnlyTaskAdminBoundaries(t *testing.T) {
Cron: "0 * * * *",
IsActive: false,
}
require.NoError(t, model.CreateSchedule(ctx, schedule))
require.NoError(t, repository.CreateSchedule(ctx, schedule))
req := httptest.NewRequest(
http.MethodDelete,
fmt.Sprintf("/api/v1/admin/tasks/schedules/%d", schedule.ID),
@@ -331,7 +333,7 @@ func TestInternalOnlyTaskAdminBoundaries(t *testing.T) {
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
_, err := model.GetScheduleByID(ctx, schedule.ID)
_, err := repository.GetScheduleByID(ctx, schedule.ID)
assert.Error(t, err)
})
}
@@ -470,7 +472,7 @@ func TestListTaskExecutions(t *testing.T) {
{TaskID: "exec_003", TaskType: "system:cleanup", TaskName: "系统垃圾清理", Status: model.TaskExecutionStatusPending, TriggeredBy: "manual", Retryable: true, MaxRetry: 3},
}
for _, r := range records {
err := model.CreateTaskExecution(ctx, r)
err := repository.CreateTaskExecution(ctx, r)
require.NoError(t, err)
}
@@ -581,7 +583,7 @@ func TestGetTaskExecution(t *testing.T) {
MaxRetry: 3,
TriggeredBy: "manual",
}
err := model.CreateTaskExecution(ctx, execution)
err := repository.CreateTaskExecution(ctx, execution)
require.NoError(t, err)
t.Run("get existing execution", func(t *testing.T) {
@@ -646,7 +648,7 @@ func TestRetryTask(t *testing.T) {
StartedAt: &now,
FinishedAt: &now,
}
err := model.CreateTaskExecution(ctx, execution)
err := repository.CreateTaskExecution(ctx, execution)
require.NoError(t, err)
url := fmt.Sprintf("/api/v1/admin/tasks/executions/%d/retry", execution.ID)
@@ -666,7 +668,7 @@ func TestRetryTask(t *testing.T) {
assert.True(t, ok)
assert.NotEmpty(t, newTaskID)
newExecution, err := model.GetTaskExecutionByTaskID(ctx, newTaskID)
newExecution, err := repository.GetTaskExecutionByTaskID(ctx, newTaskID)
require.NoError(t, err)
assert.Equal(t, 1, newExecution.RetryCount)
assert.Equal(t, "retry", newExecution.TriggeredBy)
@@ -682,7 +684,7 @@ func TestRetryTask(t *testing.T) {
MaxRetry: 3,
TriggeredBy: "manual",
}
err := model.CreateTaskExecution(ctx, execution)
err := repository.CreateTaskExecution(ctx, execution)
require.NoError(t, err)
url := fmt.Sprintf("/api/v1/admin/tasks/executions/%d/retry", execution.ID)
@@ -702,7 +704,7 @@ func TestRetryTask(t *testing.T) {
Retryable: false,
TriggeredBy: "manual",
}
err := model.CreateTaskExecution(ctx, execution)
err := repository.CreateTaskExecution(ctx, execution)
require.NoError(t, err)
url := fmt.Sprintf("/api/v1/admin/tasks/executions/%d/retry", execution.ID)