Files
zt-closet-backend/.codebuddy/plans/扁平化迁移脚本目录结构_11e4276d.md
2026-09-11 01:41:52 +08:00

106 lines
5.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: 扁平化迁移脚本目录结构
overview: 把 pkg/migration/migrations/*.sql 上移一层到 pkg/migration/*.sql,embed 改为 *.sql + iofs.New(fs, "."),并删除根目录多余的空占位目录 migrations/,同步更新 README 与验证。
todos:
- id: flatten-sql
content: 将 32 个迁移 SQL 上移到 pkg/migration 并删除空的 migrations 子目录
status: completed
- id: fix-embed
content: 修改 migration.go 的 embed 模式与 iofs 源路径为当前目录
status: completed
dependencies:
- flatten-sql
- id: clean-root-dir
content: 删除仓库根空的 migrations 占位目录
status: completed
- id: sync-readme
content: 同步 README 中所有 pkg/migration/migrations 路径引用
status: completed
dependencies:
- fix-embed
- id: verify-build
content: 编译与 go vet 校验,并用临时测试确认 embed 源可解析(验证后删除)
status: completed
dependencies:
- fix-embed
- sync-readme
- id: review-paths
content: 用 [subagent:code-explorer] 复核目录结构与路径引用无残留
status: completed
dependencies:
- verify-build
---
## 产品概述
调整已实现的数据库迁移目录结构:去掉 `pkg/migration/migrations/` 这一层多余嵌套,将版本化 SQL 直接放在 `pkg/migration/` 下,并清理仓库根已失效的 `migrations/` 占位目录;迁移入口 `cmd/migrate` 保留不动。
## 核心功能
- **SQL 目录扁平化**:32 个迁移脚本(`000001~000016` 的 up/down 配对)上移一层至 `pkg/migration/`,文件名与内容完全不变,删除空的 `migrations/` 子目录
- **embed 路径适配**:改为 `//go:embed *.sql` + `iofs.New(migrationFS, ".")`,迁移脚本与 `migration.go` 同级
- **清理根目录**:删除仓库根已无引用的空占位目录 `migrations/`(`sql/`、`scripts/`、`docs/` 保持不变)
- **文档同步**:README 目录树与「准备数据库」章节中的 `pkg/migration/migrations` 路径全部改为 `pkg/migration`
- **迁移能力不变**:`Up/Down/Steps/Version/Force` API、`cmd/migrate` 子命令、22 张表 SQL 内容均保持不变
## 技术栈
- Go 1.27,模块 `git.lzcwy.cn/zhengchiliu/zt-closet-backend`
- `github.com/golang-migrate/migrate/v4 v4.19.1`(`database/mysql` 驱动 + `source/iofs` 源)
- `github.com/go-sql-driver/mysql v1.10.0`
## 实现方案
采用「脚本与代码同级」的扁平布局:`//go:embed *.sql` 把同目录 SQL 打进 embed FS,`iofs.New(migrationFS, ".")` 以当前目录作为 golang-migrate 源根目录,文件名 `00000N_xxx.up.sql` / `.down.sql` 保持 golang-migrate 规范不变。
关键决策:
1. **去掉源子目录而非保留**:`iofs` 源只需一个目录根,SQL 与 `migration.go` 同级时路径最短、引用最少,且不损失任何能力(golang-migrate 按文件名而非目录识别版本)。
2. **`//go:embed *.sql` 只嵌入 SQL**:embed FS 中不会出现 `.go` 文件,避免 `iofs` 源扫描到无关文件。
3. **保留 `cmd/migrate`**:用户已确认接受 Go 标准布局;独立二进制使迁移不依赖主服务的 Redis/COS/支付等初始化。
4. **不改文件名与内容**:避免已应用环境的版本号/校验和变化,保证迁移历史兼容。
## 实现要点(防回归)
- `migration.go` 中 `migrationsDir` 常量改为 `"."` 并更新注释(迁移脚本与本文件同级);`iofs.New(migrationFS, migrationsDir)` 调用不变。
- 文件名保持 `00000N_xxx.up.sql` / `00000N_xxx.down.sql`,**不要**重命名或改版本号。
- 验证用临时测试文件放在 `pkg/migration` 下(仅 `iofs.New` + `src.First()`,不连数据库),**验证后必须删除**。
- 不要改动 `cmd/migrate/main.go`、SQL 内容与迁移包对外 API。
- 不连接真实数据库:`configs/config.yaml` 的 MySQL 为内网地址,且该文件第 2 行 `Domain: *` 为非法 YAML(用户本地配置,本次不处理)。
## 架构设计
```mermaid
flowchart LR
A["cmd/migrate/main.go<br/>up/down/steps/version/force"] --> B["pkg/setting<br/>读取 Mysql 段"]
B --> C["pkg/migration.Run<br/>DSN multiStatements=true"]
C --> D["iofs.New(embed FS, .)"]
D --> E["pkg/migration/*.sql<br/>000001~000016 up/down"]
C --> F["mysql.WithInstance(*sql.DB)"]
E --> G["migrate.NewWithInstance"]
F --> G
G --> H["schema_migrations"]
```
## 目录结构
```
pkg/migration/
├── migration.go # [MODIFY] //go:embed 由 migrations/*.sql 改为 *.sql;migrationsDir 常量由 "migrations" 改为 ".";
│ # Up/Down/Steps/Version/Force/Run 与 DSN 拼装逻辑不变
├── 000001_create_users.up.sql # [MOVE] 由 migrations/ 上移,内容不变
├── 000001_create_users.down.sql # [MOVE]
├── ...(000002~000016 的 up/down,共 32 个文件)[MOVE]
└── migrations/ # [DELETE] 空目录,扁平化后删除
migrations/ # [DELETE] 仓库根空占位目录,已无引用
README.md # [MODIFY] 目录树:pkg/migration 去掉 migrations 子层;
# 「准备数据库」章节与 sql/ 占位说明中的 pkg/migration/migrations 改为 pkg/migration
```
## Agent Extensions
### SubAgent
- **code-explorer**
- Purpose:扁平化完成后复核 `pkg/migration/` 目录结构与 README 中的路径引用,确认 `migrations/` 子目录与根占位目录已消失、无遗留 `pkg/migration/migrations` 文本引用、32 个 SQL 文件齐全且 up/down 配对完整
- Expected outcome:输出路径引用与文件清单核查结果,确保无残留旧路径