Phase 2: device registry, dashboard cards, manual lock/unlock, audit
- Device registry: add/edit name, child and platform, persisted in devices. - Stable per-device topic derived from name + id, unchanged by renames. - Desired state persisted in state; timed locks expire and are audited. - Dashboard cards: name, child, platform, status dot, state and time left. - Manual lock/unlock forms with CSRF; every change appends to audit (FR-15). - Append-only activity list on the dashboard. No hard deletes (rule 10). - Store and handler tests; version bumped to 0.2.0-phase2. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
39
README.md
39
README.md
@@ -5,7 +5,8 @@ Internet Use Control project (`SYSTEM_MAP.md`). It holds schedules, blocklists,
|
||||
per-device state and usage, and serves the web dashboard. Only it publishes
|
||||
device config.
|
||||
|
||||
This repository currently contains **Phase 1 — Skeleton** (AGENTS.md §11):
|
||||
This repository currently contains **Phase 2 — Devices and state**
|
||||
(AGENTS.md §11), on top of the Phase 1 skeleton:
|
||||
|
||||
- Go service with its own image (`Dockerfile`) and compose file.
|
||||
- SQLite schema for the whole data model (§7), applied through versioned
|
||||
@@ -16,9 +17,14 @@ This repository currently contains **Phase 1 — Skeleton** (AGENTS.md §11):
|
||||
- `GET /health`.
|
||||
- HTMX + server-rendered dashboard styled with the Family Home Lab design
|
||||
system (`tokens.css` copied in).
|
||||
- **Device registry**: add and edit a device, assign it to a child, choose its
|
||||
platform. Persisted in `devices`.
|
||||
- **Dashboard cards**: name, child, platform, status, current state, time left.
|
||||
- **Manual lock/unlock** from the dashboard, persisted in `state` and written
|
||||
to the append-only `audit` log (FR-15).
|
||||
|
||||
Enforcement, MQTT, devices, schedules and the clients arrive in later phases.
|
||||
Nothing here touches the router, Pi-hole, or DNS.
|
||||
Enforcement, MQTT, schedules, blocklists and the clients arrive in later
|
||||
phases. Nothing here touches the router, Pi-hole, or DNS.
|
||||
|
||||
## Quick start (on `.13`)
|
||||
|
||||
@@ -34,7 +40,7 @@ docker compose up -d --build
|
||||
|
||||
# 3. Prove it.
|
||||
curl -s http://127.0.0.1:8791/health
|
||||
# {"status":"ok","service":"control-service","version":"0.1.0-phase1",...}
|
||||
# {"status":"ok","service":"control-service","version":"0.2.0-phase2",...}
|
||||
```
|
||||
|
||||
Open <http://127.0.0.1:8791/> in a browser. It redirects to `/login`. Sign in
|
||||
@@ -63,11 +69,11 @@ reads only the process environment.
|
||||
Generate a bcrypt hash without host Go:
|
||||
|
||||
```bash
|
||||
docker run --rm --entrypoint /app/control webrestrict/control:0.1.0-phase1 \
|
||||
docker run --rm --entrypoint /app/control webrestrict/control:0.2.0-phase2 \
|
||||
hash-password 'your-password'
|
||||
```
|
||||
|
||||
## Endpoints (Phase 1)
|
||||
## Endpoints (Phase 2)
|
||||
|
||||
| Method | Path | Notes |
|
||||
|---|---|---|
|
||||
@@ -75,8 +81,17 @@ docker run --rm --entrypoint /app/control webrestrict/control:0.1.0-phase1 \
|
||||
| `GET` | `/login` | Session login form. |
|
||||
| `POST` | `/login` | Verifies credentials, sets a signed session cookie. |
|
||||
| `POST` | `/logout` | Clears the session. |
|
||||
| `GET` | `/` | Dashboard. Redirects to `/login` when not signed in. |
|
||||
| `GET` | `/` | Dashboard: service status, device cards, recent activity. |
|
||||
| `GET` | `/partials/status` | HTMX fragment, polled every 10 s. |
|
||||
| `GET` | `/devices/new` | Add-device form. |
|
||||
| `POST` | `/devices` | Creates a device. |
|
||||
| `GET` | `/devices/{id}/edit` | Edit-device form. |
|
||||
| `POST` | `/devices/{id}` | Updates name, child, platform. |
|
||||
| `POST` | `/devices/{id}/lock` | Locks now; optional `minutes` (0 = until unlocked). |
|
||||
| `POST` | `/devices/{id}/unlock` | Unlocks now. |
|
||||
|
||||
Every form POST needs the `csrf` field from the session cookie. State changes
|
||||
append to the `audit` table. Devices are never hard-deleted (§10 rule 10).
|
||||
|
||||
## Development
|
||||
|
||||
@@ -95,11 +110,12 @@ make logs # follow container logs
|
||||
```
|
||||
cmd/control/ service entry point (+ hash-password helper)
|
||||
internal/config/ environment configuration
|
||||
internal/store/ SQLite open, migrations, audit
|
||||
internal/store/ SQLite open, migrations, audit, devices + state
|
||||
internal/store/migrations/001_init.sql
|
||||
internal/auth/ signed-cookie session login + CSRF
|
||||
internal/web/ HTTP handlers, templates, static assets
|
||||
templates/ login, dashboard, HTMX partials
|
||||
devices.go device registry + manual lock/unlock handlers
|
||||
templates/ login, dashboard, device form, HTMX partials
|
||||
static/ tokens.css (Family Home Lab), app.css, htmx, Inter fonts
|
||||
Dockerfile own image (multi-stage, CGO-free)
|
||||
docker-compose.yml own container, port 8791
|
||||
@@ -113,9 +129,10 @@ deploy/caddy/ Caddy vhost for webrestrict.lab.audasmedia.com.au
|
||||
`webrestrict.lab.audasmedia.com.au`. The terminating Caddy runs on `.35`
|
||||
(sam-Ubuntu1); see that file for the two proxy patterns and the apply commands.
|
||||
|
||||
## Non-goals (Phase 1)
|
||||
## Non-goals (Phase 2)
|
||||
|
||||
- No MQTT publishing (Phase 3).
|
||||
- No device registry or lock/unlock UI (Phase 2).
|
||||
- No schedules, blocklists or allowlists (Phase 6).
|
||||
- No telemetry or usage screens (Phase 7).
|
||||
- No admin API (Phase 8).
|
||||
- No Hub contact (Phase 9).
|
||||
|
||||
Reference in New Issue
Block a user