1
T-201
ila edited this page 2026-08-07 16:36:25 +08:00
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.

同步来源:docs/tasks/T-201.md · commit afc651f75a3a


id: T-201 title: 生成并收敛 Go-Gin、SQLite 和迁移骨架 phase: 2 deps:

  • T-104 status: DONE created: 2026-07-25 context_ref: 84f2da3cf7 work_branch: main write_paths:
  • backend-api/**
  • init.ps1
  • init.sh
  • README.md
  • docs/00-ai-start-here.md
  • docs/03-tech-stack.md
  • docs/04-architecture.md
  • docs/05-coding-rules.md
  • docs/api.md
  • docs/current-state.md
  • docs/tasks/T-201.md
  • progress.md

问题 / 背景

Phase 1 已证明 Android 能从私有任务完成结构化需求提取、拼多多有界搜索、最多 5 个 候选评估并停在人工确认点。Phase 2 需要统一后端承载后续的管理 Web、手动领取、租约 和结果回传,但仓库当前没有 Go module、HTTP 服务、SQLite 生命周期或迁移入口。

关联需求与交互

  • 功能:F-001、F-002、F-003、F-007 的共享后端基础,不在本任务实现业务接口。
  • 用户故事:US-001、US-002、US-003、US-007 的前置基础设施。
  • 交互:不适用;T-202 才生成并确认 P0 Web/App 原型。
  • 架构/API:docs/03-tech-stack.md 后端版本与骨架选择、docs/04-architecture.md Backend API 分层、docs/api.md 通用 HTTP 约定。

方案

  1. 固定 Go Blueprint v0.10.11,在仓库外临时目录生成最小 Gin + SQLite 项目作为 一次性参考,不直接保留演示业务和生成器默认配置。
  2. 建立 cmd/api 和 cmd/migrate 两个入口;应用入口只负责装配、信号处理和优雅 关闭,迁移入口显式执行版本化 SQL。
  3. 使用 Go 1.23.0、Gin 1.11.0、database/sql、mattn/go-sqlite3 和 Goose v3.26.0;所有验证设置 GOTOOLCHAIN=local。
  4. 配置、SQLite、迁移和 Gin transport 分包;关闭默认 CORS,不读取或提交 .env, 默认只监听本机回环地址,健康检查失败不得终止进程或泄露内部错误。
  5. SQLite 创建父目录、启用 foreign keys、busy timeout 和 WAL,限制单进程写连接, 并由调用方显式关闭数据库。
  6. 单元/集成测试覆盖配置边界、健康检查成功/失败、SQLite pragma、迁移 up/down 和 HTTP 路由;根初始化脚本纳入后端测试与构建。

验收要点

  • go.mod 精确声明 Go 1.23.0、Gin 1.11.0 和固定依赖版本。
  • GOTOOLCHAIN=local go test ./... 和 Windows 后端构建通过。
  • migration 在临时 SQLite 上可 up/down,运行数据目录被 Git 忽略。
  • /healthz 正常返回稳定 JSON;数据库不可用时返回 503 且进程不退出。
  • HTTP Server 具有读头、读、写、空闲和优雅关闭 timeout。
  • 没有包级数据库单例、隐式 .env、默认 CORS、演示业务或明文凭证。
  • 根 init.ps1/init.sh 同时验证 Android 和后端。
  • 启动 smoke、迁移、测试、构建和敏感信息检查均有可复现证据。

边界

  • 不实现任务创建、列表、鉴权、claim、租约、事件或资产 API。
  • 不实现管理 Web 页面或 Android HTTP TaskSource。
  • 不引入 ORM、SPA、Redis、消息队列、WebSocket、Docker 或自动下单逻辑。
  • 不提交 SQLite 数据文件、.env、密钥、私有任务或生成器临时目录。

执行记录

2026-07-25:任务开始

  • 基于 T-104 提交 84f2da3 开始。
  • 本机已核实 Go 1.23.0、CGO 开启、GCC 可用,且 Go Blueprint 可执行文件存在。
  • 先完成骨架生成审计和依赖版本固定,再写入正式代码。

2026-07-25:骨架审计与实现

  • 本机 Go Blueprint 精确版本为 v0.10.11;在仓库外临时目录执行文档生成命令, 文件已完整生成,但 CLI 在非交互 PowerShell 恢复终端时返回错误码。
  • 生成树当前解析为 Go 1.25.0、Gin 1.12.0,并含默认 CORS、.env autoload、 包级数据库单例、log.Fatal 健康检查和 Hello World;正式实现未复制这些行为。
  • 正式 go.mod 固定 Go 1.23.0、Gin 1.11.0、go-sqlite3 1.14.48 和 Goose 3.26.0; v3.27.x 因要求 Go 1.25 未采用。
  • 建立 cmd/api、cmd/migrate、internal/config、SQLite、migration 和 transport/httpapi;没有提前创建空的 domain/usecase/repository/web 包。
  • SQLite 强制 foreign keys、5 秒 busy timeout、WAL、immediate transaction 和 单连接;Gin 默认只监听回环地址,无 CORS/默认 logger,请求异常只记录通用事件。
  • 公共错误固定 request_id、retryable=false 和空 details;优雅关闭超时后强制 关闭 listener 并有界等待,避免数据库关闭后继续接受请求。

2026-07-25:自动化验证

  • 执行 $env:GOTOOLCHAIN="local"; go test -count=1 ./...:25 个测试通过,0 失败; 配置、SQLite、迁移、健康 200/503、安全 recovery、错误合约、404/405、正常关闭和 超时强制关闭均有覆盖。
  • 执行 go test -race -count=1 ./...、go vet ./...、gofmt -l、API/migration Windows 构建,全部通过;二进制使用本地 Go 1.23.0 工具链。
  • 根目录 $env:RUN_START_COMMAND="0"; .\init.ps1 成功完成 Android test assembleDebug、后端 test/vet/gofmt 和双入口构建。
  • 默认 Debug APK 的 assets/probe-fixtures/ 条目为 0;bin/、var/、数据库、 WAL/SHM、日志和 .env 均被 Git 忽略。

2026-07-25:迁移与 HTTP smoke

  • 独立临时 SQLite 执行 status -> up -> up -> down -> up -> status: 状态按 pending/applied 切换,第二次 up 返回 applied=0。
  • API Windows 进程使用动态回环端口启动;GET /healthz 返回 {"status":"ok"},Cache-Control 为 no-store,未知路由为 404,POST health 为 405,公共错误合约完整,未返回 CORS header,stdout/stderr 字节数均为 0。
  • smoke 结束后精确检查 API 测试进程数量为 0。健康 503 和不终止行为由 Fake DB 集成测试验证;不需要破坏真实运行时数据库来制造故障。

未验证项

  • 当前 Windows 的 bash.exe 指向未配置发行版的 WSL,init.sh 未实际运行;脚本 已与 Windows 入口同步 Go/CGO/test/vet/gofmt/build 逻辑,需在 Linux/WSL 复核。
  • /healthz 当前只表示进程与数据库连接可用,不检查 migration 是否最新;增加 readiness/migration 门禁应在首个业务表落地前完成。
  • 默认数据库路径相对启动工作目录;本地命令必须从 backend-api/ 运行,部署时应 显式配置绝对 CMROUBAO_DATABASE_PATH。
  • 本任务没有业务表、鉴权、管理页面或任务 API;分别属于 T-202 至 T-205。