mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-01 22:46:38 +08:00
fix(auth): add missing masked_token column to w_access_tokens table in migrations
This commit is contained in:
@@ -38,3 +38,47 @@ func TestAdminPluginUnit(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "0 4 * * *", setting.Default)
|
||||
}
|
||||
|
||||
func TestAdminMigrationsIncludeTaskExecutionsAndSchedules(t *testing.T) {
|
||||
ctx := core.NewContext(context.Background())
|
||||
p := admin.New()
|
||||
require.NoError(t, p.Apply(ctx))
|
||||
|
||||
entry, ok := ctx.Migrations().Get("admin")
|
||||
require.True(t, ok, "admin plugin must register migrations")
|
||||
assert.Equal(t, "admin", entry.PluginID)
|
||||
|
||||
// Verify sqlite migration files include w_schedules and w_task_executions
|
||||
sqliteDir, err := entry.FS.Open("migrations/sqlite/00001_initial.sql")
|
||||
require.NoError(t, err)
|
||||
defer sqliteDir.Close()
|
||||
|
||||
stat, err := sqliteDir.Stat()
|
||||
require.NoError(t, err)
|
||||
buf := make([]byte, stat.Size())
|
||||
_, err = sqliteDir.Read(buf)
|
||||
require.NoError(t, err)
|
||||
content := string(buf)
|
||||
|
||||
assert.Contains(t, content, "CREATE TABLE IF NOT EXISTS w_task_executions")
|
||||
assert.Contains(t, content, "CREATE TABLE IF NOT EXISTS w_schedules")
|
||||
assert.Contains(t, content, "CREATE TABLE IF NOT EXISTS w_system_configs")
|
||||
assert.Contains(t, content, "CREATE TABLE IF NOT EXISTS w_templates")
|
||||
|
||||
// Verify postgres migration files include w_schedules and w_task_executions
|
||||
pgDir, err := entry.FS.Open("migrations/postgres/00001_initial.sql")
|
||||
require.NoError(t, err)
|
||||
defer pgDir.Close()
|
||||
|
||||
stat, err = pgDir.Stat()
|
||||
require.NoError(t, err)
|
||||
buf = make([]byte, stat.Size())
|
||||
_, err = pgDir.Read(buf)
|
||||
require.NoError(t, err)
|
||||
pgContent := string(buf)
|
||||
|
||||
assert.Contains(t, pgContent, "CREATE TABLE IF NOT EXISTS w_task_executions")
|
||||
assert.Contains(t, pgContent, "CREATE TABLE IF NOT EXISTS w_schedules")
|
||||
assert.Contains(t, pgContent, "CREATE TABLE IF NOT EXISTS w_system_configs")
|
||||
assert.Contains(t, pgContent, "CREATE TABLE IF NOT EXISTS w_templates")
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ CREATE TABLE IF NOT EXISTS w_access_tokens (
|
||||
user_id BIGINT NOT NULL,
|
||||
token_hash VARCHAR(64) NOT NULL UNIQUE,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
masked_token VARCHAR(64) NOT NULL DEFAULT '',
|
||||
description VARCHAR(255),
|
||||
is_admin BOOLEAN DEFAULT FALSE,
|
||||
expires_at TIMESTAMPTZ,
|
||||
|
||||
@@ -35,6 +35,7 @@ CREATE TABLE IF NOT EXISTS w_access_tokens (
|
||||
user_id BIGINT NOT NULL,
|
||||
token_hash VARCHAR(64) NOT NULL UNIQUE,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
masked_token VARCHAR(64) NOT NULL DEFAULT '',
|
||||
description VARCHAR(255),
|
||||
is_admin BOOLEAN DEFAULT 0,
|
||||
expires_at DATETIME,
|
||||
|
||||
@@ -151,6 +151,7 @@ func TestUserPlugin(t *testing.T) {
|
||||
require.NoError(t, db.New(db.WithDB(testDB)).Apply(ctx))
|
||||
require.NoError(t, cache.New().Apply(ctx))
|
||||
require.NoError(t, logger.New().Apply(ctx))
|
||||
require.NoError(t, auth.New().Apply(ctx))
|
||||
|
||||
p := user.New()
|
||||
assert.Equal(t, "user", p.Name())
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS w_schedules (
|
||||
id BIGINT PRIMARY KEY,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
task_type VARCHAR(64) NOT NULL,
|
||||
cron VARCHAR(64) NOT NULL,
|
||||
payload TEXT,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_w_schedules_is_active ON w_schedules (is_active);
|
||||
|
||||
-- Seed initial cleanup task
|
||||
INSERT INTO w_schedules (id, name, task_type, cron, payload, is_active, created_at, updated_at)
|
||||
VALUES (1, '系统定期垃圾清理', 'system_cleanup', '0 3 * * *', '{}', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS w_schedules;
|
||||
-- +goose StatementEnd
|
||||
@@ -1,24 +0,0 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS w_schedules (
|
||||
id BIGINT PRIMARY KEY,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
task_type VARCHAR(64) NOT NULL,
|
||||
cron VARCHAR(64) NOT NULL,
|
||||
payload TEXT,
|
||||
is_active BOOLEAN NOT NULL DEFAULT 1,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_w_schedules_is_active ON w_schedules (is_active);
|
||||
|
||||
-- Seed initial cleanup task
|
||||
INSERT INTO w_schedules (id, name, task_type, cron, payload, is_active, created_at, updated_at)
|
||||
VALUES (1, '系统定期垃圾清理', 'system_cleanup', '0 3 * * *', '{}', 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS w_schedules;
|
||||
-- +goose StatementEnd
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"Wavelet/core"
|
||||
"Wavelet/core/contracts"
|
||||
"context"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
@@ -17,9 +16,6 @@ import (
|
||||
"github.com/hibiken/asynq"
|
||||
)
|
||||
|
||||
//go:embed migrations/*/*.sql
|
||||
var cronMigrations embed.FS
|
||||
|
||||
// Option configures the Asynq cron scheduler driver plugin.
|
||||
type Option func(*Plugin)
|
||||
|
||||
@@ -148,9 +144,6 @@ func (p *Plugin) Apply(ctx *core.Context) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
// Register migrations for w_schedules table
|
||||
ctx.Migrations().Register("driver_asynq_cron", cronMigrations)
|
||||
|
||||
ctx.OnDispose(func() error {
|
||||
return p.Stop(context.Background())
|
||||
})
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS w_task_executions (
|
||||
id BIGINT PRIMARY KEY,
|
||||
task_id VARCHAR(128) NOT NULL UNIQUE,
|
||||
task_type VARCHAR(64) NOT NULL,
|
||||
task_name VARCHAR(128),
|
||||
status VARCHAR(32) NOT NULL,
|
||||
retryable BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
max_retry INTEGER NOT NULL DEFAULT 0,
|
||||
retry_count INTEGER NOT NULL DEFAULT 0,
|
||||
log TEXT,
|
||||
error_message TEXT,
|
||||
result TEXT,
|
||||
started_at TIMESTAMPTZ,
|
||||
finished_at TIMESTAMPTZ,
|
||||
duration BIGINT,
|
||||
payload TEXT,
|
||||
triggered_by VARCHAR(32) NOT NULL DEFAULT 'system',
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_w_task_executions_task_type ON w_task_executions (task_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_w_task_executions_status ON w_task_executions (status);
|
||||
CREATE INDEX IF NOT EXISTS idx_w_task_executions_started_at ON w_task_executions (started_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_w_task_executions_created_at ON w_task_executions (created_at);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS w_task_executions;
|
||||
-- +goose StatementEnd
|
||||
@@ -1,32 +0,0 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS w_task_executions (
|
||||
id BIGINT PRIMARY KEY,
|
||||
task_id VARCHAR(128) NOT NULL UNIQUE,
|
||||
task_type VARCHAR(64) NOT NULL,
|
||||
task_name VARCHAR(128),
|
||||
status VARCHAR(32) NOT NULL,
|
||||
retryable BOOLEAN NOT NULL DEFAULT 0,
|
||||
max_retry INTEGER NOT NULL DEFAULT 0,
|
||||
retry_count INTEGER NOT NULL DEFAULT 0,
|
||||
log TEXT,
|
||||
error_message TEXT,
|
||||
result TEXT,
|
||||
started_at DATETIME,
|
||||
finished_at DATETIME,
|
||||
duration BIGINT,
|
||||
payload TEXT,
|
||||
triggered_by VARCHAR(32) NOT NULL DEFAULT 'system',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_w_task_executions_task_type ON w_task_executions (task_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_w_task_executions_status ON w_task_executions (status);
|
||||
CREATE INDEX IF NOT EXISTS idx_w_task_executions_started_at ON w_task_executions (started_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_w_task_executions_created_at ON w_task_executions (created_at);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS w_task_executions;
|
||||
-- +goose StatementEnd
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"Wavelet/core"
|
||||
"Wavelet/core/contracts"
|
||||
"context"
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
@@ -23,9 +22,6 @@ const (
|
||||
defaultShutdownTimeout = 10 * time.Second
|
||||
)
|
||||
|
||||
//go:embed migrations/*/*.sql
|
||||
var workerMigrations embed.FS
|
||||
|
||||
// Option configures the Asynq worker driver plugin.
|
||||
type Option func(*Plugin)
|
||||
|
||||
@@ -166,9 +162,6 @@ func (p *Plugin) Apply(ctx *core.Context) error {
|
||||
core.Provide[contracts.TaskService](ctx, p.taskSvc)
|
||||
SetActiveTaskExtension(ctx.Tasks())
|
||||
|
||||
// 2. Register migrations for w_task_executions table
|
||||
ctx.Migrations().Register("driver_asynq_worker", workerMigrations)
|
||||
|
||||
ctx.OnDispose(func() error {
|
||||
SetActiveTaskExtension(nil)
|
||||
SetRedisClient(nil)
|
||||
|
||||
@@ -152,11 +152,9 @@ Wavelet 贯彻了 Cordis 核心范式,通过形式化保证解决组件系统
|
||||
| `w_users` | `backend/plugins/domain/user` | `models.go`<br>`repository.go` | `core/contracts.UserService`<br>`contracts.UserDTO` |
|
||||
| `w_auth_sources`<br>`w_external_accounts`<br>`w_access_tokens` | `backend/plugins/domain/auth` | `models.go`<br>`service.go` | `core/contracts.AuthService`<br>`contracts.AuthRegistry` |
|
||||
| `w_uploads`<br>`w_upload_stats` | `backend/plugins/domain/upload` | `models/models.go`<br>`repository/repository.go` | `core/contracts.StorageService`<br>`upload.Ingest` 流水线 |
|
||||
| `w_system_configs`<br>`w_templates` | `backend/plugins/domain/admin` | `models.go`<br>`repository.go` | `ctx.Settings()` / `contracts.ConfigService`<br>Redis Pub/Sub 广播 |
|
||||
| `w_system_configs`<br>`w_templates`<br>`w_schedules`<br>`w_task_executions` | `backend/plugins/domain/admin` | `models.go`<br>`repository.go` | `ctx.Settings()` / `contracts.ConfigService`<br>`contracts.TaskService` |
|
||||
| `w_message_channels`<br>`w_message_bindings`<br>`w_message_pairing_codes`<br>`w_push_events`<br>`w_push_channels`<br>`w_push_histories` | `backend/plugins/domain/message_gateway` | `models.go`<br>`repository.go` | `EventBus` 强类型事件广播订阅 |
|
||||
| `w_user_access_logs` | `backend/plugins/domain/risk_control` | `logstore/` | `logstore` 门面<br>ClickHouse PG/SQLite 回落 |
|
||||
| `w_schedules` | `backend/plugins/drivers/driver_asynq_cron` | `schedule.go` | `ctx.Schedule()` 扩展点 |
|
||||
| `w_task_executions` | `backend/plugins/drivers/driver_asynq_worker` | `types.go`<br>`executor.go` | `ctx.Task()` 扩展点 |
|
||||
| `w_schema_versions` | **系统内部** | `backend/cmd/app.go` sharedStore | 自动管理,不归属于任何插件 |
|
||||
|
||||
### 5.3 架构防线与单向依赖保障
|
||||
|
||||
Reference in New Issue
Block a user