Files
yovision/docs/tasks/T-009.md
T
QiuSW 04231d006a
Harness governance / validate (push) Has been cancelled
chore(task): claim T-009
2026-08-07 17:32:48 +08:00

7.7 KiB
Raw Blame History

id, title, phase, deps, status, created, issue, context_ref, claim_branch, work_branch, write_paths
id title phase deps status created issue context_ref claim_branch work_branch write_paths
T-009 建立 PostgreSQL 双 Schema 与 Bell 配额投影基础 2
T-008
DOING 2026-08-07 31 8a4514076e claims/T-009 agent/codex/T-009
docs/tasks/T-009.md
deploy/postgres/
scripts/test_postgres.ps1
Sense/internal/store/
Sense/internal/config/
Sense/cmd/sense-api/main.go
Sense/go.mod
Sense/go.sum
Sense/README.md
docs/03-tech-stack.md
docs/04-architecture.md
docs/06-tasks.md
docs/api.md
docs/current-state.md
tests/test_postgres_contract.py

问题 / 背景

T-008 已冻结 Sense Control API v1 和 bell.site_quota_v1 只读投影,但当前 Sense 仍只使用 M1 SQLite,Bell 也没有 PostgreSQL 源表、schema、角色或 migration。若直接实现 HTTP handler,tenant、配额读取、并发准入和事务语义仍会绑定 SQLite,后续迁移必然返工。

项目负责人指定使用本机现有 D:\pgsql17,已核实二进制与服务版本为 PostgreSQL 17.10、默认端口 5432。现有实例要求 SCRAM 且当前执行环境没有管理员密码,因此自动验收必须使用同一套本机二进制启动隔离临时集群;不得修改现有实例的认证、角色、数据库或数据。生产/共享实例安装只有在操作者显式提供管理员连接信息时才执行。

关联需求与交互(如适用)

  • 用户故事:US-001、US-002、US-008、US-009、US-010。
  • 交互清单:IX-001~IX-004、IX-013~IX-016、IX-019、IX-020;本任务是数据基础,不修改已确认原型或实现 HTTP 页面交互。
  • 前置契约:docs/contracts/sense-control-v1.openapi.json、docs/contracts/site-quota-v1.sql 和 docs/contracts/README.md。

方案

  1. 冻结 PostgreSQL 17.10 与 Go PostgreSQL driver;增加可审计、顺序执行的初始化 SQL,创建 NOLOGIN 权限角色 bell_app/sense_app、bell/sense schema、Bell Site 配额源表和 Sense 设备/能力/调和表。
  2. migration 创建与 T-008 完全一致的 bell.site_quota_v1(tenant_id, site_id, max_video_channels, source_version, source_updated_at);Bell 拥有源表和视图,Sense 只有 Bell schema USAGE 与视图 SELECT,没有 Bell 源表或写权限。
  3. Bell Site 在数据库层执行默认 16、范围 1~128、逻辑删除和单调版本;配额更新通过 trigger 增加版本,不能由 Sense 修改。
  4. 新增 Sense PostgreSQL repository,覆盖现有 SQLite 被对账/探活使用的全部 port;设备新增/启用在同一事务内按 tenant/site 读取配额投影、串行化同站点准入、统计 enabled + video_capture,并拒绝投影缺失、越界或版本回退。
  5. Sense 进程增加显式 SENSE_DB_DRIVER=sqlite|postgres;默认继续使用 SQLite 保持单摄像头开发路径,生产选择 PostgreSQL 时必须显式提供 DSN。不得把 DSN、密码或完整连接串写入日志、错误、任务证据或仓库。
  6. 使用 D:\pgsql17\bin 的 initdb/pg_ctl/psql 启动仅绑定回环地址的隔离临时集群,执行 migration、权限断言和 PostgreSQL repository 集成测试,结束后验证目标路径再清理临时数据目录;不停止或重启现有 Windows PostgreSQL 服务。
  7. 增加无 PostgreSQL 也能运行的静态契约测试,校验 migration 顺序、角色权限、配额视图签名、范围、版本 trigger 和禁止的宽权限;同步技术栈、架构、API、路线图、Sense 启动说明与当前状态。

