From 4ff41c1ce6a06a3c02bdbfad445ad33ef70cc25f Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Mon, 20 Apr 2026 20:32:36 +0800 Subject: [PATCH] docs(task4): harden rollback runbook for sqlite migration Refine the Task4 rollback plan with executable SQL, explicit schema restoration targets, and post-rollback validation checks so rollback readiness is auditable before Task5. Made-with: Cursor --- .../2026-04-20-comment-email-config-design.md | 61 +++++++++++++++++++--- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/docs/superpowers/specs/2026-04-20-comment-email-config-design.md b/docs/superpowers/specs/2026-04-20-comment-email-config-design.md index 4fcdd02..1e640fb 100644 --- a/docs/superpowers/specs/2026-04-20-comment-email-config-design.md +++ b/docs/superpowers/specs/2026-04-20-comment-email-config-design.md @@ -237,14 +237,59 @@ - 仅在维护窗口执行,暂停写入评论相关流量,避免迁移过程中出现并发写导致数据不一致。 - 执行前完成数据库备份(至少一份可恢复快照),并验证备份可用性后再开始回滚。 -### 10.3 回滚步骤(可执行) - -1. 创建临时表(例如 `post_comments_rollback`),字段集合与回滚前结构一致,**不包含** `guest_email`、`guest_is_anonymous`。 -2. 将原 `post_comments` 的保留字段按列名显式写入临时表(禁止 `SELECT *`,避免列位错配)。 -3. 删除或重命名原 `post_comments` 表。 -4. 将临时表重命名为 `post_comments`,完成结构替换。 -5. 按回滚前定义重建 `post_comments` 相关索引、唯一约束与外键约束(如有)。 -6. 执行完整性校验(记录条数、关键查询、外键检查)并恢复流量。 +### 10.3 回滚步骤(可执行,针对 migration `0009_curly_jack_murdock.sql`) + +> 说明:以下步骤用于撤销 Task4 新增列 `guest_email`、`guest_is_anonymous`,并恢复到 `0002_post-comments.sql` 对应的 `post_comments` 结构。 + +```sql +PRAGMA foreign_keys = OFF; +BEGIN TRANSACTION; + +CREATE TABLE `post_comments_rollback` ( + `id` integer PRIMARY KEY NOT NULL, + `post_id` integer NOT NULL, + `parent_id` integer, + `author_user_id` integer, + `guest_display_name` text, + `body` text NOT NULL, + `kind` text NOT NULL, + `deleted_at` integer, + `deleted_by_user_id` integer, + `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5) * 86400000 as integer)) NOT NULL, + `updated_at` integer DEFAULT (cast((julianday('now') - 2440587.5) * 86400000 as integer)) NOT NULL, + FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`parent_id`) REFERENCES `post_comments_rollback` (`id`) ON UPDATE no action ON DELETE no action, + FOREIGN KEY (`author_user_id`) REFERENCES `users` (`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`deleted_by_user_id`) REFERENCES `users` (`id`) ON UPDATE no action ON DELETE set null +); + +INSERT INTO `post_comments_rollback` ( + `id`, `post_id`, `parent_id`, `author_user_id`, `guest_display_name`, + `body`, `kind`, `deleted_at`, `deleted_by_user_id`, `created_at`, `updated_at` +) +SELECT + `id`, `post_id`, `parent_id`, `author_user_id`, `guest_display_name`, + `body`, `kind`, `deleted_at`, `deleted_by_user_id`, `created_at`, `updated_at` +FROM `post_comments`; + +DROP TABLE `post_comments`; +ALTER TABLE `post_comments_rollback` RENAME TO `post_comments`; + +CREATE INDEX `post_comments_post_id_idx` ON `post_comments` (`post_id`); +CREATE INDEX `post_comments_parent_id_idx` ON `post_comments` (`parent_id`); + +COMMIT; +PRAGMA foreign_keys = ON; +``` + +执行后校验(至少包含以下检查): + +1. 行数一致:`SELECT COUNT(*) FROM post_comments;` 与回滚前快照对比。 +2. 结构一致:`PRAGMA table_info('post_comments');` 中不应包含 `guest_email`、`guest_is_anonymous`。 +3. 外键一致:`PRAGMA foreign_key_check;` 返回空集。 +4. 关键查询回归:按 `post_id`、`parent_id` 的评论查询可正常命中索引并返回结果。 + +若任一步骤失败,停止后续操作并使用回滚前备份恢复,不做“半回滚”上线。 ### 10.4 风险与注意事项