소스 검색

docs: add prisma v1 baseline plan

ChenYu 3 달 전
부모
커밋
a11dd6049e
1개의 변경된 파일과 234개의 추가작업 그리고 0개의 파일을 삭제
  1. 234 0
      docs/superpowers/plans/2026-06-28-prisma-v1-baseline.md

+ 234 - 0
docs/superpowers/plans/2026-06-28-prisma-v1-baseline.md

@@ -0,0 +1,234 @@
+# Prisma V1 Baseline Migration Implementation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** 将当前稳定版数据库结构收敛为单一的 `v1 baseline migration`,删除旧增量 migration,并让 Prisma 后续从该基线继续演进。
+
+**Architecture:** 保持 `backend/prisma/schema.prisma` 不变,把 `backend/prisma/migrations` 重置为仅包含一条 `20260628_init_v1/migration.sql` 的完整建表基线;现有数据库不重建、不重新执行 baseline SQL,而是通过 Prisma 的已应用状态对齐这条基线。实现过程中同步校验 baseline SQL 与 `schema.prisma`、`数据库设计.md` 一致,并移除旧 migration 目录。
+
+**Tech Stack:** Prisma, MySQL, SQL, Node.js
+
+## Global Constraints
+
+- `schema.prisma` 继续作为当前稳定数据库结构的唯一事实来源。
+- `backend/prisma/migrations` 目录只保留一条 `v1 baseline migration`。
+- baseline SQL 必须包含当前稳定结构的完整建表、索引与注释。
+- 旧 migration 全部移除,不保留历史增量。
+- 不修改当前稳定数据库结构语义,只做基线重置。
+- 现有数据库不重新执行 baseline SQL,采用 Prisma 已应用状态对齐。
+- 后续数据库改动必须在 `v1 baseline` 之上继续新增 migration。
+
+---
+
+### Task 1: 生成并校验 V1 Baseline SQL
+
+**Files:**
+- Create: `backend/prisma/migrations/20260628_init_v1/migration.sql`
+- Read: `backend/prisma/schema.prisma`
+- Read: `backend/docs/数据库设计.md`
+
+**Interfaces:**
+- Consumes: `backend/prisma/schema.prisma`
+- Consumes: `backend/docs/数据库设计.md`
+- Produces: `backend/prisma/migrations/20260628_init_v1/migration.sql`
+
+- [ ] **Step 1: 基于当前 schema 与数据库设计文档列出 baseline 必须覆盖的表**
+
+```text
+hairstylist_user
+customer
+customer_treatment_record
+ai_hair_simulation
+ai_hair_simulation_task
+hair_template
+hair_template_make_task
+system_config
+```
+
+- [ ] **Step 2: 先写 baseline SQL 文件,包含完整建表与索引定义**
+
+```sql
+CREATE TABLE `hairstylist_user` (
+  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '发型师主键ID',
+  `username` VARCHAR(50) NOT NULL COMMENT '发型师用户名',
+  `email` VARCHAR(100) NOT NULL COMMENT '登录邮箱',
+  `password` VARCHAR(100) NOT NULL COMMENT '加密后的登录密码',
+  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `is_deleted` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '逻辑删除:0未删除,1已删除',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='发型师用户信息表';
+
+CREATE TABLE `hair_template` (
+  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '模板主键ID',
+  `template_name` VARCHAR(100) NOT NULL COMMENT '模板名称(必填)',
+  `cover_url` VARCHAR(500) DEFAULT '' COMMENT '模板封面图URL',
+  `status` ENUM('DRAFT','PUBLIC') NOT NULL DEFAULT 'DRAFT' COMMENT '模板状态:DRAFT草稿 / PUBLIC公开',
+  `category` ENUM('LONG','MEDIUM','SHORT','DYE') NOT NULL DEFAULT 'LONG' COMMENT '分类:长发/中长发/短发/染发',
+  `tags` VARCHAR(500) DEFAULT '' COMMENT '模板标签,逗号分隔存储',
+  `description` TEXT NULL COMMENT '模板详细说明',
+  `model_url` VARCHAR(500) DEFAULT '' COMMENT 'AI模特图片URL',
+  `clothes_url` VARCHAR(500) DEFAULT '' COMMENT '服装素材URL',
+  `background_url` VARCHAR(500) DEFAULT '' COMMENT '背景图片URL',
+  `ref_hair_url` VARCHAR(500) DEFAULT '' COMMENT '参考发型图片URL',
+  `hairstylist_id` BIGINT UNSIGNED NULL COMMENT '创建发型师ID,系统模板为空',
+  `template_url` VARCHAR(500) DEFAULT '' COMMENT '完整模板预览页面URL',
+  `used_count` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '模板累计使用次数',
+  `is_system_template` ENUM('YES','NO') NOT NULL DEFAULT 'NO' COMMENT '是否系统模板:YES系统模板,NO门店自定义模板',
+  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `is_deleted` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '逻辑删除:0正常 1删除',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='AI发型模板表';
+```
+
+- [ ] **Step 3: 补齐剩余 6 张表、索引和全部注释**
+
+```sql
+CREATE INDEX `idx_category` ON `hair_template` (`category`, `is_deleted`);
+CREATE INDEX `idx_hairstylist_id` ON `hair_template` (`hairstylist_id`, `is_deleted`);
+CREATE INDEX `idx_status` ON `hair_template` (`status`, `is_deleted`);
+```
+
+- [ ] **Step 4: 自查 baseline SQL 是否包含 `used_count`、索引和注释**
+
+Run: `grep -n "used_count\\|COMMENT\\|CREATE INDEX" backend/prisma/migrations/20260628_init_v1/migration.sql | head -n 20`
+
+Expected: 输出包含 `used_count`、`COMMENT`、`CREATE INDEX`
+
+- [ ] **Step 5: 提交 baseline SQL 初稿**
+
+```bash
+git add backend/prisma/migrations/20260628_init_v1/migration.sql
+git commit -m "feat: add prisma v1 baseline migration"
+```
+
+### Task 2: 清理旧 migration 并校验目录基线
+
+**Files:**
+- Delete: `backend/prisma/migrations/20260628050000_add_customer_follow_content/migration.sql`
+- Delete: `backend/prisma/migrations/20260628120000_add_customer_table/migration.sql`
+- Delete: `backend/prisma/migrations/20260628173000_add_template_used_count/migration.sql`
+- Modify: `backend/prisma/migrations/`
+
+**Interfaces:**
+- Consumes: `backend/prisma/migrations/20260628_init_v1/migration.sql`
+- Produces: `backend/prisma/migrations/` 目录中仅保留 `20260628_init_v1`
+
+- [ ] **Step 1: 删除旧 migration 目录**
+
+```text
+backend/prisma/migrations/20260628050000_add_customer_follow_content
+backend/prisma/migrations/20260628120000_add_customer_table
+backend/prisma/migrations/20260628173000_add_template_used_count
+```
+
+- [ ] **Step 2: 列出 migration 目录,确认只剩 baseline**
+
+Run: `find backend/prisma/migrations -maxdepth 2 -type f | sort`
+
+Expected:
+
+```text
+backend/prisma/migrations/20260628_init_v1/migration.sql
+```
+
+- [ ] **Step 3: 再次校验 baseline 文件存在且旧目录已移除**
+
+Run: `git status --short backend/prisma/migrations`
+
+Expected: 只出现新 baseline 与旧目录删除记录
+
+- [ ] **Step 4: 提交 migration 目录重置**
+
+```bash
+git add backend/prisma/migrations
+git commit -m "chore: reset prisma migrations to v1 baseline"
+```
+
+### Task 3: 对齐现有数据库与 Prisma migration 状态
+
+**Files:**
+- Modify: `backend/prisma/migration_lock.toml` (if generated by Prisma tooling)
+- Read: current database state via Prisma CLI
+
+**Interfaces:**
+- Consumes: `backend/prisma/migrations/20260628_init_v1/migration.sql`
+- Produces: Prisma recognizes `20260628_init_v1` as applied for the current database
+
+- [ ] **Step 1: 先确认当前数据库不需要重新执行 baseline SQL**
+
+Run: `npx prisma db pull --print`
+
+Expected: 输出的结构与 `backend/prisma/schema.prisma` 主要一致,不出现缺失 `used_count` 等明显差异
+
+- [ ] **Step 2: 将 baseline migration 标记为已应用**
+
+Run: `npx prisma migrate resolve --applied 20260628_init_v1`
+
+Expected: 输出包含 `marked as applied` 或等价成功提示
+
+- [ ] **Step 3: 查看 Prisma migration 状态**
+
+Run: `npx prisma migrate status`
+
+Expected: 输出包含 `20260628_init_v1`,且当前数据库没有 pending migration
+
+- [ ] **Step 4: 如果 Prisma 生成了额外锁文件或状态文件,确认其已纳入版本控制策略**
+
+```text
+backend/prisma/migration_lock.toml
+```
+
+- [ ] **Step 5: 提交 migration 状态对齐改动**
+
+```bash
+git add backend/prisma
+git commit -m "chore: align prisma baseline migration state"
+```
+
+### Task 4: 最终一致性校验与文档收口
+
+**Files:**
+- Read: `backend/prisma/schema.prisma`
+- Read: `backend/prisma/migrations/20260628_init_v1/migration.sql`
+- Read: `backend/docs/数据库设计.md`
+
+**Interfaces:**
+- Consumes: `schema.prisma`, `数据库设计.md`, `20260628_init_v1/migration.sql`
+- Produces: verified v1 baseline layout ready for future migrations
+
+- [ ] **Step 1: 对照 `schema.prisma` 与 baseline SQL 逐项检查核心表和字段**
+
+```text
+重点校验:
+- customer.follow_content
+- ai_hair_simulation.template_ids
+- hair_template.used_count
+- system_config.value_type
+```
+
+- [ ] **Step 2: 运行 Prisma 客户端生成,确认 schema 与 migration 目录在当前仓库状态下可工作**
+
+Run: `npx prisma generate`
+
+Expected: PASS,输出包含 `Generated Prisma Client`
+
+- [ ] **Step 3: 运行 migration 状态检查,确认没有残留旧目录引用**
+
+Run: `npx prisma migrate status`
+
+Expected: 不再出现旧 migration 名称,只识别 `20260628_init_v1`
+
+- [ ] **Step 4: 查看最终工作区状态,只确认本次相关文件**
+
+Run: `git status --short backend/prisma backend/docs/数据库设计.md`
+
+Expected: 仅包含本次 baseline 重置相关改动,或已 clean
+
+- [ ] **Step 5: 提交最终收口**
+
+```bash
+git add backend/prisma backend/docs/数据库设计.md
+git commit -m "chore: finalize prisma v1 baseline"
+```