Files
ledgrab/server/CLAUDE.md
T
alexei.dolgolyov 12b40e6071 docs: actualize README and API reference, embed screenshots
README: add free & open-source (MIT) framing; add a Platforms table (Windows/Linux/macOS/Docker supported, Android-TV build marked experimental, scrcpy phone-capture retained); expand the LED device list to ~20 protocols; correct storage to SQLite, the auth model, and resource names (Output Targets, Automations); add a prebuilt-download section; remove the Architecture and Acknowledgments sections; embed dashboard, channels, live-preview, and device-picker screenshots.

docs/API.md: full rewrite from the live route modules — all 253 endpoints across 34 modules, grouped by resource with REST + WebSocket tables, accurate auth model and WS handshake, worked examples, and sensitive-endpoint markers. Replaces the stale v0.1.0 stub.

server/CLAUDE.md: storage is now SQLite (BaseSqliteStore / ledgrab.db / LEDGRAB_DATA_DIR / data_migrations.py); fix the auth description (loopback anonymous, LAN rejected with 401 — not all endpoints open); router registration happens in api/__init__.py.
2026-05-29 14:35:45 +03:00

80 lines
4.1 KiB
Markdown

# Claude Instructions for LedGrab Server
## Project Structure
- `src/ledgrab/main.py` — FastAPI application entry point
- `src/ledgrab/api/routes/` — REST API endpoints (one file per entity)
- `src/ledgrab/api/schemas/` — Pydantic request/response models (one file per entity)
- `src/ledgrab/core/` — Core business logic (capture, devices, audio, processing, automations)
- `src/ledgrab/storage/` — Data models (dataclasses) and SQLite-backed persistence stores (`BaseSqliteStore`)
- `src/ledgrab/utils/` — Utility functions (logging, monitor detection, SSRF validation, sound playback)
- `src/ledgrab/static/` — Frontend files (TypeScript, CSS, locales)
- `src/ledgrab/templates/` — Jinja2 HTML templates
- `config/` — Configuration files (YAML)
- `data/` — Runtime data: SQLite database (`ledgrab.db`) + assets. Relocate the root with `LEDGRAB_DATA_DIR`.
## Entity & Storage Pattern
Each entity follows: dataclass model (`storage/`) + SQLite store (`storage/*_store.py`, subclassing `BaseSqliteStore`) + Pydantic schemas (`api/schemas/`) + routes (`api/routes/`).
Stores keep an in-memory write-through cache over a per-entity SQLite table (the legacy `BaseJsonStore` still exists for reference but new stores use `BaseSqliteStore`). Schema/data shape changes go through `storage/data_migrations.py` — migrations are idempotent and tracked in a dedicated `data_migrations` audit table, so they run safely on every startup. **When renaming or restructuring stored fields, add a migration there** (see the Data Migration Policy in the root `CLAUDE.md`).
## Authentication
API key authentication via Bearer token in the `Authorization` header (`Authorization: Bearer <key>`). WebSocket connections authenticate with a first-message handshake (`{"type":"auth","token":"<key>"}`). See `src/ledgrab/api/auth.py` for the canonical logic.
- Config: `config/default_config.yaml` under `auth.api_keys`; env var `LEDGRAB_AUTH__API_KEYS`
- When `api_keys` is **empty** (default): **loopback** requests (`127.0.0.1` / `::1` / `localhost`) are allowed anonymously, but **LAN / remote** requests are rejected with `401`. Auth is *not* fully open.
- When `api_keys` is **set**: a valid Bearer token is required from every client (loopback included).
- `require_authenticated()` rejects even loopback-anonymous callers on sensitive endpoints (e.g. backup download, secret reveal).
## Common Tasks
### Adding a new API endpoint
1. Create route file in `api/routes/` (define an `APIRouter(prefix="/api/v1/...")`)
2. Define request/response schemas in `api/schemas/`
3. Register the router in `api/__init__.py` (it aggregates every route module into the single `router` that `main.py` mounts)
4. Restart the server
5. Test via `/docs` (Swagger UI)
### Adding a new field to existing API
1. Update Pydantic schema in `api/schemas/`
2. Update corresponding dataclass in `storage/`
3. Update backend logic to populate the field
4. Restart the server
5. Update frontend to display the new field
6. Rebuild bundle: `cd server && npm run build`
### Adding translations
1. Add keys to `static/locales/en.json`, `static/locales/ru.json`, and `static/locales/zh.json`
2. Add `data-i18n` attributes to HTML elements in `templates/`
3. Use `t('key')` in TypeScript modules (`static/js/`)
4. No server restart needed (frontend only), but rebuild bundle if JS changed
### Modifying display/monitor detection
1. Update functions in `utils/monitor_names.py` or `core/screen_capture.py`
2. Restart the server
3. Test with `GET /api/v1/config/displays`
## Testing
```bash
cd server && pytest # Run all tests
cd server && pytest --cov # With coverage report
cd server && pytest tests/test_api.py # Single test file
```
Tests are in `server/tests/`. Config in `pyproject.toml` under `[tool.pytest]`.
## Frontend Conventions
For all frontend conventions (CSS variables, UI patterns, modals, localization, icons, bundling), see [contexts/frontend.md](../contexts/frontend.md).
## Server Operations
For restart procedures, server modes, and demo mode checklist, see [contexts/server-operations.md](../contexts/server-operations.md).