From 27dc59ed63999024cc401617da258b480ac45a36 Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Wed, 1 Jul 2026 18:07:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(server):=20pro=20=E5=A5=97=E9=A4=90?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E4=B8=8A=E9=99=90=205=20=E2=86=92=203?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - seed(sqlite/mysql 000007)+ 001_init:pro max_devices 5→3(全新库直接对) - 新增迁移 000019(sqlite/mysql,up/down):UPDATE plans SET max_devices=3 WHERE code='pro' —— 已迁移的线上库靠它更新;down 回退 5 - 000002/001 注释同步(free 1 / pro 3 / team 10) - 测试:sqlite_migrate 期望版本 18→19;devices 集成测试 pro 断言 5→3 - free(1)/team(10)不变 注:设备上限当前仍未强制执行(登录注册 MaxDevices=0),仅数据/展示口径; 真正启用+超限 UX 见 todo #16。 Co-Authored-By: Claude Opus 4.8 --- server/internal/devices/devices_integration_test.go | 6 +++--- server/internal/store/sqlite_migrate_test.go | 4 ++-- server/migrations/001_init.sql | 4 ++-- server/migrations/mysql/000002_plans_subscriptions.up.sql | 2 +- server/migrations/mysql/000007_seed.up.sql | 4 ++-- server/migrations/mysql/000019_pro_max_devices_3.down.sql | 2 ++ server/migrations/mysql/000019_pro_max_devices_3.up.sql | 2 ++ server/migrations/sqlite/000007_seed.up.sql | 2 +- server/migrations/sqlite/000019_pro_max_devices_3.down.sql | 2 ++ server/migrations/sqlite/000019_pro_max_devices_3.up.sql | 2 ++ 10 files changed, 19 insertions(+), 11 deletions(-) create mode 100644 server/migrations/mysql/000019_pro_max_devices_3.down.sql create mode 100644 server/migrations/mysql/000019_pro_max_devices_3.up.sql create mode 100644 server/migrations/sqlite/000019_pro_max_devices_3.down.sql create mode 100644 server/migrations/sqlite/000019_pro_max_devices_3.up.sql diff --git a/server/internal/devices/devices_integration_test.go b/server/internal/devices/devices_integration_test.go index 22e18eb..f6c1d3f 100644 --- a/server/internal/devices/devices_integration_test.go +++ b/server/internal/devices/devices_integration_test.go @@ -172,15 +172,15 @@ func TestFullChain(t *testing.T) { ctx := context.Background() userID := createUser(t, db, "chain@example.com", "active") - // 7-day pro trial → effective plan pro (max 5). + // 7-day pro trial → effective plan pro (max 3). giveSubscription(t, db, userID, "pro", "trial", time.Now().UTC().Add(7*24*time.Hour)) plan, apiErr := svc.ResolvePlan(ctx, userID) if apiErr != nil { t.Fatalf("ResolvePlan: %v", apiErr) } - if plan.PlanCode != "pro" || plan.MaxDevices != 5 { - t.Fatalf("want pro/5, got %s/%d", plan.PlanCode, plan.MaxDevices) + if plan.PlanCode != "pro" || plan.MaxDevices != 3 { + t.Fatalf("want pro/3, got %s/%d", plan.PlanCode, plan.MaxDevices) } devUUID := newUUID(t, db) diff --git a/server/internal/store/sqlite_migrate_test.go b/server/internal/store/sqlite_migrate_test.go index 249b307..634647c 100644 --- a/server/internal/store/sqlite_migrate_test.go +++ b/server/internal/store/sqlite_migrate_test.go @@ -29,8 +29,8 @@ func TestSQLiteMigrateUpDown(t *testing.T) { if dirty { t.Fatalf("schema dirty after MigrateUp") } - if v != 18 { - t.Errorf("version = %d, want 18", v) + if v != 19 { + t.Errorf("version = %d, want 19", v) } // 2. Core tables exist. diff --git a/server/migrations/001_init.sql b/server/migrations/001_init.sql index 524060c..fe0949b 100644 --- a/server/migrations/001_init.sql +++ b/server/migrations/001_init.sql @@ -25,14 +25,14 @@ CREATE TABLE IF NOT EXISTS users ( CREATE TABLE IF NOT EXISTS plans ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, code ENUM('free','pro','team') NOT NULL UNIQUE, - max_devices INT NOT NULL, -- free 1 / pro 5 / team 10 + max_devices INT NOT NULL, -- free 1 / pro 3 / team 10 daily_minutes INT NULL, -- free 10; NULL = unlimited ad_gate BOOLEAN NOT NULL DEFAULT FALSE -- free users must watch an ad daily ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT IGNORE INTO plans (code, max_devices, daily_minutes, ad_gate) VALUES ('free', 1, 10, TRUE), - ('pro', 5, NULL, FALSE), + ('pro', 3, NULL, FALSE), ('team', 10, NULL, FALSE); -- ------------------------------------------------------------------------- diff --git a/server/migrations/mysql/000002_plans_subscriptions.up.sql b/server/migrations/mysql/000002_plans_subscriptions.up.sql index f754ff1..0f56bc5 100644 --- a/server/migrations/mysql/000002_plans_subscriptions.up.sql +++ b/server/migrations/mysql/000002_plans_subscriptions.up.sql @@ -2,7 +2,7 @@ CREATE TABLE plans ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, code ENUM('free','pro','team') NOT NULL UNIQUE, - max_devices INT NOT NULL, -- free 1 / pro 5 / team 10 + max_devices INT NOT NULL, -- free 1 / pro 3 / team 10 daily_minutes INT NULL, -- free 10;NULL = 不限 ad_gate BOOLEAN NOT NULL DEFAULT FALSE -- free 每日看广告解锁 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/server/migrations/mysql/000007_seed.up.sql b/server/migrations/mysql/000007_seed.up.sql index 2634b3c..168e89a 100644 --- a/server/migrations/mysql/000007_seed.up.sql +++ b/server/migrations/mysql/000007_seed.up.sql @@ -1,11 +1,11 @@ -- plans seed(口径来源:design/CLAUDE.md §7,价格不入表) -- free: 1 设备,10 分钟/天,每日广告解锁 --- pro: 5 设备,不限时长,无广告门槛 +-- pro: 3 设备,不限时长,无广告门槛 -- team: 10 设备,不限时长,无广告门槛 INSERT INTO plans (code, max_devices, daily_minutes, ad_gate) VALUES ('free', 1, 10, TRUE), - ('pro', 5, NULL, FALSE), + ('pro', 3, NULL, FALSE), ('team', 10, NULL, FALSE) ON DUPLICATE KEY UPDATE max_devices = VALUES(max_devices), diff --git a/server/migrations/mysql/000019_pro_max_devices_3.down.sql b/server/migrations/mysql/000019_pro_max_devices_3.down.sql new file mode 100644 index 0000000..f92e3b9 --- /dev/null +++ b/server/migrations/mysql/000019_pro_max_devices_3.down.sql @@ -0,0 +1,2 @@ +-- 回退:pro 套餐设备上限 3 → 5。 +UPDATE plans SET max_devices = 5 WHERE code = 'pro'; diff --git a/server/migrations/mysql/000019_pro_max_devices_3.up.sql b/server/migrations/mysql/000019_pro_max_devices_3.up.sql new file mode 100644 index 0000000..4632b0e --- /dev/null +++ b/server/migrations/mysql/000019_pro_max_devices_3.up.sql @@ -0,0 +1,2 @@ +-- pro 套餐设备上限 5 → 3(已迁移库更新;新库由 000007_seed 直接 seed 为 3)。 +UPDATE plans SET max_devices = 3 WHERE code = 'pro'; diff --git a/server/migrations/sqlite/000007_seed.up.sql b/server/migrations/sqlite/000007_seed.up.sql index 551ef67..6739e70 100644 --- a/server/migrations/sqlite/000007_seed.up.sql +++ b/server/migrations/sqlite/000007_seed.up.sql @@ -1,7 +1,7 @@ -- plans seed(free/pro/team) INSERT INTO plans (code, max_devices, daily_minutes, ad_gate) VALUES ('free', 1, 10, 1), - ('pro', 5, NULL, 0), + ('pro', 3, NULL, 0), ('team', 10, NULL, 0) ON CONFLICT(code) DO UPDATE SET max_devices = excluded.max_devices, diff --git a/server/migrations/sqlite/000019_pro_max_devices_3.down.sql b/server/migrations/sqlite/000019_pro_max_devices_3.down.sql new file mode 100644 index 0000000..f92e3b9 --- /dev/null +++ b/server/migrations/sqlite/000019_pro_max_devices_3.down.sql @@ -0,0 +1,2 @@ +-- 回退:pro 套餐设备上限 3 → 5。 +UPDATE plans SET max_devices = 5 WHERE code = 'pro'; diff --git a/server/migrations/sqlite/000019_pro_max_devices_3.up.sql b/server/migrations/sqlite/000019_pro_max_devices_3.up.sql new file mode 100644 index 0000000..4632b0e --- /dev/null +++ b/server/migrations/sqlite/000019_pro_max_devices_3.up.sql @@ -0,0 +1,2 @@ +-- pro 套餐设备上限 5 → 3(已迁移库更新;新库由 000007_seed 直接 seed 为 3)。 +UPDATE plans SET max_devices = 3 WHERE code = 'pro';