Sync project instructions with design v2: - Framework framing: top-level `projects` table, LOFT/OFFICE/… as separate projects, frames as sub-zones inside a project. - DB path moved from ~/.m/mcables.db to ./data/mcables.db (gitignored). - Frontend stack locked: vanilla JS modules + SVG, no build step, TypeScript types via JSDoc, Preact-via-CDN-ESM as fallback. - Deploy: raw docker on mDock under /home/m/stacks/mcables/ — explicitly NOT Dokploy. Port 7777, no reverse proxy, no auth (LAN-trusted). - mExDraw access: raw HTTP API (mcp__mexdraw__* not configured for this project), one-way export only. - Seed drawing reframed as visual-grammar reference, NOT a runtime import target. IO markers documented as wall-outlet terminators (type=Power), not inter-frame bridges. - Out-of-scope list updated: no auth, no inventory fields, no runtime import. Worker-preference slices re-aligned with the new design.
6.3 KiB
mCables — Project Instructions
Project Overview
Cable-management framework for m's setup. Each cable-managed environment
(LOFT, OFFICE, …) is a separate mCables project, and each project is
backed by exactly one Excalidraw drawing. The framework provides a visual
web interface backed by a Go HTTP API and SQLite, plus an export pipeline
that writes .excalidraw files via mExDraw.
Memory group_id: mcables
No CLI. Frontend-first — every interaction is through the visual
interface. The backend serves the UI and the API; there is no
mcables shell binary intended for humans.
Goal
- A reusable framework for tracking devices, ports, cables, cable types, bundles, frames — scoped per project (LOFT and OFFICE are separate projects, each a separate drawing).
- A visual editor in the browser: switch projects, add frames/devices/ports, click ports to wire up cables, pick cable types from a per-project legend.
- A one-way export from the DB to the corresponding
.excalidrawdrawing onmxdrw.msbls.dewhenever m clicks Export — DB is authoritative, Excalidraw is the projection. - Bundle detection: parallel cables along the same path within a project get grouped + colour-bundled in the diagram.
Architecture
| Layer | Tech | Notes |
|---|---|---|
| DB | SQLite | ./data/mcables.db (project-local, gitignored). Driver: modernc.org/sqlite (cgo-free). |
| Backend | Go | net/http HTTP API + static frontend via embed.FS. Standard library + minimal deps. Single binary. |
| Frontend | Vanilla JS modules + SVG, no build step | TypeScript types via JSDoc, optional tsc --noEmit in CI. Preact-via-CDN-ESM is the documented fallback if vanilla state gets painful — no build step either way. |
| Diagram I/O | mExDraw HTTP API | PUT https://mxdrw.msbls.de/api/drawings/<name>.excalidraw with Authorization: Bearer $MEXDRAW_TOKEN. (The mcp__mexdraw__* MCP tools are not currently configured for this project — workers use the raw HTTP API.) |
Hierarchy
- Project (
projectstable) is the top-level concept. LOFT, OFFICE, HOMELAB, … are separate projects. One project ↔ one.excalidrawdrawing in mExDraw. - Frames sub-divide a project (LOFT has
desk,rack,media; OFFICE hasdesk,server). Frames are not projects — they're zones within one drawing. - Every device, port, cable, cable type, IO marker, and bundle is
project-scoped (
project_iddenormalised onto every row, withON DELETE CASCADEfromprojects).
Branch Strategy
main= production-deployable.mai/<worker>/<slug>= worker branches via the mai workflow.- No
devbranch — too small a project for staging. - Merge with
--no-ffto main, delete branches after merge.
Tech Stack
- Go for the backend (matches m's other tools:
m,mai, youpcms, mExDraw). - SQLite via
modernc.org/sqlite(cgo-free → cleanscratch/distroless container, no toolchain pain). - mExDraw via HTTP for diagram export. Never edit raw
.excalidrawfiles directly outside the mExDraw API. - Vanilla JS + SVG for the frontend — no build step. JSDoc-typed.
Deployment — mDock, raw docker (NOT Dokploy)
mCables runs on mDock (192.168.178.131 on the LAN, Tailscale mdock)
as a plain docker-compose service. Dokploy is for public mlake/mRiver
stuff; mDock uses raw docker compose per the conventions of the existing
mDock services (mgreen, mgeo, msports-garmin, paperless, …).
- Repo layout on mDock:
/home/m/stacks/mcables/withdocker-compose.yml,data/bind-mount, secrets in/home/m/secrets/mcables/.env. - Image:
mgit.msbls.de/m/mcables:latest(built and pushed by a Gitea Actions workflow on push tomain, runs on the self-hosted runner on mDock with labelself-hosted:host). - Port mapping:
7777:7777, exposed on the LAN — no reverse proxy. - Restart policy:
unless-stopped. - LAN URL:
http://mdock:7777. - No auth — LAN-trusted.
Local dev (no Docker): go run ./cmd/mcables against ./data/mcables.db.
Seed drawing — visual grammar reference, not a runtime importer
mxdrw.msbls.de/draw/Cable-Management.excalidraw is reference material
only. mCables does not auto-ingest it. m will rebuild LOFT and OFFICE
from scratch inside the tool — the seed exists so the exporter mimics
its visual grammar:
- Devices = rectangles with a text label.
- Ports = small ellipses (~12×9) positioned on a device edge. Positional, not containerId-bound. Stroke colour = cable type.
- Cables = arrows with
startBinding/endBindingto ports or devices or IO diamonds. - Cable types = colour, with a legend at the top-left of the project's first frame listing the project's cable_types.
- IO markers = small diamonds. Semantically wall outlets / power entry points — a cable terminating at an IO marker means "this end is plugged into a wall socket outside the diagram". They are not inter-frame bridges and they do not pair up.
- Frames = sub-zones inside a project (
desk,rack,media, …). - Lines = decorative only (legend separators in the seed). Ignored on export.
Legend colours (per-project default seed when a project is created):
| Type | Hex |
|---|---|
| Power | #e03131 |
| USB | #2f9e44 |
| HDMI | #1971c2 |
| DP | #9c36b5 |
| RJ45 | #ffd500 |
Out of scope (v0)
- Multi-user. mCables is m-only.
- Auth / sharing — LAN-trusted on mDock.
- Mobile / responsive — desktop browser only.
- Cable inventory beyond visual structure (no length, no purchase history, no SKU). Strictly visual structure for v0.
- Import from
.excalidrawat runtime. If a one-shot migration is ever needed, a separatemcables-migrateCLI tool is the right shape, not a hot API endpoint.
Worker Preferences
- First shift = inventor (design pass): conventions, schema, API,
export pipeline, mDock deploy plan, UI flows, slices. Output:
docs/design.md+ open questions for m. - Second shift = coder (after m's go on the design): bootstrap repo skeleton (Go module, SQLite migrations, server, exporter, frontend scaffold). Take slices 1–4 first (project CRUD, frames/devices, ports and cables, IO + cable-type editing); slice 5 (Excalidraw export) closes the round-trip.
- Use Sonnet for both — greenfield, structure matters more than depth.