safesight-control/CLAUDE.md
tian 84b8b1c65a fix: remove transactions causing SQLITE_BUSY, add coding rules
- persistTask: 去掉事务,每个 Exec 原子即可
- saveAsset(profiles): 去掉事务,profile 和 units 分步保存
- CLAUDE.md: 加两条规则——不用事务除非必要;调试只加日志不改代码
2026-05-12 16:43:44 +08:00

6.0 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Build, Test & Restart Commands

  • Build: go build -o managerd ./cmd/managerdpwsh -File scripts/managerd.ps1 build
  • Run: ./managerd (uses managerd.json config) 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

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

  • AgentClient proxies HTTP requests to device-side rk3588-agent via 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-Token header 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 assets
  • integration_services, video_sources — third-party service and video source definitions
  • tasks + task_devices — batch task execution (type, status, per-device status)
  • device_config_state — per-device applied config state
  • audit_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 sed on Windows (Git Bash). It produces stray t characters, broken indentation, and corrupted files.
  • Use rg and fd for searching (not grep/find). Both are installed.
  • File editing: use the write tool for new/rewritten files and edit tool 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 onclick with complex quoting — use data-* attributes + event delegation instead.
  • Use pwsh for PowerShell commands (v7.6.1 in PATH, not powershell.exe).
  • 重启服务:统一用 pwsh -File scripts/managerd.ps1 restart,它会先编译、停旧进程、再启动新进程并做健康检查。不要手动 kill + build + start。
  • 如无必要,不使用数据库事务SQLite 只允许一个写者,事务会阻塞所有其他写操作。单个 Exec 已是原子操作,绝大多数场景不需要包裹事务。仅模板重命名等必须原子完成的多步操作才用事务。
  • 调试时只加日志,不改代码:遇到 bug 先用 fmt.Printf 全量打印关键路径的状态和数据流,定位根因后再动手修。不要猜测、不要加 workaround重试、超时、锁之类

测试设备

  • RK3588: orangepi@10.0.0.81 / password: orangepi / key: ~/.ssh/id_ed25519_rk3588
  • Agent:9100 / Media:9000 / Token:4fe2d69fda23d0d5d04a1486d4920e68
  • 详细命令参考 docs/test-devices.md