Tight pass on m's review of v4 (single commit per head's instruction).
Six locked answers integrated:
1. mCables is a schematic, not a physical-routing tool. Stripped
'trunk', 'frame-edge corridor', 'cable tray', 'path optimisation'
from §5b.1, §5b.2, §7, §8, §9. Bundling reduces to the v3 endpoint-
pair rule: ≥2 cables between the same A↔B endpoint pair → group as
one bundle. Anything path-shaped is "out of scope, period" (§8).
2. Solver button-only for v0 (no change). Live-solve parked at 9+.
3. Unmet-requirement quick-fix: red badge on the affected device in the
inspector with a single "+ Add <type> port to <device> and re-solve"
button per §5b.4. New endpoint
POST /api/projects/:pid/devices/:id/ports-and-resolve chains the
port insert + the solve re-run in one transaction.
4. Setup templates fold INTO v4.1. New §2.4 with the schema for
setup_templates + setup_template_devices + setup_template_requirements
(migration 004), 3 built-in templates seeded (Living Room, Home
Office, Server Rack). New API: GET /api/setup-templates,
POST /api/projects/:pid/apply-template. New UI flow: "or start from
a template" section in the New Project modal + an "Apply template"
action on empty projects. Built-in catalog grows to 14 types
(adds Screen, Keyboard, Mouse).
5. Catalog SQL seed in migration 002 (no change).
6. Promote-to-manual: explicit button on cable inspector (no change).
§8 slice 6 absorbs the templates work alongside the solver MVP.
§9 closes all six v4 questions; no open design questions remain.
Trailer changes to "DESIGN v4.1 READY FOR REVIEW".
CLAUDE.md mirrors: schematic-only framing, 14-type catalog, setup
templates as a first-class feature, quick-fix UX note.
Big rescope driven by m's product-vision clarification: mCables is a
cable-management framework with a solver as its core value prop, not a
manual draw-and-click editor. m declares devices + required connections
between them; the solver emits the cable plan + bundle recommendations,
optimising for maximum bundling.
Schema additions (migrations 002 + 003):
- device_types (catalog) — built-ins (project_id NULL) + project-custom
(project_id non-null). 11 built-in types seeded with default port
profiles (NAS, PC, Mac, TV, Soundbar, Switch, fritz, ChromeCast,
SteamLink, IOx-3/6/8, Notebook).
- device_type_ports (profile rows: cable_type × count × edge).
- devices.type_id (nullable). Picking a type seeds ports once;
instance-owned thereafter (no retroactive re-seed).
- connection_requirements (per-project, from/to device + preferred type
+ must_connect flag, with order-normalised pair_lo/pair_hi for
duplicate prevention).
- cables.auto (slice 5.5 migration) — distinguishes solver-owned cables
from user-drawn ones.
API additions:
- GET /api/device-types (built-ins only, read-only) and
GET /api/projects/:pid/device-types (built-ins + project-custom merged)
- POST/PATCH/DELETE under /api/projects/:pid/device-types (project-custom
only; built-ins are 403)
- /api/projects/:pid/connection-requirements full CRUD
- POST /api/projects/:pid/solve with ?preview=1 — pure-function solver
(greedy port allocation, endpoint-pair bundling for v0); returns
add[], remove[], bundles_added[], unsatisfied[], warnings[]
Solver algorithm (§5b):
- Read project devices + ports + connection_requirements + manual cables
- Assign each requirement a (port_a, port_b) using the preferred cable
type (or auto-pick if exactly one type matches both ends)
- Bundle by endpoint-pair (v3 rule, applied to auto cables only)
- Surface unsatisfied requirements per class (no compat type / ambiguous
type / no free port) — does NOT auto-add ports; UI quick-fix instead
- ?preview=1 returns the diff without writing; default applies in a tx
UI additions:
- Device-create modal: type dropdown (built-ins grouped by kind, then
project-custom, then "Custom (no type)" for the v3 freeform fallback)
- Left-sidebar Requirements section with + Requirement button
- Header Solve button (S keybinding) → preview modal → Apply
- Inspector for selected device: type, ports grid, unmet requirements
with red badges + quick-fix actions
- Inspector for selected auto cable: driving requirement, parent bundle,
Promote-to-manual button
Slice reshape (§8):
- Slices 1, 2 shipped. v4 inserts: 4 = catalog + type-aware device create,
4.5 = catalog management, 5 = requirements CRUD + UI, 6 = solver MVP +
Solve button. Old "manual port + manual cable draw" slides to slice 7
as a tweak path on solver output. Export becomes slice 8.
Six new open questions (§9) for m to gate before slice 4:
1. Path source (auto-route through frame edges / user cable-trays /
Steiner-tree)?
2. Live-solve vs. button-only?
3. UX when solver has no compatible port pair?
4. Setup templates in v4 or post-MVP?
5. Catalog as code seed or JSON file?
6. Auto-promote vs. explicit Promote-to-manual on solver cable edits?
CLAUDE.md updated to reflect the solver-core framing, hybrid catalog,
connection-requirements model, and auto/manual cable distinction.
Trailer changes to "DESIGN v4 READY FOR REVIEW".
Tight pass on round-4 answers (single commit per head's request):
- cable_types is GLOBAL — drop project_id, UNIQUE(name). Migration 001
seeds the 5 defaults once; POST /api/projects no longer seeds them.
API moves to top-level /api/cable-types. Renaming/recolouring affects
every project. CASCADE from projects does not touch cable_types.
- devices: UNIQUE (project_id, name) added.
- projects: drawing_name defaults to "<name>.excalidraw" server-side
on POST when omitted; editable via PATCH.
- DELETE /api/projects/:pid requires ?confirm=<name>; server checks
name match, returns 400 if missing or mismatched.
- io_markers: no type_id (Power-by-convention, UI soft-warn). Confirmed
v0 stance.
- Bundles ignored on export — carries over from v2.
- §0 changelog rewritten as "what changed in v3 / what carried over".
- §2 schema rewritten; FK-shape paragraph updated to call out the one
global table.
- §3 endpoints: cable-types moved to top level; POST/DELETE projects
show new defaults + guardrail semantics.
- §4 export table notes cable_types pulled from global.
- §7 "edit cable type" flow gains the cross-project-effect banner +
ON DELETE RESTRICT inline-error UX.
- §8 slice 1 rewritten: no per-project seeding; legend reads global.
- §9 all six v2 questions marked resolved with the v3 answer per item.
- Trailer changes to "DESIGN v3 READY — coder shift gated".
- CLAUDE.md mirrors: global cable_types, device UNIQUE per project,
drawing_name default, delete guardrail.
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.