Full project rename per m's call. Single atomic commit because the codebase rename is a coupled change — go module path, env vars, DB default, Docker artefact names, and on-disk mDock paths all flip together. - go.mod: module mgit.msbls.de/m/mcables → mgit.msbls.de/m/cablegui - cmd/mcables → cmd/cablegui (git mv) - All Go imports rewritten to the new module path - Env vars: MCABLES_ADDR/MCABLES_DB → CABLEGUI_ADDR/CABLEGUI_DB - DB default path: data/mcables.db → data/cablegui.db - Dockerfile + docker-compose.yml: image, container_name, env vars, bind-mount /home/m/stacks/mcables → /home/m/stacks/cablegui, secrets /home/m/secrets/mcables → /home/m/secrets/cablegui - Makefile: bin target + run/build commands point at cmd/cablegui - .gitignore + .dockerignore: /mcables → /cablegui - README, docs/design.md, CLAUDE.md: prose + paths + image name - web/static/index.html: <title> + brand - web/static/main.js + web/web.go: header comment - internal/exporter: Scene.Source "mcables" → "cablegui" - internal/server/export.go: error-detail secrets path - internal/db/migrations/*.sql: header comments (mCables vN → CableGUI vN) Memory group_id kept as "mcables" to preserve existing memory continuity. Documented as historical in CLAUDE.md. go build ./... clean; go test -race ./... green
155 lines
5.1 KiB
Markdown
155 lines
5.1 KiB
Markdown
# CableGUI
|
|
|
|
Cable-management **framework** for m's setup — visual web editor backed by
|
|
a single Go binary + SQLite, generating Excalidraw drawings via mExDraw.
|
|
|
|
Each cable-managed environment (LOFT, OFFICE, …) is a separate CableGUI
|
|
*project*; each project is backed by exactly one `.excalidraw` drawing on
|
|
mxdrw.msbls.de.
|
|
|
|
## Status
|
|
|
|
Slice 1 — bootstrap shipped. Projects + global cable types are
|
|
end-to-end; the SVG canvas is intentionally empty until slice 2.
|
|
|
|
| Slice | What's in it | Status |
|
|
|---|---|---|
|
|
| 1 | Project CRUD, global cable types, empty SVG canvas, project picker | ✅ |
|
|
| 2 | Frames + devices, drag-to-position | pending |
|
|
| 3 | Ports + cables (click-port → click-port) | pending |
|
|
| 4 | IO markers + cable-type editing | pending |
|
|
| 5 | Export to mxdrw.msbls.de | pending |
|
|
|
|
## Run it
|
|
|
|
```sh
|
|
go run ./cmd/cablegui
|
|
# open http://localhost:7777
|
|
```
|
|
|
|
Or built:
|
|
|
|
```sh
|
|
make build
|
|
./bin/cablegui
|
|
```
|
|
|
|
The binary serves the frontend from an embedded `web/static/` and the
|
|
JSON API under `/api/`. SQLite lives at `./data/cablegui.db` by default.
|
|
|
|
### Environment
|
|
|
|
| Var | Default | Notes |
|
|
|---|---|---|
|
|
| `CABLEGUI_ADDR` | `0.0.0.0:7777` | Listen address. |
|
|
| `CABLEGUI_DB` | `./data/cablegui.db` | SQLite path. Parent dir is created on boot. |
|
|
| `MEXDRAW_BASE_URL` | `https://mxdrw.msbls.de` | Base URL for mExDraw export. |
|
|
| `MEXDRAW_USER` | (unset) | Username for the mxdrw HTTP Basic Auth on export. Required. |
|
|
| `MEXDRAW_PASS` | (unset) | Password for the mxdrw HTTP Basic Auth on export. Required. |
|
|
|
|
### Tests
|
|
|
|
```sh
|
|
make test # go test -race ./...
|
|
```
|
|
|
|
Store-level tests cover projects + cable-types CRUD, the
|
|
`drawing_name` auto-default, the `?confirm=<name>` guardrail on
|
|
`DELETE /api/projects/:pid`, and the `ON DELETE RESTRICT` on a
|
|
referenced cable type.
|
|
|
|
## API (slice 1)
|
|
|
|
```
|
|
GET /api/healthz → 200 {"status":"ok"}
|
|
|
|
GET /api/projects → [Project, …]
|
|
POST /api/projects ← {name, drawing_name?, description?}
|
|
drawing_name defaults to "<name>.excalidraw"
|
|
GET /api/projects/:pid → {project, cable_types, frames, devices, …}
|
|
PATCH /api/projects/:pid ← partial
|
|
DELETE /api/projects/:pid?confirm=<name> ← confirm must equal current name
|
|
|
|
GET /api/cable-types → [CableType, …] (global)
|
|
POST /api/cable-types ← {name, color}
|
|
PATCH /api/cable-types/:id ← partial — affects every project
|
|
DELETE /api/cable-types/:id ← 409 in_use if any cable references it
|
|
```
|
|
|
|
## Deploy to mDock
|
|
|
|
CableGUI runs on **mDock** at `http://mdock:7777` as a docker-compose
|
|
service under `/home/m/stacks/cablegui/`. Pattern matches the other
|
|
mDock services (mgreen-journal, mgeo, msports-garmin, …) — no Dokploy,
|
|
no reverse proxy, LAN-trusted.
|
|
|
|
### Manual deploy
|
|
|
|
1. **Build + push the image** (image now lives under `m/` in Gitea):
|
|
|
|
```sh
|
|
docker build -t mgit.msbls.de/m/cablegui:latest .
|
|
awk '/machine mgit.msbls.de/{getline; getline; print $2}' ~/.netrc \
|
|
| docker login mgit.msbls.de -u m --password-stdin
|
|
docker push mgit.msbls.de/m/cablegui:latest
|
|
```
|
|
|
|
2. **Prepare directories on mDock** (one-time):
|
|
|
|
```sh
|
|
ssh mdock 'mkdir -p /home/m/stacks/cablegui/data /home/m/secrets/cablegui \
|
|
&& touch /home/m/secrets/cablegui/.env \
|
|
&& chmod 0600 /home/m/secrets/cablegui/.env'
|
|
scp docker-compose.yml mdock:/home/m/stacks/cablegui/docker-compose.yml
|
|
```
|
|
|
|
3. **Pull + start**:
|
|
|
|
```sh
|
|
ssh mdock 'cd /home/m/stacks/cablegui && docker compose pull && docker compose up -d'
|
|
```
|
|
|
|
4. **Verify** from any LAN host:
|
|
|
|
```sh
|
|
curl http://mdock:7777/api/healthz # → {"status":"ok"}
|
|
curl http://mdock:7777/api/cable-types # → the 5 seeded types
|
|
```
|
|
|
|
To **update** to a new build: rebuild + push the image, then
|
|
`ssh mdock 'cd /home/m/stacks/cablegui && docker compose pull && docker compose up -d'`.
|
|
|
|
### Persistence
|
|
|
|
SQLite lives at `/home/m/stacks/cablegui/data/cablegui.db` on the host
|
|
(bind-mounted into the container at `/app/data`). Container runs as
|
|
UID 1000:1000 to align with `m:m` ownership on mDock — DB files end
|
|
up owned by `m`, the host user.
|
|
|
|
`docker compose restart` keeps the data intact (tested 2026-05-15).
|
|
|
|
### Automation — follow-up task
|
|
|
|
This first roll is **manual**. A Gitea Actions workflow on the
|
|
self-hosted runner already on mDock (`/home/m/act-runner/`, label
|
|
`self-hosted:host`) — build → push → `docker compose up -d` on every
|
|
push to `main` — is a separate task per the design's §10. Tracking
|
|
spawned by the head if/when wanted.
|
|
|
|
## Design + project conventions
|
|
|
|
- `docs/design.md` — full v3 design (schema, API, importer/export
|
|
conventions, slices, mDock deploy notes).
|
|
- `CLAUDE.md` — project instructions for mai workers.
|
|
|
|
## Architecture
|
|
|
|
| Layer | Tech |
|
|
|---|---|
|
|
| DB | SQLite via `modernc.org/sqlite` (cgo-free), WAL, FKs on |
|
|
| Backend | Go 1.22+ `net/http` ServeMux pattern routing, single binary |
|
|
| Frontend | Vanilla ES modules + SVG, no build step, embedded via `embed.FS` |
|
|
| Export (slice 5) | mExDraw HTTP API on mxdrw.msbls.de |
|
|
|
|
LAN-trusted, no auth.
|