Adds Workers + static-assets configs for the app (app.diagrav.com) and a separate marketing/landing site (diagrav.com), plus the deployment runbook used to stand up Supabase Cloud, Google OAuth, Resend SMTP, and Cloudflare DNS/custom domains. Renames the app from "AV Planner" to "Diagrav" to match the new domain. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
66 lines
2.8 KiB
Markdown
66 lines
2.8 KiB
Markdown
# Diagrav
|
|
|
|
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](https://reactflow.dev)** (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. `DiagramRepository` is the interface the
|
|
rest of the app codes against; `SupabaseDiagramRepository` is
|
|
the active implementation, with `LocalStorageDiagramRepository`
|
|
kept as a reference/fallback. Swapping storage means adding
|
|
one new implementation of that interface, not touching
|
|
state/UI code.
|
|
state/ Zustand store (`diagramStore`) — the single source of truth for
|
|
the current diagram. 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` and seed the public catalog;
|
|
custom ones are your own private catalog entries (or submitted for public
|
|
review).
|
|
- **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).
|
|
- **Diagram** — devices + connections. This is the one object persisted
|
|
(auto-saved to Supabase, or explicitly exported/imported as JSON); the
|
|
catalog (PortType/CableType/DeviceTemplate/category) is shared and global,
|
|
not part of any one diagram.
|
|
|
|
## Development
|
|
|
|
```bash
|
|
npm install
|
|
npm run dev # start the dev server
|
|
npm run build # typecheck + production build
|
|
npm run lint # oxlint
|
|
```
|