17 KiB
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Local-Development-and-Verification wiki_url: https://git.ilapage.cn/ila/yovision/wiki/Local-Development-and-Verification.- wiki_revision: 925a16a72bd5840697b5c61489a97018134b3930 synchronized_at: 2026-08-27T08:07:04Z
本地开发与验证
环境要求
| 工具 | 当前用途 | 检查命令 |
|---|---|---|
| Git | 版本和工作区保护 | git --version |
| Python 3 | Harness 脚本和测试 | python --version |
| Gitea | 工单与 Wiki | 浏览仓库或调用 MCP |
| Gitea PAT | Wiki 写入 | 仅由 MCP 或 GITEA_TOKEN 提供,不打印 |
Sense/Bell 的 Go、Node 与 pnpm 基线已冻结并记录于下文;Brain 的 Python/CUDA 以及 PostgreSQL、MediaMTX 精确版本仍将在对应骨架工单冻结。旧仓库环境不自动成为新项目事实。
第一次运行
-
检查工作区:
git status --short --branch预期:显示
main和本任务创建的引导文件,没有来源不明改动。 -
检查 Harness:
python dev_scripts/check_harness.py --strict预期:输出“DevHarness 检查通过”。
-
运行 Harness 测试:
python -m unittest discover -s tests -v预期:全部测试为
ok。 -
对照 Wiki:
python dev_scripts/sync_wiki_docs.py --check预期:全部映射一致。
子项目命令状态
| 项目 | 构建 | 测试 | 运行 | 当前状态 |
|---|---|---|---|---|
| Sense | cd Sense/server; go build ./...、cd Sense/ui; corepack pnpm@9.15.1 build:prod |
go test ./...、go vet ./...、前端 lint/单测 |
sense server -c <仓库外配置> |
GoAdmin 源码骨架已建立;业务模块待后续工单 |
| Brain | 待骨架工单冻结 | 待冻结 | 待冻结 | 未初始化业务代码 |
| Bell | 待 GoAdmin 派生工单建立 | 待建立 | 待建立 | 旧实现仅在 explore;新基线未初始化 |
不得复制旧仓库命令来填空。每个骨架工单必须同时建立 README、可复制命令和最小测试。
常用调试方式
- Harness 语法:
python -m compileall -q dev_scripts tests。 - 单测:
python -m unittest tests.test_harness_docs -v。 - 查看差异:
git diff --check、git diff。 - 查看 Wiki 配置:只查看
wiki-docs.json,不得打印 token。 - 跨项目问题先验证契约,再分别验证生产者和消费者,不直接修改两端猜测修复。
测试数据与日志
- 只使用合成或脱敏事件、合成 RTSP 和明确授权的实验室设备。ONVIF 自动化测试需覆盖 Basic、Digest challenge、Media 服务发现、跨主机地址归一化、拒绝地址凭据和禁止重定向。
- 不提交真实视频、客户名称、地址、手机号、摄像头密码或通知凭据;真实设备验证只记录状态与 Profile 数量,不记录设备地址、Authorization 或 Stream URI。
- 日志必须可按 request/event/alert ID 追踪,但不得记录 Authorization、Cookie 或连接密钥。
完成修改前
python -m unittest discover -s tests -v
python dev_scripts/check_harness.py --strict
python dev_scripts/sync_wiki_docs.py --check
git diff --check
git status --short
业务工单还必须运行其声明的子项目测试;跨契约工单必须运行所有受影响项目的契约测试。未执行部分写入工单。
Sense/Bell 固定工具链与只读参考源
根 goadmin-baseline.json 是机器可读基线。开始 Sense/Bell 骨架或升级工作前,先核对:
Get-Content .\goadmin-baseline.json
git -C D:\github\goadmin\go-admin rev-parse HEAD
git -C D:\github\goadmin\go-admin-ui rev-parse HEAD
git -C D:\github\goadmin\go-admin-doc rev-parse HEAD
go version
node --version
pnpm --version
D:\github\goadmin 下三个仓库只允许读取和核对,不允许在其中开发或提交 yovision 产品代码。本机路径不是跨机器事实;缺少该路径时,应从清单中的上游 URL 检出相同 commit 到仓库外目录。
截至 2026-08-12,系统 Go 1.23.0 仍不满足基线;开发机已在仓库外安装并校验隔离 Go 1.26.5,并通过 Corepack 使用 pnpm 9.15.1。Sense、Bell 的后端测试/构建与前端 lint/build 已在该隔离工具链完成。隔离目录是开发机临时事实,不得写入部署配置;其他机器应从官方来源安装相同精确版本。
go-admin-doc 只用于理解上游框架;项目自己的架构、开发规则和版本事实仍以 yovision Wiki、Agent 规则与 goadmin-baseline.json 为准。
Sense 本地构建与验证
Sense 后端与前端已从冻结源码建立。先确认 Go 1.26.5、Node 22.22.1 和 pnpm 9.15.1,再执行:
cd Sense/server
go test ./...
go vet ./...
go build ./...
cd ../ui
corepack pnpm@9.15.1 install --frozen-lockfile
corepack pnpm@9.15.1 lint
corepack pnpm@9.15.1 test:unit
corepack pnpm@9.15.1 build:prod
数据库固定为 PostgreSQL。复制 Sense/server/config/settings.yml 到仓库外,填写连接串和至少 32 个字符的随机 JWT 密钥;仓库模板本身不可直接启动生产服务。首次运行先执行 sense migrate -c <配置路径>,再通过只存在于当前进程的高熵令牌启动服务并创建首位管理员:
$env:SENSE_BOOTSTRAP_TOKEN = Read-Host "输入至少 32 个字符的一次性初始化令牌"
sense server -c <配置路径>
# 在另一个 PowerShell 中输入相同令牌;不要把真实值写入脚本或命令历史
$bootstrapToken = Read-Host "输入一次性初始化令牌"
$bootstrapBody = @{
username = "admin"
password = Read-Host "输入至少 6 个字符的管理员密码"
nickname = "系统管理员"
} | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://127.0.0.1:<端口>/api/v1/bootstrap" -Headers @{ "X-Sense-Bootstrap-Token" = $bootstrapToken } -ContentType "application/json" -Body $bootstrapBody
Remove-Variable bootstrapToken, bootstrapBody
初始化成功后停止服务,从启动环境中执行 Remove-Item Env:SENSE_BOOTSTRAP_TOKEN,再按正常生产方式启动。已有任一用户时初始化接口会拒绝请求。Sense 在 production、test、dev 模式均只提交账号和密码,不显示、不请求也不校验验证码;/api/v1/captcha 暂时保留作上游兼容接口,但登录页和登录 API 不依赖它。登录成功、错误密码和未认证拒绝仍必须写入脱敏身份审计,密码继续执行 6–72 字节策略。
Sense 默认登录有效期为固定 30 天。仓库配置和 Windows 运行脚本生成的 jwt.timeout 均为 2592000 秒,前端 Sense-Admin-Token Cookie 使用 30 天持久化期限。更新该版本后必须重新登录,已有 Token 不会自动延长。该有效期不是滑动续期;退出登录会删除本机 Cookie,但当前无状态 JWT 架构不提供服务端单 Token 撤销。如需立即使全部已签发 Token 失效,应在受控维护窗口轮换仓库外 JWT secret,并明确通知所有用户重新登录。
身份回归至少覆盖:admin 可管理账户及查看审计;implementation_operator 只能查看实施所需日志和字典支撑数据;site_admin 可维护账户并读取角色、部门、岗位、字典,但不能修改角色或菜单;viewer 不能访问管理接口。还要验证配置/接口管理路由返回 404、短密码被拒绝、6 位全小写密码可用,以及登录/登出/改密/拒绝审计中不含密码、令牌、Cookie 或验证码。身份审计直接写入 PostgreSQL,不依赖通用操作日志数据库开关。
详细来源与安全约束见 Sense/LICENSES/SOURCES.md 和 Sense/README.md。
设备台账启用凭据写入前,还必须在服务进程环境提供独立随机密钥;示例文件 Sense/server/config/credential.env.example 只保留空值:
# 生成一次随机 32 字节密钥并以 Base64 形式注入当前进程;不要打印或写入仓库
$keyBytes = New-Object byte[] 32
[System.Security.Cryptography.RandomNumberGenerator]::Fill($keyBytes)
$env:SENSE_CREDENTIAL_KEY = [Convert]::ToBase64String($keyBytes)
[Array]::Clear($keyBytes, 0, $keyBytes.Length)
缺少或格式错误的密钥时,普通设备台账仍可读写,但凭据更新返回服务不可用且不得产生部分写入。设备回归至少覆盖:中文名称与位置、未知 JSON 字段拒绝、版本冲突返回 409、非视频设备显示适配器未就绪、viewer 只读、凭据响应/操作日志不含明文,以及 PostgreSQL 迁移重复执行不增加菜单或权限记录。
视频接入还需在仓库外配置 SENSE_ONVIF_DISCOVERY_IP(获准的本机网卡 IP)和 SENSE_ONVIF_ALLOWED_CIDRS(逗号分隔的获准摄像头网段)。不要使用 0.0.0.0/0 代替授权清单。
协议回归位于 app/sense/onvif、app/sense/rtsp、app/sense/admission;隔离 PostgreSQL 重启恢复测试通过 SENSE_ADMISSION_TEST_DATABASE_URL 显式启用。验证至少覆盖 Digest/Basic、无配置发现提示、URL 凭据和敏感查询拒绝、目标网段、重定向、Media/Stream 主机归一化、主子码流、失败重探保留已验证 Profile,以及 viewer 只读权限。 MediaMTX 保持仓库外独立二进制。运行前在进程环境设置:
$env:SENSE_MEDIAMTX_BINARY = '<MediaMTX 可执行文件>'
$env:SENSE_MEDIAMTX_CONFIG = '<仓库外 mediamtx.yml>'
$env:SENSE_MEDIAMTX_API = 'http://127.0.0.1:9997'
配置文件不存在时 Sense 只生成 loopback API 和空 paths: {} 的无凭据基础配置;模板位于 Sense/server/config/mediamtx/mediamtx.yml.example。Control API 不允许非回环地址。真实集成验证使用:
$env:SENSE_MEDIAMTX_TEST_BINARY = '<MediaMTX 可执行文件>'
go test ./tests/media -run TestRealMediaMTXControlLifecycle -v
$env:SENSE_MEDIA_TEST_DATABASE_URL = '<隔离 PostgreSQL 连接>'
go test ./tests/media -run TestPostgresColdStartRestoresDesiredRoute -v
$env:SENSE_MEDIA_MIGRATION_TEST_DATABASE_URL = '<隔离 PostgreSQL 连接>'
go test ./cmd/migrate/migration/version -run TestMediaMigrationOnPostgres -v
测试必须使用隔离端口和数据库;结束后停止测试进程。不得输出连接串或摄像头凭据。
Sense 实时监看
浏览器直接访问 Sense 所在主机且 MediaMTX 使用默认 WebRTC 端口 8889 时无需额外变量。反向代理、HTTPS 或端口映射部署必须在 Sense 进程环境提供浏览器可达的基础地址;值只能是无用户信息、查询和片段的 HTTP(S) origin:
$env:SENSE_MEDIAMTX_WEBRTC_PUBLIC_BASE = 'http://<浏览器可达主机>:8889'
不要填写 RTSP 地址、Control API 地址、摄像头凭据或服务器内部文件路径。HTTPS 页面不得嵌入 HTTP 视频地址;应为 MediaMTX WebRTC 配置 HTTPS 或受控同源代理后填写对应 HTTPS origin。
定向与回归验证:
cd Sense/server
go test -race ./app/sense/liveview
go test ./...
go vet ./...
go build ./...
$env:SENSE_LIVEVIEW_MIGRATION_TEST_DATABASE_URL = '<隔离 PostgreSQL 连接>'
go test ./cmd/migrate/migration/version -run TestLiveviewMigrationOnPostgres -count=1 -v
cd ../ui
corepack pnpm@9.15.1 lint
corepack pnpm@9.15.1 test:unit
corepack pnpm@9.15.1 build:prod
真实 smoke 使用隔离端口、MediaMTX 和合成 RTSP:浏览器打开 WebRTC 播放地址后必须取得非零视频尺寸和可播放 readyState,并确认任一时刻只存在一个播放器。结束后停止测试 MediaMTX/FFmpeg/浏览器并删除临时目录。客户真实摄像机与现场网络仍需获得授权后验证,记录状态而不记录地址、URI 或凭据。
Bell 本地构建与验证
新 Bell 尚未初始化。骨架工单必须从冻结 GoAdmin 源码建立并验证独立构建、数据库、认证和前端流程;旧 Bell 命令只在 explore 对应提交中适用。
Sense Windows 打包与验证
在仓库根目录使用冻结工具链构建:
Sense\scripts\build\build-windows.ps1 -MediaMTXPath D:\approved\mediamtx.exe
构建脚本严格检查 Go 1.26.5、Node 22.22.1 和 pnpm 9.15.1,执行前端生产构建与 Windows 后端构建,并生成 Sense\dist\sense-windows-amd64\ 和同名 ZIP。未传 -MediaMTXPath 时只生成占位说明,交付前必须另外提供已审核的 Windows amd64 MediaMTX。构建末尾会执行包审计,并清理源码目录的 Sense/ui/node_modules 与 Sense/ui/dist。
提交前验证:
cd Sense\server
go test ./...
go vet ./...
go build ./...
go test -race ./app/sense/media ./cmd/api
cd ..\..
Sense\scripts\build\test-package.ps1 -PackageRoot Sense\dist\sense-windows-amd64
包内验证从解压目录执行:
check-sense.bat
start-sense.bat
stop-sense.bat
检查项至少覆盖配置解析与进程环境优先级、特殊字符不被执行、production/demo 数据库隔离、迁移失败不启动服务、首页 SPA fallback、/healthz、MediaMTX Control API、包外工作目录启动与停止、PostgreSQL custom-format 备份及恢复到独立数据库。真实摄像机、目标客户数据库账号、目标浏览器与干净客户机器仍须在授权交付环境验收。
GoAdmin 派生前置检查
每个 Sense/Bell 骨架或基础能力工单在修改前必须:
- 核对
goadmin-baseline.json中三个完整 commit。 - 核对本机只读副本或重新检出的上游仓库 HEAD。
- 阅读任务相关的 go-admin-doc 主题/文件,并把参考项记录到工单。
- 记录计划继承的 go-admin/go-admin-ui 路径、计划隐藏/禁用的模块和许可证处理。
- 验证最终产品树确实包含上游派生结构;只使用 Go、Vue、Element Plus 或相似视觉不算通过。
Sense 区域与警戒线验证
后端定向与全量验证:
cd Sense/server
go test ./app/sense/area ./app/sense/admission
go test -race ./app/sense/area ./app/sense/admission
go test ./...
go vet ./...
go build ./...
使用隔离 PostgreSQL 验证迁移和真实并发;连接值只放当前进程环境,不写入仓库或日志:
$env:SENSE_AREA_MIGRATION_TEST_DATABASE_URL = '<隔离 PostgreSQL 连接>'
go test ./cmd/migrate/migration/version -run TestAreaMigrationOnPostgres -count=1 -v
$env:SENSE_AREA_TEST_DATABASE_URL = '<隔离 PostgreSQL 连接>'
go test ./app/sense/area -run TestConcurrentUpdateOnPostgresReturnsConflict -count=1 -v
前端验证:
cd Sense/ui
corepack pnpm@9.15.1 install --frozen-lockfile
corepack pnpm@9.15.1 lint
corepack pnpm@9.15.1 test:unit
corepack pnpm@9.15.1 build:prod
���览器 smoke 至少覆盖:鼠标添加和拖动顶点;键盘 Enter 添加、方向键移动、Delete 删除;错误文字可见并具有 aria-live/alert 语义;刷新后版本、启停和重新校准状态仍可追溯。真实摄像机校准只使用明确授权设备,不记录地址、URI、凭据或视频内容。Brain、Bell 不启动时必须能独立保存、读取和预览。
Sense 本机 Supervisor 托管
本机开发/演示环境可由 D:\supervisor 托管已经构建的 Sense Windows 交付包。实例配置位于仓库外的 D:\supervisor\programs\yovision.conf,实例名为 yovision-sense;工作目录固定为 D:\OPC\yovision\Sense\dist\sense-windows-amd64。
Supervisor 配置只调用包内 scripts\runtime\start-sense.ps1,运行参数继续从包内 config\sense.env 读取。不得把数据库连接、JWT 密钥、摄像头凭据或其他秘密复制到 Supervisor 配置或工单。
常用命令:
D:\supervisor\supervisord.exe ctl /c D:\supervisor\supervisord.conf status yovision-sense
D:\supervisor\supervisord.exe ctl /c D:\supervisor\supervisord.conf restart yovision-sense
D:\supervisor\supervisord.exe ctl /c D:\supervisor\supervisord.conf stop yovision-sense
D:\supervisor\supervisord.exe ctl /c D:\supervisor\supervisord.conf start yovision-sense
Get-Content D:\supervisor\logs\yovision-sense.log -Tail 100
新增或修改 programs/*.conf 后执行:
D:\supervisor\supervisord.exe ctl /c D:\supervisor\supervisord.conf reload
当前 Go Supervisor 的 reload 会重新读取独立配置;实际受影响实例必须以命令输出和 reload 前后 PID 为准。切换托管前先停止占用 Sense 端口的非 Supervisor 实例,防止自动启动进入 Backoff。验证至少包含 Supervisor 状态为 Running、http://127.0.0.1:18080/health 与首页返回 200,以及受控重启后 Sense 和受管 MediaMTX PID 均更新。