7.0 KiB
7.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Build, Test & Restart Commands
本地 Windows 编译
- Build:
go build -o managerd ./cmd/managerd或pwsh -File scripts/managerd.ps1 build - Run:
./managerd(usesmanagerd.jsonconfig) or./managerd <config-path> - 重启服务(编译+启停+健康检查一站式):
pwsh -File scripts/managerd.ps1 restart - 查看服务状态:
pwsh -File scripts/managerd.ps1 status - Test all:
go test ./... - Test single package:
go test ./internal/service/... - Test single test:
go test ./internal/storage/... -run TestAssetsRepo_SaveTemplate - Verbose test:
go test ./internal/web/... -v -run TestUI_ActionDevicesBatchAction
81 (ARM64) 编译部署(主要开发流程)
Windows 上改代码 push → 81 上 pull 编译部署:
# 管理端
cd ~/apps/safesight-control
git pull
GOPROXY=https://goproxy.cn,direct bash scripts/build.sh
sudo systemctl restart safesightd
# Edge agent
cd ~/apps/safesight-edge/agent
git pull
GOPROXY=https://goproxy.cn,direct go build -ldflags="-s -w" -o safesight-edge-agent ./cmd/safesight-agent/
sudo systemctl restart safesight-edge-agent
81 已安装 Go 1.23.4,设置 goproxy.cn 镜像代理。
Codebase Architecture
Layered Structure (no DI framework — manual wiring in main.go)
cmd/managerd/main.go — Composition root: builds config, services, storage, router
internal/api/ — Thin HTTP handlers that delegate to services (chi router, no framework)
internal/web/ — Embedded HTML UI (Go html/template + layout.html pattern)
internal/service/ — Business logic (discovery, registry, tasks, config assets, preview rendering, template slots)
internal/storage/ — SQLite persistence (raw SQL via database/sql, pure-Go modernc.org/sqlite driver)
internal/config/ — JSON config file loading (managerd.json)
internal/models/ — Core domain types (Device, Task, DeviceTaskStatus, etc.)
templates/ — Local JSON template files loaded at runtime
templates/standard_templates/ — "Standard" templates (std_ prefix) imported into SQLite on startup
Dependency Flow (all wired in main.go)
config → service (agent client, registry, discovery)
config + service → storage (opens SQLite, creates repos)
storage → service (task service, config preview, etc.)
service + storage → api + web (HTTP handlers)
chi.Router → mounts api routes + UI
Device Communication
AgentClientproxies HTTP requests to device-siderk3588-agentvia the device's IP/port.- Two timeout tiers: 3s for normal requests, 120s for long operations (config apply, media server, model uploads).
- All proxied requests carry
X-RK-Tokenheader from config. - Generic passthrough:
r.Handle("/devices/{id}/v1/*", proxyAgentV1)covers agent sub-routes.
Config Asset Management
The system manages four asset types stored as JSON blobs in SQLite:
| Asset | Table | Key Concept |
|---|---|---|
| Templates | templates |
Base config template with bindings/variables |
| Profiles | profiles |
Template-specific configuration (references primary_template_name) |
| Overlays | overlays |
Named config overrides that can be appended to any profile |
| Integration Services | integration_services |
Third-party service definitions (e.g., RTMP, HTTP push) |
| Video Sources | video_sources |
Camera/stream source definitions |
Naming convention: names starting with std_ are read-only standard templates, imported on startup from templates/standard_templates/.
The config preview rendering pipeline: merge template + profile + overlays → resolve binding references (video sources, integration services) → expand slot tokens (${slot:name.field}) → compute SHA256 hash.
Background Goroutines
- RegistryService: 2s tick for offline pruning, 30s tick for graph polling
- DiscoveryService: UDP broadcast listener (blocking goroutine per discovery request)
- TaskService: concurrent task execution gated by a semaphore channel
Key Database Tables (SQLite, migrations in storage/migrate.go)
devices— device registry (device_id PK, ip, port, online status, last_seen)templates,profiles,overlays— config assetsintegration_services,video_sources— third-party service and video source definitionstasks+task_devices— batch task execution (type, status, per-device status)device_config_state— per-device applied config stateaudit_logs— action audit trail (actor, action, target, details)
Test Patterns
- Test files co-located with source:
*_test.go - Services constructed with nil/real dependencies (no mocking framework)
- HTTP tests use
httptest.NewRequest+httptest.NewRecorder - Storage tests use in-memory SQLite (tests seed their own data via repo methods)
- Tests assert on status codes, redirect URLs, and response body content
Coding Rules
- Never use
sedon Windows (Git Bash). It produces straytcharacters, broken indentation, and corrupted files. - Use
rgandfdfor searching (notgrep/find). Both are installed. - File editing: use the
writetool for new/rewritten files andedittool for precise changes. For complex find-and-replace, write a small temporary Go program. - No tabs: use spaces for indentation in all source files.
- No
fetch()in templates for page data — all API calls must go through Go server-side handlers. JS is only for UI interactivity (modals, carousels, confirm dialogs). - No inline
onclickwith complex quoting — usedata-*attributes + event delegation instead. - Use
pwshfor PowerShell commands (v7.6.1 in PATH, notpowershell.exe). - 重启服务:统一用
pwsh -File scripts/managerd.ps1 restart,它会先编译、停旧进程、再启动新进程并做健康检查。不要手动 kill + build + start。 - 如无必要,不使用数据库事务:SQLite 只允许一个写者,事务会阻塞所有其他写操作。单个
Exec已是原子操作,绝大多数场景不需要包裹事务。仅模板重命名等必须原子完成的多步操作才用事务。 - 调试时只加日志,不改代码:遇到 bug 先用
fmt.Printf全量打印关键路径的状态和数据流,定位根因后再动手修。不要猜测、不要加 workaround(重试、超时、锁之类)。 - UDP 仅用于设备发现:
dev.Online只用于 UI 指示灯,不做业务操作的准入判断。所有 agent HTTP 调用直接发出,由 HTTP 结果判断设备是否可达。 - 运行时配置持久化到文件:系统配置(告警保留天数、公司名称等)通过 UI 修改后写入
safesightd.json,配置模板safesightd.json.template为只读参考。
测试设备
- RK3588:
orangepi@10.0.0.81/ password:orangepi/ key:~/.ssh/id_ed25519_rk3588 - Agent:9100 / Media:9000 / Token:
4fe2d69fda23d0d5d04a1486d4920e68 - 详细命令参考 docs/test-devices.md