From b7b0b1880235930598567eb0af969bba5226a9a1 Mon Sep 17 00:00:00 2001 From: jackyu66git Date: Thu, 13 Aug 2026 02:14:52 +0800 Subject: [PATCH] =?UTF-8?q?fix(db):=20=E9=87=8D=E7=BC=96=E5=8F=B7=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=90=8E=E6=92=9E=E5=8F=B7=20migration=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E4=BF=AE=20admin=20e2e=20base?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 015–023 双文件冲突线性化为 015–050;提供已有库 schema_migrations 修复脚本;admin Playwright 对齐 /psy/admin/ 预览路径。 Co-authored-by: Cursor --- apps/admin-h5/e2e/admin-ops-smoke.spec.ts | 3 +- apps/admin-h5/playwright.config.ts | 6 +- ...ac.down.sql => 000018_admin_rbac.down.sql} | 0 ...n_rbac.up.sql => 000018_admin_rbac.up.sql} | 0 ....sql => 000019_account_lifecycle.down.sql} | 0 ...up.sql => 000019_account_lifecycle.up.sql} | 0 ...n.sql => 000020_membership_plans.down.sql} | 0 ....up.sql => 000020_membership_plans.up.sql} | 0 ...n.sql => 000021_redemption_codes.down.sql} | 0 ....up.sql => 000021_redemption_codes.up.sql} | 0 ....down.sql => 000022_ask_ops_read.down.sql} | 0 ...read.up.sql => 000022_ask_ops_read.up.sql} | 0 ... => 000023_content_safety_filter.down.sql} | 0 ...ql => 000023_content_safety_filter.up.sql} | 0 ...l => 000024_ask_quality_feedback.down.sql} | 0 ...sql => 000024_ask_quality_feedback.up.sql} | 0 ....sql => 000025_ai_system_prompts.down.sql} | 0 ...up.sql => 000025_ai_system_prompts.up.sql} | 0 ...wn.sql => 000026_crisis_policies.down.sql} | 0 ...s.up.sql => 000026_crisis_policies.up.sql} | 0 ...r.down.sql => 000027_user_avatar.down.sql} | 0 ...vatar.up.sql => 000027_user_avatar.up.sql} | 0 ...el.down.sql => 000028_mbti_label.down.sql} | 0 ..._label.up.sql => 000028_mbti_label.up.sql} | 0 ...own.sql => 000029_mbti_questions.down.sql} | 0 ...ns.up.sql => 000029_mbti_questions.up.sql} | 0 ...ti.down.sql => 000030_oejts_mbti.down.sql} | 0 ...s_mbti.up.sql => 000030_oejts_mbti.up.sql} | 0 ....down.sql => 000031_mbti_full_60.down.sql} | 0 ...l_60.up.sql => 000031_mbti_full_60.up.sql} | 0 ...wn.sql => 000032_home_daily_tips.down.sql} | 0 ...s.up.sql => 000032_home_daily_tips.up.sql} | 0 ....sql => 000033_knowledge_sources.down.sql} | 0 ...up.sql => 000033_knowledge_sources.up.sql} | 0 ...s.down.sql => 000034_ops_banners.down.sql} | 0 ...nners.up.sql => 000034_ops_banners.up.sql} | 0 ...own.sql => 000035_ops_feed_slots.down.sql} | 0 ...ts.up.sql => 000035_ops_feed_slots.up.sql} | 0 ...00036_ops_scheduled_publications.down.sql} | 0 ... 000036_ops_scheduled_publications.up.sql} | 0 ...n.sql => 000037_knowledge_chunks.down.sql} | 0 ....up.sql => 000037_knowledge_chunks.up.sql} | 0 ...n.sql => 000038_tool_definitions.down.sql} | 0 ....up.sql => 000038_tool_definitions.up.sql} | 0 ...own.sql => 000039_block_policies.down.sql} | 0 ...es.up.sql => 000039_block_policies.up.sql} | 0 ...n.sql => 000040_moderation_cases.down.sql} | 0 ....up.sql => 000040_moderation_cases.up.sql} | 0 ...down.sql => 000041_crisis_events.down.sql} | 0 ...nts.up.sql => 000041_crisis_events.up.sql} | 0 ... => 000042_intervention_outcomes.down.sql} | 0 ...ql => 000042_intervention_outcomes.up.sql} | 0 ....sql => 000043_ask_handoff_cases.down.sql} | 0 ...up.sql => 000043_ask_handoff_cases.up.sql} | 0 ...n.sql => 000044_privacy_requests.down.sql} | 0 ....up.sql => 000044_privacy_requests.up.sql} | 0 ....down.sql => 000045_star_configs.down.sql} | 0 ...figs.up.sql => 000045_star_configs.up.sql} | 0 ...own.sql => 000046_rhythm_configs.down.sql} | 0 ...gs.up.sql => 000046_rhythm_configs.up.sql} | 0 ...n.sql => 000047_image_card_decks.down.sql} | 0 ....up.sql => 000047_image_card_decks.up.sql} | 0 ...n.sql => 000048_report_templates.down.sql} | 0 ....up.sql => 000048_report_templates.up.sql} | 0 ...sql => 000049_funnel_definitions.down.sql} | 0 ...p.sql => 000049_funnel_definitions.up.sql} | 0 ...down.sql => 000050_ops_hardening.down.sql} | 0 ...ing.up.sql => 000050_ops_hardening.up.sql} | 0 docs/CHANGELOG.md | 1 + docs/MIGRATION_RENUMBER.md | 69 +++++++++++++++++++ docs/TRACEABILITY.md | 4 +- scripts/repair-schema-migrations-renumber.sql | 54 +++++++++++++++ 72 files changed, 133 insertions(+), 4 deletions(-) rename apps/api/migrations/{000015_admin_rbac.down.sql => 000018_admin_rbac.down.sql} (100%) rename apps/api/migrations/{000015_admin_rbac.up.sql => 000018_admin_rbac.up.sql} (100%) rename apps/api/migrations/{000016_account_lifecycle.down.sql => 000019_account_lifecycle.down.sql} (100%) rename apps/api/migrations/{000016_account_lifecycle.up.sql => 000019_account_lifecycle.up.sql} (100%) rename apps/api/migrations/{000017_membership_plans.down.sql => 000020_membership_plans.down.sql} (100%) rename apps/api/migrations/{000017_membership_plans.up.sql => 000020_membership_plans.up.sql} (100%) rename apps/api/migrations/{000018_redemption_codes.down.sql => 000021_redemption_codes.down.sql} (100%) rename apps/api/migrations/{000018_redemption_codes.up.sql => 000021_redemption_codes.up.sql} (100%) rename apps/api/migrations/{000019_ask_ops_read.down.sql => 000022_ask_ops_read.down.sql} (100%) rename apps/api/migrations/{000019_ask_ops_read.up.sql => 000022_ask_ops_read.up.sql} (100%) rename apps/api/migrations/{000020_content_safety_filter.down.sql => 000023_content_safety_filter.down.sql} (100%) rename apps/api/migrations/{000020_content_safety_filter.up.sql => 000023_content_safety_filter.up.sql} (100%) rename apps/api/migrations/{000021_ask_quality_feedback.down.sql => 000024_ask_quality_feedback.down.sql} (100%) rename apps/api/migrations/{000021_ask_quality_feedback.up.sql => 000024_ask_quality_feedback.up.sql} (100%) rename apps/api/migrations/{000022_ai_system_prompts.down.sql => 000025_ai_system_prompts.down.sql} (100%) rename apps/api/migrations/{000022_ai_system_prompts.up.sql => 000025_ai_system_prompts.up.sql} (100%) rename apps/api/migrations/{000023_crisis_policies.down.sql => 000026_crisis_policies.down.sql} (100%) rename apps/api/migrations/{000023_crisis_policies.up.sql => 000026_crisis_policies.up.sql} (100%) rename apps/api/migrations/{000018_user_avatar.down.sql => 000027_user_avatar.down.sql} (100%) rename apps/api/migrations/{000018_user_avatar.up.sql => 000027_user_avatar.up.sql} (100%) rename apps/api/migrations/{000019_mbti_label.down.sql => 000028_mbti_label.down.sql} (100%) rename apps/api/migrations/{000019_mbti_label.up.sql => 000028_mbti_label.up.sql} (100%) rename apps/api/migrations/{000020_mbti_questions.down.sql => 000029_mbti_questions.down.sql} (100%) rename apps/api/migrations/{000020_mbti_questions.up.sql => 000029_mbti_questions.up.sql} (100%) rename apps/api/migrations/{000021_oejts_mbti.down.sql => 000030_oejts_mbti.down.sql} (100%) rename apps/api/migrations/{000021_oejts_mbti.up.sql => 000030_oejts_mbti.up.sql} (100%) rename apps/api/migrations/{000022_mbti_full_60.down.sql => 000031_mbti_full_60.down.sql} (100%) rename apps/api/migrations/{000022_mbti_full_60.up.sql => 000031_mbti_full_60.up.sql} (100%) rename apps/api/migrations/{000023_home_daily_tips.down.sql => 000032_home_daily_tips.down.sql} (100%) rename apps/api/migrations/{000023_home_daily_tips.up.sql => 000032_home_daily_tips.up.sql} (100%) rename apps/api/migrations/{000024_knowledge_sources.down.sql => 000033_knowledge_sources.down.sql} (100%) rename apps/api/migrations/{000024_knowledge_sources.up.sql => 000033_knowledge_sources.up.sql} (100%) rename apps/api/migrations/{000025_ops_banners.down.sql => 000034_ops_banners.down.sql} (100%) rename apps/api/migrations/{000025_ops_banners.up.sql => 000034_ops_banners.up.sql} (100%) rename apps/api/migrations/{000026_ops_feed_slots.down.sql => 000035_ops_feed_slots.down.sql} (100%) rename apps/api/migrations/{000026_ops_feed_slots.up.sql => 000035_ops_feed_slots.up.sql} (100%) rename apps/api/migrations/{000027_ops_scheduled_publications.down.sql => 000036_ops_scheduled_publications.down.sql} (100%) rename apps/api/migrations/{000027_ops_scheduled_publications.up.sql => 000036_ops_scheduled_publications.up.sql} (100%) rename apps/api/migrations/{000028_knowledge_chunks.down.sql => 000037_knowledge_chunks.down.sql} (100%) rename apps/api/migrations/{000028_knowledge_chunks.up.sql => 000037_knowledge_chunks.up.sql} (100%) rename apps/api/migrations/{000029_tool_definitions.down.sql => 000038_tool_definitions.down.sql} (100%) rename apps/api/migrations/{000029_tool_definitions.up.sql => 000038_tool_definitions.up.sql} (100%) rename apps/api/migrations/{000030_block_policies.down.sql => 000039_block_policies.down.sql} (100%) rename apps/api/migrations/{000030_block_policies.up.sql => 000039_block_policies.up.sql} (100%) rename apps/api/migrations/{000031_moderation_cases.down.sql => 000040_moderation_cases.down.sql} (100%) rename apps/api/migrations/{000031_moderation_cases.up.sql => 000040_moderation_cases.up.sql} (100%) rename apps/api/migrations/{000032_crisis_events.down.sql => 000041_crisis_events.down.sql} (100%) rename apps/api/migrations/{000032_crisis_events.up.sql => 000041_crisis_events.up.sql} (100%) rename apps/api/migrations/{000033_intervention_outcomes.down.sql => 000042_intervention_outcomes.down.sql} (100%) rename apps/api/migrations/{000033_intervention_outcomes.up.sql => 000042_intervention_outcomes.up.sql} (100%) rename apps/api/migrations/{000034_ask_handoff_cases.down.sql => 000043_ask_handoff_cases.down.sql} (100%) rename apps/api/migrations/{000034_ask_handoff_cases.up.sql => 000043_ask_handoff_cases.up.sql} (100%) rename apps/api/migrations/{000035_privacy_requests.down.sql => 000044_privacy_requests.down.sql} (100%) rename apps/api/migrations/{000035_privacy_requests.up.sql => 000044_privacy_requests.up.sql} (100%) rename apps/api/migrations/{000036_star_configs.down.sql => 000045_star_configs.down.sql} (100%) rename apps/api/migrations/{000036_star_configs.up.sql => 000045_star_configs.up.sql} (100%) rename apps/api/migrations/{000037_rhythm_configs.down.sql => 000046_rhythm_configs.down.sql} (100%) rename apps/api/migrations/{000037_rhythm_configs.up.sql => 000046_rhythm_configs.up.sql} (100%) rename apps/api/migrations/{000038_image_card_decks.down.sql => 000047_image_card_decks.down.sql} (100%) rename apps/api/migrations/{000038_image_card_decks.up.sql => 000047_image_card_decks.up.sql} (100%) rename apps/api/migrations/{000039_report_templates.down.sql => 000048_report_templates.down.sql} (100%) rename apps/api/migrations/{000039_report_templates.up.sql => 000048_report_templates.up.sql} (100%) rename apps/api/migrations/{000040_funnel_definitions.down.sql => 000049_funnel_definitions.down.sql} (100%) rename apps/api/migrations/{000040_funnel_definitions.up.sql => 000049_funnel_definitions.up.sql} (100%) rename apps/api/migrations/{000041_ops_hardening.down.sql => 000050_ops_hardening.down.sql} (100%) rename apps/api/migrations/{000041_ops_hardening.up.sql => 000050_ops_hardening.up.sql} (100%) create mode 100644 docs/MIGRATION_RENUMBER.md create mode 100644 scripts/repair-schema-migrations-renumber.sql diff --git a/apps/admin-h5/e2e/admin-ops-smoke.spec.ts b/apps/admin-h5/e2e/admin-ops-smoke.spec.ts index 55cfc68..a31fa10 100644 --- a/apps/admin-h5/e2e/admin-ops-smoke.spec.ts +++ b/apps/admin-h5/e2e/admin-ops-smoke.spec.ts @@ -161,7 +161,8 @@ test('admin login users grant and audit with mocked API', async ({ page }) => { await ok({}) }) - await page.goto('/login') + // Leading `/login` would resolve to host root and miss Vite base `/psy/admin/`. + await page.goto('login') await expect(page.getByRole('heading', { name: '愈心谷' })).toBeVisible() await page.locator('input[type="password"]').fill('change-me') await page.getByRole('button', { name: '登录' }).click() diff --git a/apps/admin-h5/playwright.config.ts b/apps/admin-h5/playwright.config.ts index b9c2d0d..136806f 100644 --- a/apps/admin-h5/playwright.config.ts +++ b/apps/admin-h5/playwright.config.ts @@ -2,6 +2,7 @@ import { defineConfig, devices } from '@playwright/test' /** * Ops admin L3 smoke: Vite preview + mocked /api/v1/admin (no Go required). + * Build uses base `/psy/admin/` — baseURL must include that prefix. * Run: npm run test:e2e -w @yuxingu/admin-h5 */ export default defineConfig({ @@ -10,7 +11,8 @@ export default defineConfig({ forbidOnly: !!process.env.CI, retries: process.env.CI ? 1 : 0, use: { - baseURL: 'http://127.0.0.1:4174', + // Trailing slash so relative goto('login') resolves under /psy/admin/ + baseURL: 'http://127.0.0.1:4174/psy/admin/', trace: 'on-first-retry', }, projects: [ @@ -24,7 +26,7 @@ export default defineConfig({ ], webServer: { command: 'npm run build && npm run preview -- --host 127.0.0.1 --port 4174', - url: 'http://127.0.0.1:4174', + url: 'http://127.0.0.1:4174/psy/admin/', reuseExistingServer: false, timeout: 120_000, }, diff --git a/apps/api/migrations/000015_admin_rbac.down.sql b/apps/api/migrations/000018_admin_rbac.down.sql similarity index 100% rename from apps/api/migrations/000015_admin_rbac.down.sql rename to apps/api/migrations/000018_admin_rbac.down.sql diff --git a/apps/api/migrations/000015_admin_rbac.up.sql b/apps/api/migrations/000018_admin_rbac.up.sql similarity index 100% rename from apps/api/migrations/000015_admin_rbac.up.sql rename to apps/api/migrations/000018_admin_rbac.up.sql diff --git a/apps/api/migrations/000016_account_lifecycle.down.sql b/apps/api/migrations/000019_account_lifecycle.down.sql similarity index 100% rename from apps/api/migrations/000016_account_lifecycle.down.sql rename to apps/api/migrations/000019_account_lifecycle.down.sql diff --git a/apps/api/migrations/000016_account_lifecycle.up.sql b/apps/api/migrations/000019_account_lifecycle.up.sql similarity index 100% rename from apps/api/migrations/000016_account_lifecycle.up.sql rename to apps/api/migrations/000019_account_lifecycle.up.sql diff --git a/apps/api/migrations/000017_membership_plans.down.sql b/apps/api/migrations/000020_membership_plans.down.sql similarity index 100% rename from apps/api/migrations/000017_membership_plans.down.sql rename to apps/api/migrations/000020_membership_plans.down.sql diff --git a/apps/api/migrations/000017_membership_plans.up.sql b/apps/api/migrations/000020_membership_plans.up.sql similarity index 100% rename from apps/api/migrations/000017_membership_plans.up.sql rename to apps/api/migrations/000020_membership_plans.up.sql diff --git a/apps/api/migrations/000018_redemption_codes.down.sql b/apps/api/migrations/000021_redemption_codes.down.sql similarity index 100% rename from apps/api/migrations/000018_redemption_codes.down.sql rename to apps/api/migrations/000021_redemption_codes.down.sql diff --git a/apps/api/migrations/000018_redemption_codes.up.sql b/apps/api/migrations/000021_redemption_codes.up.sql similarity index 100% rename from apps/api/migrations/000018_redemption_codes.up.sql rename to apps/api/migrations/000021_redemption_codes.up.sql diff --git a/apps/api/migrations/000019_ask_ops_read.down.sql b/apps/api/migrations/000022_ask_ops_read.down.sql similarity index 100% rename from apps/api/migrations/000019_ask_ops_read.down.sql rename to apps/api/migrations/000022_ask_ops_read.down.sql diff --git a/apps/api/migrations/000019_ask_ops_read.up.sql b/apps/api/migrations/000022_ask_ops_read.up.sql similarity index 100% rename from apps/api/migrations/000019_ask_ops_read.up.sql rename to apps/api/migrations/000022_ask_ops_read.up.sql diff --git a/apps/api/migrations/000020_content_safety_filter.down.sql b/apps/api/migrations/000023_content_safety_filter.down.sql similarity index 100% rename from apps/api/migrations/000020_content_safety_filter.down.sql rename to apps/api/migrations/000023_content_safety_filter.down.sql diff --git a/apps/api/migrations/000020_content_safety_filter.up.sql b/apps/api/migrations/000023_content_safety_filter.up.sql similarity index 100% rename from apps/api/migrations/000020_content_safety_filter.up.sql rename to apps/api/migrations/000023_content_safety_filter.up.sql diff --git a/apps/api/migrations/000021_ask_quality_feedback.down.sql b/apps/api/migrations/000024_ask_quality_feedback.down.sql similarity index 100% rename from apps/api/migrations/000021_ask_quality_feedback.down.sql rename to apps/api/migrations/000024_ask_quality_feedback.down.sql diff --git a/apps/api/migrations/000021_ask_quality_feedback.up.sql b/apps/api/migrations/000024_ask_quality_feedback.up.sql similarity index 100% rename from apps/api/migrations/000021_ask_quality_feedback.up.sql rename to apps/api/migrations/000024_ask_quality_feedback.up.sql diff --git a/apps/api/migrations/000022_ai_system_prompts.down.sql b/apps/api/migrations/000025_ai_system_prompts.down.sql similarity index 100% rename from apps/api/migrations/000022_ai_system_prompts.down.sql rename to apps/api/migrations/000025_ai_system_prompts.down.sql diff --git a/apps/api/migrations/000022_ai_system_prompts.up.sql b/apps/api/migrations/000025_ai_system_prompts.up.sql similarity index 100% rename from apps/api/migrations/000022_ai_system_prompts.up.sql rename to apps/api/migrations/000025_ai_system_prompts.up.sql diff --git a/apps/api/migrations/000023_crisis_policies.down.sql b/apps/api/migrations/000026_crisis_policies.down.sql similarity index 100% rename from apps/api/migrations/000023_crisis_policies.down.sql rename to apps/api/migrations/000026_crisis_policies.down.sql diff --git a/apps/api/migrations/000023_crisis_policies.up.sql b/apps/api/migrations/000026_crisis_policies.up.sql similarity index 100% rename from apps/api/migrations/000023_crisis_policies.up.sql rename to apps/api/migrations/000026_crisis_policies.up.sql diff --git a/apps/api/migrations/000018_user_avatar.down.sql b/apps/api/migrations/000027_user_avatar.down.sql similarity index 100% rename from apps/api/migrations/000018_user_avatar.down.sql rename to apps/api/migrations/000027_user_avatar.down.sql diff --git a/apps/api/migrations/000018_user_avatar.up.sql b/apps/api/migrations/000027_user_avatar.up.sql similarity index 100% rename from apps/api/migrations/000018_user_avatar.up.sql rename to apps/api/migrations/000027_user_avatar.up.sql diff --git a/apps/api/migrations/000019_mbti_label.down.sql b/apps/api/migrations/000028_mbti_label.down.sql similarity index 100% rename from apps/api/migrations/000019_mbti_label.down.sql rename to apps/api/migrations/000028_mbti_label.down.sql diff --git a/apps/api/migrations/000019_mbti_label.up.sql b/apps/api/migrations/000028_mbti_label.up.sql similarity index 100% rename from apps/api/migrations/000019_mbti_label.up.sql rename to apps/api/migrations/000028_mbti_label.up.sql diff --git a/apps/api/migrations/000020_mbti_questions.down.sql b/apps/api/migrations/000029_mbti_questions.down.sql similarity index 100% rename from apps/api/migrations/000020_mbti_questions.down.sql rename to apps/api/migrations/000029_mbti_questions.down.sql diff --git a/apps/api/migrations/000020_mbti_questions.up.sql b/apps/api/migrations/000029_mbti_questions.up.sql similarity index 100% rename from apps/api/migrations/000020_mbti_questions.up.sql rename to apps/api/migrations/000029_mbti_questions.up.sql diff --git a/apps/api/migrations/000021_oejts_mbti.down.sql b/apps/api/migrations/000030_oejts_mbti.down.sql similarity index 100% rename from apps/api/migrations/000021_oejts_mbti.down.sql rename to apps/api/migrations/000030_oejts_mbti.down.sql diff --git a/apps/api/migrations/000021_oejts_mbti.up.sql b/apps/api/migrations/000030_oejts_mbti.up.sql similarity index 100% rename from apps/api/migrations/000021_oejts_mbti.up.sql rename to apps/api/migrations/000030_oejts_mbti.up.sql diff --git a/apps/api/migrations/000022_mbti_full_60.down.sql b/apps/api/migrations/000031_mbti_full_60.down.sql similarity index 100% rename from apps/api/migrations/000022_mbti_full_60.down.sql rename to apps/api/migrations/000031_mbti_full_60.down.sql diff --git a/apps/api/migrations/000022_mbti_full_60.up.sql b/apps/api/migrations/000031_mbti_full_60.up.sql similarity index 100% rename from apps/api/migrations/000022_mbti_full_60.up.sql rename to apps/api/migrations/000031_mbti_full_60.up.sql diff --git a/apps/api/migrations/000023_home_daily_tips.down.sql b/apps/api/migrations/000032_home_daily_tips.down.sql similarity index 100% rename from apps/api/migrations/000023_home_daily_tips.down.sql rename to apps/api/migrations/000032_home_daily_tips.down.sql diff --git a/apps/api/migrations/000023_home_daily_tips.up.sql b/apps/api/migrations/000032_home_daily_tips.up.sql similarity index 100% rename from apps/api/migrations/000023_home_daily_tips.up.sql rename to apps/api/migrations/000032_home_daily_tips.up.sql diff --git a/apps/api/migrations/000024_knowledge_sources.down.sql b/apps/api/migrations/000033_knowledge_sources.down.sql similarity index 100% rename from apps/api/migrations/000024_knowledge_sources.down.sql rename to apps/api/migrations/000033_knowledge_sources.down.sql diff --git a/apps/api/migrations/000024_knowledge_sources.up.sql b/apps/api/migrations/000033_knowledge_sources.up.sql similarity index 100% rename from apps/api/migrations/000024_knowledge_sources.up.sql rename to apps/api/migrations/000033_knowledge_sources.up.sql diff --git a/apps/api/migrations/000025_ops_banners.down.sql b/apps/api/migrations/000034_ops_banners.down.sql similarity index 100% rename from apps/api/migrations/000025_ops_banners.down.sql rename to apps/api/migrations/000034_ops_banners.down.sql diff --git a/apps/api/migrations/000025_ops_banners.up.sql b/apps/api/migrations/000034_ops_banners.up.sql similarity index 100% rename from apps/api/migrations/000025_ops_banners.up.sql rename to apps/api/migrations/000034_ops_banners.up.sql diff --git a/apps/api/migrations/000026_ops_feed_slots.down.sql b/apps/api/migrations/000035_ops_feed_slots.down.sql similarity index 100% rename from apps/api/migrations/000026_ops_feed_slots.down.sql rename to apps/api/migrations/000035_ops_feed_slots.down.sql diff --git a/apps/api/migrations/000026_ops_feed_slots.up.sql b/apps/api/migrations/000035_ops_feed_slots.up.sql similarity index 100% rename from apps/api/migrations/000026_ops_feed_slots.up.sql rename to apps/api/migrations/000035_ops_feed_slots.up.sql diff --git a/apps/api/migrations/000027_ops_scheduled_publications.down.sql b/apps/api/migrations/000036_ops_scheduled_publications.down.sql similarity index 100% rename from apps/api/migrations/000027_ops_scheduled_publications.down.sql rename to apps/api/migrations/000036_ops_scheduled_publications.down.sql diff --git a/apps/api/migrations/000027_ops_scheduled_publications.up.sql b/apps/api/migrations/000036_ops_scheduled_publications.up.sql similarity index 100% rename from apps/api/migrations/000027_ops_scheduled_publications.up.sql rename to apps/api/migrations/000036_ops_scheduled_publications.up.sql diff --git a/apps/api/migrations/000028_knowledge_chunks.down.sql b/apps/api/migrations/000037_knowledge_chunks.down.sql similarity index 100% rename from apps/api/migrations/000028_knowledge_chunks.down.sql rename to apps/api/migrations/000037_knowledge_chunks.down.sql diff --git a/apps/api/migrations/000028_knowledge_chunks.up.sql b/apps/api/migrations/000037_knowledge_chunks.up.sql similarity index 100% rename from apps/api/migrations/000028_knowledge_chunks.up.sql rename to apps/api/migrations/000037_knowledge_chunks.up.sql diff --git a/apps/api/migrations/000029_tool_definitions.down.sql b/apps/api/migrations/000038_tool_definitions.down.sql similarity index 100% rename from apps/api/migrations/000029_tool_definitions.down.sql rename to apps/api/migrations/000038_tool_definitions.down.sql diff --git a/apps/api/migrations/000029_tool_definitions.up.sql b/apps/api/migrations/000038_tool_definitions.up.sql similarity index 100% rename from apps/api/migrations/000029_tool_definitions.up.sql rename to apps/api/migrations/000038_tool_definitions.up.sql diff --git a/apps/api/migrations/000030_block_policies.down.sql b/apps/api/migrations/000039_block_policies.down.sql similarity index 100% rename from apps/api/migrations/000030_block_policies.down.sql rename to apps/api/migrations/000039_block_policies.down.sql diff --git a/apps/api/migrations/000030_block_policies.up.sql b/apps/api/migrations/000039_block_policies.up.sql similarity index 100% rename from apps/api/migrations/000030_block_policies.up.sql rename to apps/api/migrations/000039_block_policies.up.sql diff --git a/apps/api/migrations/000031_moderation_cases.down.sql b/apps/api/migrations/000040_moderation_cases.down.sql similarity index 100% rename from apps/api/migrations/000031_moderation_cases.down.sql rename to apps/api/migrations/000040_moderation_cases.down.sql diff --git a/apps/api/migrations/000031_moderation_cases.up.sql b/apps/api/migrations/000040_moderation_cases.up.sql similarity index 100% rename from apps/api/migrations/000031_moderation_cases.up.sql rename to apps/api/migrations/000040_moderation_cases.up.sql diff --git a/apps/api/migrations/000032_crisis_events.down.sql b/apps/api/migrations/000041_crisis_events.down.sql similarity index 100% rename from apps/api/migrations/000032_crisis_events.down.sql rename to apps/api/migrations/000041_crisis_events.down.sql diff --git a/apps/api/migrations/000032_crisis_events.up.sql b/apps/api/migrations/000041_crisis_events.up.sql similarity index 100% rename from apps/api/migrations/000032_crisis_events.up.sql rename to apps/api/migrations/000041_crisis_events.up.sql diff --git a/apps/api/migrations/000033_intervention_outcomes.down.sql b/apps/api/migrations/000042_intervention_outcomes.down.sql similarity index 100% rename from apps/api/migrations/000033_intervention_outcomes.down.sql rename to apps/api/migrations/000042_intervention_outcomes.down.sql diff --git a/apps/api/migrations/000033_intervention_outcomes.up.sql b/apps/api/migrations/000042_intervention_outcomes.up.sql similarity index 100% rename from apps/api/migrations/000033_intervention_outcomes.up.sql rename to apps/api/migrations/000042_intervention_outcomes.up.sql diff --git a/apps/api/migrations/000034_ask_handoff_cases.down.sql b/apps/api/migrations/000043_ask_handoff_cases.down.sql similarity index 100% rename from apps/api/migrations/000034_ask_handoff_cases.down.sql rename to apps/api/migrations/000043_ask_handoff_cases.down.sql diff --git a/apps/api/migrations/000034_ask_handoff_cases.up.sql b/apps/api/migrations/000043_ask_handoff_cases.up.sql similarity index 100% rename from apps/api/migrations/000034_ask_handoff_cases.up.sql rename to apps/api/migrations/000043_ask_handoff_cases.up.sql diff --git a/apps/api/migrations/000035_privacy_requests.down.sql b/apps/api/migrations/000044_privacy_requests.down.sql similarity index 100% rename from apps/api/migrations/000035_privacy_requests.down.sql rename to apps/api/migrations/000044_privacy_requests.down.sql diff --git a/apps/api/migrations/000035_privacy_requests.up.sql b/apps/api/migrations/000044_privacy_requests.up.sql similarity index 100% rename from apps/api/migrations/000035_privacy_requests.up.sql rename to apps/api/migrations/000044_privacy_requests.up.sql diff --git a/apps/api/migrations/000036_star_configs.down.sql b/apps/api/migrations/000045_star_configs.down.sql similarity index 100% rename from apps/api/migrations/000036_star_configs.down.sql rename to apps/api/migrations/000045_star_configs.down.sql diff --git a/apps/api/migrations/000036_star_configs.up.sql b/apps/api/migrations/000045_star_configs.up.sql similarity index 100% rename from apps/api/migrations/000036_star_configs.up.sql rename to apps/api/migrations/000045_star_configs.up.sql diff --git a/apps/api/migrations/000037_rhythm_configs.down.sql b/apps/api/migrations/000046_rhythm_configs.down.sql similarity index 100% rename from apps/api/migrations/000037_rhythm_configs.down.sql rename to apps/api/migrations/000046_rhythm_configs.down.sql diff --git a/apps/api/migrations/000037_rhythm_configs.up.sql b/apps/api/migrations/000046_rhythm_configs.up.sql similarity index 100% rename from apps/api/migrations/000037_rhythm_configs.up.sql rename to apps/api/migrations/000046_rhythm_configs.up.sql diff --git a/apps/api/migrations/000038_image_card_decks.down.sql b/apps/api/migrations/000047_image_card_decks.down.sql similarity index 100% rename from apps/api/migrations/000038_image_card_decks.down.sql rename to apps/api/migrations/000047_image_card_decks.down.sql diff --git a/apps/api/migrations/000038_image_card_decks.up.sql b/apps/api/migrations/000047_image_card_decks.up.sql similarity index 100% rename from apps/api/migrations/000038_image_card_decks.up.sql rename to apps/api/migrations/000047_image_card_decks.up.sql diff --git a/apps/api/migrations/000039_report_templates.down.sql b/apps/api/migrations/000048_report_templates.down.sql similarity index 100% rename from apps/api/migrations/000039_report_templates.down.sql rename to apps/api/migrations/000048_report_templates.down.sql diff --git a/apps/api/migrations/000039_report_templates.up.sql b/apps/api/migrations/000048_report_templates.up.sql similarity index 100% rename from apps/api/migrations/000039_report_templates.up.sql rename to apps/api/migrations/000048_report_templates.up.sql diff --git a/apps/api/migrations/000040_funnel_definitions.down.sql b/apps/api/migrations/000049_funnel_definitions.down.sql similarity index 100% rename from apps/api/migrations/000040_funnel_definitions.down.sql rename to apps/api/migrations/000049_funnel_definitions.down.sql diff --git a/apps/api/migrations/000040_funnel_definitions.up.sql b/apps/api/migrations/000049_funnel_definitions.up.sql similarity index 100% rename from apps/api/migrations/000040_funnel_definitions.up.sql rename to apps/api/migrations/000049_funnel_definitions.up.sql diff --git a/apps/api/migrations/000041_ops_hardening.down.sql b/apps/api/migrations/000050_ops_hardening.down.sql similarity index 100% rename from apps/api/migrations/000041_ops_hardening.down.sql rename to apps/api/migrations/000050_ops_hardening.down.sql diff --git a/apps/api/migrations/000041_ops_hardening.up.sql b/apps/api/migrations/000050_ops_hardening.up.sql similarity index 100% rename from apps/api/migrations/000041_ops_hardening.up.sql rename to apps/api/migrations/000050_ops_hardening.up.sql diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index afed7cb..63f58f1 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,7 @@ ## 2026-08-13 +- **Migration 撞号修复:** `000015`–`000023` 双文件冲突已重编号为唯一序列至 `000050`;说明见 `docs/MIGRATION_RENUMBER.md` - **Merge:** `merge/ops-local-into-main` — 合并本地 Ops 目录扩展(ECR-013A…040)与远程 main(ECR-009…016) 注意:分叉期间 ECR-012/014/015/016 编号在两边含义不同,以 TRACEABILITY 双列说明为准 - **Git host:** 远程改为 `https://git.jackyu66.com/jack/digital-psychology.git`;删除 `.github/workflows`(不再使用 GitHub Actions) diff --git a/docs/MIGRATION_RENUMBER.md b/docs/MIGRATION_RENUMBER.md new file mode 100644 index 0000000..44939ed --- /dev/null +++ b/docs/MIGRATION_RENUMBER.md @@ -0,0 +1,69 @@ +# Migration renumber — merge collision fix (2026-08-13) + +## Problem + +`main`(产品 ECR-009…016)与 Ops 线(ECR-013A…040)合并后,`000015`–`000023` **各有两套** migration。 +本仓 `internal/db.Migrate` 以**完整文件名**为 version,两边都可能被执行,但同号双文件易误导运维,也不兼容 golang-migrate。重编号消除歧义并固定依赖顺序。 + +## Canonical sequence (after fix) + +| Ver | Name | Origin | +|-----|------|--------| +| 015 | ops_commerce | main Ops-D | +| 016 | ops_system | main Ops-E | +| 017 | unique_self_profile | main ECR-011 | +| 018 | admin_rbac | Ops ECR-013A | +| 019 | account_lifecycle | Ops ECR-013B | +| 020 | membership_plans | Ops | +| 021 | redemption_codes | Ops | +| 022 | ask_ops_read | Ops | +| 023 | content_safety_filter | Ops | +| 024 | ask_quality_feedback | Ops | +| 025 | ai_system_prompts | Ops | +| 026 | crisis_policies | Ops | +| 027 | user_avatar | main ECR-015 | +| 028 | mbti_label | main | +| 029 | mbti_questions | main | +| 030 | oejts_mbti | main | +| 031 | mbti_full_60 | main | +| 032 | home_daily_tips | main ECR-014 | +| 033–050 | knowledge…ops_hardening | Ops ECR-023…040 + hardening | + +`000001`–`000014` 未改。 + +## Fresh database + +```bash +# API 使用 internal/db.Migrate(version = 完整 stem,如 000018_admin_rbac) +cd apps/api && go run ./cmd/server # 或集成测试 setup 会 Migrate +``` + +空库应写入 **50** 条 `schema_migrations`(已在 `yuxingu_mig_check` 验证)。 + +## Already-applied databases(必做) + +本仓 version 键是 **完整文件名**(非纯数字)。重编号后若不改 `schema_migrations`,会把已执行过的 SQL **再跑一遍**。 + +对已有库先执行修复脚本: + +```bash +psql "$DATABASE_URL" -f scripts/repair-schema-migrations-renumber.sql +``` + +然后再启动 API / `Migrate`。 + +### A. 可丢弃的开发库 + +重建库后 Migrate。 + +### B. 需保留数据 + +1. 跑 `scripts/repair-schema-migrations-renumber.sql` +2. 再 Migrate(只会补尚未有的 stem) +3. 若曾手改脏数据,对照 `SELECT version FROM schema_migrations ORDER BY version` 与本表核对 + +分叉两边「同号不同义」时,必须以**实际 DDL**为准。 + +## Doc debt + +ESS / Spec 里仍可能写旧号(如「migration 000015 = RBAC」)。以本文件与 `apps/api/migrations/` 文件名为准;后续 ECR 文档可逐步改引用。 diff --git a/docs/TRACEABILITY.md b/docs/TRACEABILITY.md index c7d6cdd..1f2735b 100644 --- a/docs/TRACEABILITY.md +++ b/docs/TRACEABILITY.md @@ -21,7 +21,7 @@ | ECR-012-star | **(local)** 星座对齐收口(星盘 · outlook · 合盘) | **Implemented** | Spec star-profile · 分叉编号冲突,见 CHANGELOG merge 注 | | ECR-013 | **(main)** 探索 curated 题库 A 集 · 结果回看 | **Closed** | Spec explore-test · BD-2026-013 | | WAVE-0 | Ops Contract-First Foundation | **FROZEN** | `docs/WAVE0/` · HUMAN_REVIEW FREEZE | -| ECR-013A | Admin RBAC | **Closed** | Spec ops-rbac · BD-2026-013A · migration 000015 | +| ECR-013A | Admin RBAC | **Closed** | Spec ops-rbac · BD-2026-013A · migration **000018**(原撞号 015,见 MIGRATION_RENUMBER) | | ECR-013B | AccountLifecycle | **Closed** | Spec ops-account-lifecycle · BD-2026-013B | | ECR-014 | **(main)** 时效刷新(时辰贴士 · star/rhythm 按日) | **Closed** | RETRO · BD-2026-014 | | ECR-014-plan | **(local)** MembershipPlan | **Closed** | Spec ops-membership-plan · 分叉编号冲突 | @@ -53,3 +53,5 @@ | ECR-038 | GrowthInsights · ReportTemplate | **Closed** | Spec ops-report-template.md · BD-2026-038 | | ECR-039 | GrowthInsights · FunnelDefinition | **Closed** | Spec ops-funnel-definition.md · BD-2026-039 | | ECR-040 | ExploreConfig · ScaleDefinition | **Closed** | Spec ops-scale-definition.md · BD-2026-040 | + +> **Migration:** 合并后 `000015`–`000023` 曾撞号,已重编号至 `000050`。以 `apps/api/migrations/` 与 `docs/MIGRATION_RENUMBER.md` 为准(文档中旧号引用可能滞后)。 diff --git a/scripts/repair-schema-migrations-renumber.sql b/scripts/repair-schema-migrations-renumber.sql new file mode 100644 index 0000000..95166d7 --- /dev/null +++ b/scripts/repair-schema-migrations-renumber.sql @@ -0,0 +1,54 @@ +-- Repair schema_migrations after 2026-08-13 renumber (filename stems). +-- Safe to re-run. If new stem already exists, drops the obsolete old stem. +-- See docs/MIGRATION_RENUMBER.md + +BEGIN; + +CREATE TEMP TABLE _mig_rename(old_v text PRIMARY KEY, new_v text NOT NULL) ON COMMIT DROP; +INSERT INTO _mig_rename(old_v, new_v) VALUES + ('000015_admin_rbac', '000018_admin_rbac'), + ('000016_account_lifecycle', '000019_account_lifecycle'), + ('000017_membership_plans', '000020_membership_plans'), + ('000018_redemption_codes', '000021_redemption_codes'), + ('000019_ask_ops_read', '000022_ask_ops_read'), + ('000020_content_safety_filter', '000023_content_safety_filter'), + ('000021_ask_quality_feedback', '000024_ask_quality_feedback'), + ('000022_ai_system_prompts', '000025_ai_system_prompts'), + ('000023_crisis_policies', '000026_crisis_policies'), + ('000018_user_avatar', '000027_user_avatar'), + ('000019_mbti_label', '000028_mbti_label'), + ('000020_mbti_questions', '000029_mbti_questions'), + ('000021_oejts_mbti', '000030_oejts_mbti'), + ('000022_mbti_full_60', '000031_mbti_full_60'), + ('000023_home_daily_tips', '000032_home_daily_tips'), + ('000024_knowledge_sources', '000033_knowledge_sources'), + ('000025_ops_banners', '000034_ops_banners'), + ('000026_ops_feed_slots', '000035_ops_feed_slots'), + ('000027_ops_scheduled_publications', '000036_ops_scheduled_publications'), + ('000028_knowledge_chunks', '000037_knowledge_chunks'), + ('000029_tool_definitions', '000038_tool_definitions'), + ('000030_block_policies', '000039_block_policies'), + ('000031_moderation_cases', '000040_moderation_cases'), + ('000032_crisis_events', '000041_crisis_events'), + ('000033_intervention_outcomes', '000042_intervention_outcomes'), + ('000034_ask_handoff_cases', '000043_ask_handoff_cases'), + ('000035_privacy_requests', '000044_privacy_requests'), + ('000036_star_configs', '000045_star_configs'), + ('000037_rhythm_configs', '000046_rhythm_configs'), + ('000038_image_card_decks', '000047_image_card_decks'), + ('000039_report_templates', '000048_report_templates'), + ('000040_funnel_definitions', '000049_funnel_definitions'), + ('000041_ops_hardening', '000050_ops_hardening'); + +-- Prefer keeping new_v if both exist; otherwise rename old -> new. +DELETE FROM schema_migrations sm +USING _mig_rename r +WHERE sm.version = r.old_v + AND EXISTS (SELECT 1 FROM schema_migrations x WHERE x.version = r.new_v); + +UPDATE schema_migrations sm +SET version = r.new_v +FROM _mig_rename r +WHERE sm.version = r.old_v; + +COMMIT;