|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +Arena3D is a web application for interactive 3D visualization of multilayered networks: **FastAPI backend** (Python, `uv`) + **Vite / TypeScript / Three.js frontend** (npm). |
| 6 | + |
| 7 | +The app was migrated from R/Shiny to this stack. All R/Shiny source is gone; the migration history lives in: |
| 8 | +- **`SPEC.md`** — architecture decisions, chosen stack, design patterns, API contract, and rationale. |
| 9 | +- **`PLAN.md`** — phased implementation checklist (essentially complete). |
| 10 | +- **`MIGRATION.md`** — old R/Shiny file → new equivalent map (all rows done). |
| 11 | + |
| 12 | +## Rules for Agents |
| 13 | + |
| 14 | +- **Never push to remote.** Commit only when explicitly asked, one commit per feature. |
| 15 | +- **Always use the `token-saviour` skill** — and the tools/skills it routes to across its layers — wherever it makes sense. |
| 16 | +- **When a plan is active** (e.g. a `PLAN*.md` file): one feature per commit, tick the checkboxes as you go, and verify each feature at runtime before moving to the next. |
| 17 | +- **Before every commit**: run the build, lint, typecheck, and the relevant test suite (see commands below). Verify UI/UX changes at runtime with Playwright. |
| 18 | +- **Keep responses concise** — summarize rather than dumping full files, to stay within output token limits. |
| 19 | + |
| 20 | +## Running the App |
| 21 | + |
| 22 | +**Backend** (package management via `uv` — no manual venv/pip): |
| 23 | +```bash |
| 24 | +cd backend |
| 25 | +uv sync # installs deps + dev group into .venv |
| 26 | +uv run uvicorn app.main:app --reload # http://localhost:8000 |
| 27 | +``` |
| 28 | + |
| 29 | +**Frontend:** |
| 30 | +```bash |
| 31 | +cd frontend |
| 32 | +npm install |
| 33 | +npm run dev # http://localhost:5173 — /api proxied to localhost:8000 |
| 34 | +``` |
| 35 | + |
| 36 | +**Both together (Docker):** |
| 37 | +```bash |
| 38 | +docker-compose up |
| 39 | +``` |
| 40 | + |
| 41 | +**Backend tests:** |
| 42 | +```bash |
| 43 | +cd backend && uv run pytest |
| 44 | +``` |
| 45 | + |
| 46 | +**Frontend tests:** |
| 47 | +```bash |
| 48 | +cd frontend && npm test # Vitest unit tests |
| 49 | +cd frontend && npm run test:e2e # Playwright E2E |
| 50 | +``` |
| 51 | + |
| 52 | +**Lint / format / typecheck:** |
| 53 | +```bash |
| 54 | +cd backend && uv run ruff check . && uv run ruff format . && uv run mypy app |
| 55 | +cd frontend && npm run lint && npm run format && npx tsc --noEmit |
| 56 | +``` |
| 57 | + |
| 58 | +## Architecture Overview |
| 59 | + |
| 60 | +### Backend (`backend/app/`) |
| 61 | +Stateless FastAPI — the frontend holds all scene state; the server validates input and runs the graph algorithms. |
| 62 | + |
| 63 | +- `main.py` — app + router registration; `config.py` — constants (limits, palettes, scale targets) served at `GET /api/config`. |
| 64 | +- `models/` — Pydantic request/response models (`network`, `layout`, `topology`, `session`, `attributes`). |
| 65 | +- `routers/` — one per endpoint: `config`, `network` (TSV upload), `layout`, `topology`, `session` (import/export), `external` (token-shared sessions), `attributes` (node/edge attribute files). |
| 66 | +- `services/` — logic: `parser` (TSV parse/validate), `graph` (igraph construction + scopes), `layouts` (11 layout algos), `clustering` (4 community algos, optional layout step), `topology` (Degree / Clustering Coefficient / Betweenness), `session`, `attributes`. |
| 67 | +- Algorithms use **python-igraph** — same C core as R's igraph, so layouts/clustering/topology port 1:1. |
| 68 | + |
| 69 | +### Frontend (`frontend/src/`) |
| 70 | +- `main.ts` — entry point: fetch config → set up Three.js → mount canvas → wire panels + listeners → `animate()`. Exposes `window.__arena = { ctx, history }` as a Playwright test hook (the WebGL canvas is opaque to the a11y tree). |
| 71 | +- `three/` — `Scene`, `Layer`, `Node`, `Edge` classes on npm `three` r170; `runtime.ts` holds the shared mutable `ctx` (replaces v2 ambient globals); `constants.ts` static geometry/palette constants. |
| 72 | +- `actions/` — one module per domain (`network`, `layout`, `layer`, `node`, `edge`, `labels`, `themes`, `screen`, `canvas_controls`, `nav_controls`, `drag_controls`, `right_click_menu`, `session`). These mutate the object model + `ctx`. |
| 73 | +- `commands/` — `Command` interface + `CommandHistory` (undo/redo); `scene.ts` holds the concrete commands. Every scene mutation that should be undoable routes through a command. |
| 74 | +- `ui/` — one module per navbar panel (`home`, `file`, `layouts`, `scene`, `layer`, `node`, `edge`, `data`, `fps`, `help`), each filling its `#panel-*` pane with Bootstrap DOM and wiring controls to `actions`/`commands`. |
| 75 | +- `bus/` — typed `EventBus` singleton (returns unsubscribe fns); `store/` — typed `AppState` store. Together they replace the old Shiny input/output sync. |
| 76 | +- `api/client.ts` — hand-written typed client mirroring the Pydantic models. |
| 77 | + |
| 78 | +### Communication |
| 79 | +- **Frontend → backend**: `api.*` calls to `/api/*` (network parse, layout, topology, session, attributes). |
| 80 | +- **Within frontend**: components emit/subscribe on the `EventBus` and read/write the `store`; the render loop reacts to `ctx` flags (`renderInterLayerEdgesFlag`, label flags, etc.). |
| 81 | + |
| 82 | +### Network Data Model |
| 83 | +- Networks upload as TSV with mandatory columns `SourceNode`, `SourceLayer`, `TargetNode`, `TargetLayer` (optional: `Weight`, `Channel`, edge color columns). |
| 84 | +- Node/edge attribute files add per-node color/size/url/description and per-edge (optionally per-channel) color. |
| 85 | +- Sessions export/import as JSON with full node/edge/layer/scene state. `POST /api/external` returns a token URL so another app can hand off a session. |
0 commit comments