# 第一期本地实现与验证 Type: task Status: resolved Scope: [已确认规格](../spec.md) ## Work 完成微信身份与业务会话、PostgreSQL 迁移、项目管理、练习记录、日历和成长页;保持 07–09 规划票不变。不部署、发布、提交或推送。 ## Validation 按规格默认测试安排,通过 HTTP 请求/响应验证真实 PostgreSQL 持久化、身份隔离、幂等、归档与统计;仅替换外部微信核验。另执行后端 vet/race/build、小程序 typecheck/build。微信开发者工具、真实身份和跨设备验收分别记录,不由构建结果替代。 ## Comments - 2026-09-28:已读取交接、规格及仓库约定。工作区原有 `AGENTS.md` 修改和 `.scratch/`、`docs/` 材料保留。 - 2026-09-29:用户完成微信开发者工具登录并授权开启本机服务端口。CLI 通过 34789 确认 `login: true` 并打开项目,通过 34790 接入官方自动化 SDK;验收边界与结果补充如下。 - 2026-09-29:用户配置后端微信凭据后,核对 AppID 与项目一致;已启动本机 Compose PostgreSQL 和 Go 开发服务。`healthz`、`readyz` 均为 200;从模拟器取得真实 `wx.login` code,由本机 HTTP 客户端提交后端,微信身份交换成功返回业务会话,携带会话读取到 8 个初始项目。没有输出或另存凭据。模拟器直接请求本机接口仍被域名校验拦截,已请求用户确认仅对被 Git 忽略的本机私有配置关闭该校验;确认前不修改安全设置。 - 2026-09-29:用户手动勾选本机“不校验合法域名”。确认私有配置 `urlCheck: false` 后,完成真实后端的模拟器保存、更正、重读和统计联调;临时记录已清理,后端与数据库保持运行。 ## Answer 2026-09-28 完成第一期本地实现,2026-09-29 补充真实微信身份及本机模拟器联调;本票不代表生产发布或完整真机验收完成。 - 后端:版本化事务迁移;微信 code2Session 核验适配器;30 天随机业务会话;八个项目原子预置;项目新增/改名/删除或归档;练习增删改查、提交幂等及删除回执;按实际练习日期计算累计、去重练习日、周/月趋势和项目分布。写入按用户串行化并校验归属。 - 小程序:记录、日历、成长三个入口,独立记录表单和项目管理页;保存后回来源页并刷新;失败与空结果分开;会话失效恢复;待确认提交保留输入和原标识。近期列表按登记/更正时间排序,补记可立即看到。未加入演示数据、计时器、激励、分享或 07–09 的其他规划。 - 执行默认值:项目名 40 个 Unicode 字符、笔记 2000 字符;分钟为正整数并受 PostgreSQL integer 范围约束。暂存表单只跨当前进程内页面导航,不提供离线队列或重启后的草稿持久化。 ### 实际验证 - `go vet ./...`、连接隔离 PostgreSQL 18 的 `REQUIRE_TEST_DATABASE=1 go test -race ./...`、`go build -o bin/api ./cmd/server` 全部通过。Go 共 12 个顶层测试(其中 9 个业务/数据库集成测试、3 个健康检查测试);业务测试替换微信外部网络响应,其他会话、授权和数据库操作真实执行。 - HTTP 验证包括首次/再次登录、过期会话、另一账户猜测标识、改名/归档、归档记录编辑限制、补记与更正/删除后的统计、周日/周一及月底边界、上海业务日期、正整数/空值/长度约束、分页、重复提交/主动重复登记、并发重试/项目移除、删除回执、服务失败。重新创建 handler 后仍能恢复同一账户的数据库记录。 - `./scripts/test-integration.sh` 已实际启动独立临时 PostgreSQL 并执行 race 测试成功,退出后自动清理其容器。开发过程中另建的隔离测试容器也在收尾清理;这些隔离集成测试没有使用业务数据库或 Compose 数据卷。 - `pnpm typecheck`、`pnpm test:client`(3 项通过)、`pnpm build` 全部通过。客户端测试在 Taro 网络/存储边界验证续期、待确认提交、失败状态及成功写入通知,不等于小程序端到端运行验证。 - `docker compose --env-file .env.example config --quiet` 和本地镜像 `ballet-island-v1-local-check` 构建通过。构建时有上游 Node `punycode` 弃用提示,不影响编译成功。 - 两次只读核验:后端核验未发现确定缺陷;前端核验发现“未确认保存可取消而丢失提交标识”,已由主代理修正并补充客户端回归检查。主代理另修正近期记录排序,并以失败到通过的 HTTP 回归验证。 - 2026-09-29 微信模拟器:开发者工具 2.02.2608070、基础库 3.17.4、iPhone 12/13 (Pro) 390px 视口。记录、日历、成长三个页面均能打开,在真实后端不可达时明确显示网络失败及重试入口,没有捕获到未处理异常。 - 临时模拟微信/HTTP 响应后,9 项 UI 检查通过:八项目与近期记录、项目卡片进入表单并预选、空时长阻止提交、填写与保存后返回首页、日历标记及当天记录、补记首项选择与取消返回、周趋势和分布、月趋势切换与点按、项目管理添加。模拟结果不代表真实微信核验或数据库持久化;未写入真实后端或本地业务会话存储,检查后恢复原始 wx 方法并清除模拟数据。 - 截图发现 Taroify 默认按钮尺寸与项目 375px 设计宽度不匹配;仅通过公开主题变量修正按钮尺寸、边距和字号。再次执行 `pnpm typecheck`、`pnpm build`、`git diff --check` 通过,并重新通过上述 9 项 UI 检查。模拟器测得小按钮 33px、主按钮 45px,四个快捷时长按钮同排;已目视检查五页截图。 - 本机真实联调 7 项通过,全程未模拟微信身份或 HTTP 响应:登录后读取项目;模拟器保存 1 分钟临时记录并由已认证接口读回;日历显示记录及练习日标记;成长页与接口均增加 1 分钟、1 条记录;重新进入首页仍读到记录;表单更正为 2 分钟且记录数不增加;通过已认证 DELETE 接口清理本次临时记录后,累计时长和记录数恢复联调前值。没有捕获到未处理异常。此轮没有验证原生删除确认弹窗;清理仅按本次唯一临时标记定位,不修改用户其他记录。 ### 未验证与下一步 - 本机 `backend/.env` 已配置 `WECHAT_APP_ID` / `WECHAT_APP_SECRET`,真实微信身份交换与已认证项目读取已验证。凭据只供服务端使用,没有输出或加入小程序包。 - 微信开发者工具登录、项目打开和五页模拟器渲染已验证;原生键盘、其他窄屏尺寸、弱网/断网保存及系统返回提示仍未完成平台验收。本次模拟器验证使用自动化输入事件,并仅对部分页面执行滚动检查。 - 本机 127.0.0.1:8080 的后端与 PostgreSQL 已启动且就绪。用户关闭本机开发者工具域名校验后,小程序到后端、数据库的真实保存、更正与读取链路已通过。 - 正式 request 合法域名/HTTPS、另一设备读取、客户端进程重启恢复和真实多账户隔离仍待验收;重新进入首页不等于完整进程重启。HTTP 中的受控微信响应不能替代这些证据。 - 本轮没有部署、发布、提交或推送;07–09 规划票保持原状。启动步骤和接口约定见根目录 `README.md`。