--- 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
up/down/steps/version/force"] --> B["pkg/setting
读取 Mysql 段"] B --> C["pkg/migration.Run
DSN multiStatements=true"] C --> D["iofs.New(embed FS, .)"] D --> E["pkg/migration/*.sql
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:输出路径引用与文件清单核查结果,确保无残留旧路径