不可变约束

  • 阈值 / 数值边界:max_video_channels 默认 16、有效范围 1~128;16/128 不是单机承载保证。只统计 desired_state=enabled 且具有 video_capture capability 的设备;同站点并发创建/启用不能突破配额。
  • 判定式 / 状态转换:配额行缺失、读取失败、值越界或 source_version 回退时,PostgreSQL repository 只拒绝相关视频新增/启用,不停已有设备、不修改期望态;降低配额不会自动停用已有流。相同期望态重复提交不增加 generation。
  • 数据所有权:Bell 是 Tenant/Site/配额真相源;Sense 不建立可写 Site 真相副本,不写 Bell schema、不读取 bell.sites 源表。Sense 设备和调和状态只写 sense schema;两个 schema 只以 tenant/site 逻辑 ID 关联。
  • 安全边界:仓库、测试输出、Issue/PR 和日志不得出现 PostgreSQL 密码、DSN 凭据或私有数据。自动测试只使用临时 trust 集群且只绑定 127.0.0.1;现有 D:\pgsql17\data、Windows 服务和其他数据库严格只读。
  • 兼容与恢复:M1 SQLite 默认路径和现有五路集成工具继续可用;T-009 不搬迁或删除现有 SQLite 数据。生产切换失败时可回到 SQLite 配置;初始 PostgreSQL schema 不提供自动破坏性 down migration,清理由管理员在备份/确认后限定到 YoVision 专用数据库执行。
  • 既有契约:不修改 T-008 OpenAPI 路径、字段、错误语义、配额视图列签名或 Brain 事件 v0.1;PostgreSQL repository 的出现不表示 Sense HTTP handler、认证或 Bell 管理服务已经实现。

验收要点

  • 任务相关验证:在本机执行 ./scripts/test_postgres.ps1 -PgRoot D:\pgsql17,必须完成隔离集群启动、migration 重放、权限断言、tenant/配额/并发/版本回退 repository 集成测试和自动清理;运行 python -m unittest tests/test_postgres_contract.py 或对应 discovery 命令,静态负例能够拦截 Bell 写权限与契约漂移。
  • 完整门禁:运行 ./init.ps1、python scripts/validate_agent_context.py、python -m unittest discover -s tests -p "test_*.py"、python scripts/validate_harness_governance.py、go -C Sense test ./...、go -C Sense vet ./...、go -C Sense build ./... 和 git diff --check,全部通过。
  • 人工 / 设备验收:不需要摄像头、UI 或客户现场;任务所有者必须核对隔离集群确实没有使用 D:\pgsql17\data,现有服务 PID/端口在测试前后保持运行,且共享实例未新增 YoVision 对象。
  • 构建产物:PostgreSQL migration、权限/迁移断言、本机隔离测试入口、Sense PostgreSQL repository 和配置/运维文档;不提交临时数据目录、数据库 dump 或秘密。

边界(不改什么)

不实现 Sense Control API HTTP handler、Bearer 认证、RBAC、幂等收据、ETag/cursor/batch operation、Area/capture policy 投影、Bell Go 服务、SQLite→PostgreSQL 数据搬迁、WireGuard、孤儿删除、16 路容量压测或 T-007 现场验收;不修改 Brain、MediaMTX API、摄像头适配器、事件契约或已确认 UI 原型。

协作约束

  • 责任 Agent:由 dispatcher 分配。
  • 唯一写入者:同责任 Agent。
  • 委派:默认不启用。
  • Gitea:任务文件先进入默认分支,再创建唯一 Issue 并回填编号;领取时记录 context_ref、claim 与工作分支。

任何新增写路径先检查与其他活跃任务是否重叠;同一时刻只有一个 Agent 修改本任务的 write_paths。

执行记录

2026-08-07 领取任务

  • dispatcher ila 将任务分配给 codex;context_ref 为 8a4514076e9921b12bc26380b2aceee9334e947d,claim 为 claims/T-009,工作分支为 agent/codex/T-009。
  • 接受任务文件声明的全部写路径;当前其他任务无活跃写路径冲突,T-007 仍因外部真实设备保持 waiting。

2026-08-07 任务定义

  • 项目负责人批准创建并实施 T-009,并指定复用本机 D:\pgsql17;核实版本为 PostgreSQL 17.10。
  • 当前实例监听 5432 且 SCRAM 认证有效,执行环境未持有管理员密码;任务据此选择“本机同版二进制 + 隔离临时集群”作为自动验收,不触碰现有数据目录和服务。