homeos/CLAUDE.md

62 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# CLAUDE.md — HomeOS
Self-built smart-home control plane. Single household, self-hosted, LAN-first.
**Not** Home Assistant / not a wrapper: own data model, own integrations, own UI.
Authoritative build spec: **`handoff.md`**. Non-negotiable conventions: **`rules.md`**.
Approved design direction: **`design-mockup.html`** (open in a browser).
Read all three before non-trivial work.
## Locked decisions (see handoff §12)
- **Framework:** Laravel 13 · **Livewire v3** class-based (NOT Volt) · **Tailwind v4** (CSS-first `@theme`, no `tailwind.config.js`) · Vite
- **DB:** PostgreSQL 17 + TimescaleDB (telemetry hypertables + compression/retention)
- **Realtime:** Laravel Reverb + Echo — **every channel PRIVATE**
- **Queue/Cache:** Redis (+ Horizon)
- **MQTT:** Eclipse Mosquitto 2 · client `php-mqtt/laravel-client` · Python discovery sidecar
- **Git:** local repo, no remote yet · feature branches, never commit to `main`
- **Name:** "HomeOS" is a working title
## Everything runs in containers (R8 — host has only Docker)
The host has **no PHP / Composer / Node** for project work. Always exec into the stack:
```bash
docker compose up -d # start stack
docker compose exec app php artisan … # artisan
docker compose exec app composer … # composer
docker compose exec app npm … # node/vite (or: docker compose exec app npm run build)
docker compose logs -f app # tail
```
The `app`, `horizon`, `scheduler`, `reverb` (and later `mqtt-listener`) services share one image
(`docker/app/Dockerfile`). Ports are env-driven in `.env` (`APP_PORT`, `VITE_PORT`,
`REVERB_HOST_PORT`, `DB_HOST_PORT`). `HOST_UID`/`HOST_GID` come from `id nexxo` — never hardcode.
## Architecture (handoff §3)
MQTT-first hybrid. Mosquitto is the bus. `mqtt-listener` (artisan daemon) parses + dispatches only
(H2) → Horizon jobs upsert `device_states` → Reverb private channels → Livewire (Echo).
UI action → `DeviceCommandService` → driver (`ShellyMqttDriver` first) → device, every command
audited in `commands` (H1). Vendor specifics only in `app/Support/Mqtt` + `app/Support/Drivers` (H3).
## Design system (handoff §8)
"Enterprise Ops, dark OLED" — UniFi/Grafana-class console, not a consumer app. Tokens live in
`resources/css/app.css` `@theme` (ported verbatim from the mockup). Status via colored dot/pill +
text (never color alone, never emoji, R9). Every numeric value / MAC / IP / timestamp in
`font-mono` with `tabular-nums`. Hairline borders, no shadows. Accent (cyan) sparingly.
## Non-negotiable rules
See **`rules.md`** (R1R17 + H1H5). Highlights: class-based Livewire pages (R1/R2), tokens-only
styling (R3/R10), wire-elements/modal for confirms (R5), UUID route keys (R11), browser-verify every
page (R12), English routes / German labels (R13), self-hosted fonts (R14), Codex review gate (R15),
full localization DE+EN (R16). **On any conflict: STOP and ask.**
## Build order (handoff §13)
1. Bootstrap → 2. Domain core → 3. MQTT ingest → 4. Discovery → 5. Presence → 6. Automations →
7. Polish + PWA. Each phase ends **browser-verified (R12) + Codex-clean (R15) + committed on a
feature branch**.