1ae967c8a40a5a0af39a47c092e3534d8e648699
- DiagramRepository (renamed from ProjectRepository, per the organized-ideas.md §8 naming decision) now has a Supabase-backed implementation as the active repository. LocalStorageDiagramRepository stays in the codebase as a reference implementation / fallback, just no longer wired in. Only the storage layer's naming changed here -- the domain type, store, and UI copy still say "Project"; that's a separate, larger mechanical rename tracked on its own. - Minimal email/password auth gate (src/components/auth/LoginScreen.tsx) since Supabase RLS requires a real signed-in user to do anything -- this is NOT the Phase 2 experience (Google SSO, polished signup), just enough of the same schema (username + email + password) to make the backend foundation usable end to end before that phase exists. Respects the hard email-verification gate from config.toml. - .env.example documents the required VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY (local dev values, not secrets); .env.local has the actual local values and is gitignored. Verified end-to-end against the local stack: signup creates a confirmed-pending user, the handle_new_user trigger creates their profile, sign-in is blocked until confirmed, and a signed-in session can upsert/read back its own diagram row exactly as the app's save()/load() do it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
AV Planner
Plan out AV/network installs: define devices and their ports, wire them together on a canvas, and get a bill of materials (devices + cables, with lengths) for what you'll need to buy.
Stack
- React 19 + TypeScript + Vite
- @xyflow/react (React Flow) for the device/wiring canvas
- Zustand for app state
- Tailwind CSS v4 for styling
Architecture
src/
domain/ Framework-agnostic types + logic (compatibility rules, BOM math,
the built-in connector/cable/device library). No React, no
React Flow — safe to unit test or reuse from a future backend.
data/ Storage abstraction. `ProjectRepository` is the interface the
rest of the app codes against; `LocalStorageProjectRepository`
is the only implementation today. Swapping in a real backend
later (REST/GraphQL) means adding one new implementation of
that interface, not touching state/UI code.
state/ Zustand store (`projectStore`) — the single source of truth for
the current project. Auto-saves to the repository (debounced)
on every change.
components/
canvas/ React Flow wiring surface: custom device node, custom cable
edge, connection validation.
palette/ Device library sidebar + the "new custom device" editor.
inspector/ Right-panel editors for the selected device or cable.
bom/ Bill-of-materials view.
layout/ App shell, top bar, panels.
Data model
- PortType — a connector kind (HDMI, XLR, Cat5e/6, ...). Two ports can be
wired together only if their PortTypes share a compatibility
family. - DeviceTemplate — a reusable device shape (its ports), shown in the
palette. Built-ins live in
domain/library.ts; custom ones are saved on the project. - Device — an instance placed on the canvas, with its own copy of ports (editing an instance never mutates its template).
- CableType — a physical cable spec, scoped to a PortType family.
- Connection — a wire between two ports, referencing a CableType and an optional user-entered distance (there's no floor plan / scale model, so length is a manual estimate per connection).
- Project — devices + connections + any custom library entries. This is
the one object persisted (auto-saved to
localStorage, or explicitly exported/imported as JSON).
Development
npm install
npm run dev # start the dev server
npm run build # typecheck + production build
npm run lint # oxlint
Languages
TypeScript
79.7%
PLpgSQL
16.3%
HTML
1.6%
JavaScript
1.3%
CSS
1.1%