Commit Graph

7 Commits (d10172ac265a5b3d7e665524e91dbdd1f89330d4)

Author SHA1 Message Date
HomeOS Bootstrap 5cde2786aa All sidebar tabs are real pages (zero console errors)
Persons & Anwesenheit, Netzwerk & Discovery, Automationen, Einstellungen and
Zugang & Face-ID are now working Livewire pages (were dead "In Kürze" buttons).
Adds persons / discovery_findings / automations tables + models; authorizes the
presence + discovery broadcast channels; silences MQTT debug-log spam. Nav check
10/10 tabs clean (200, 0 console errors, 0 failed requests).

Deeper behaviour (presence polling, discovery sidecar, automation engine) lands
in the respective phase; the pages + schema are in place and render live.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 00:16:16 +02:00
HomeOS Bootstrap 23ef993cb2 Fix R15: per-device MQTT ACLs, monotonic presence, real-device online semantics
- ACL: drop the shared `shelly` account + `+` wildcard (allowed cross-device
  spoofing/control). Devices now authenticate with per-device credentials
  (username = topic prefix, provisioned at onboarding) bound to their own prefix
  via `pattern %u`. gen-passwd.sh creates only laravel + sidecar.
- last_seen_at is set from the message receive time (observed_at), monotonically,
  so a delayed/retried/stale ingest job can't mark a device online incorrectly.
- Device::isOnline: a real device with no last_seen is OFFLINE (never connected);
  only demo devices are assumed reachable. Added `demo` flag + presence tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 23:08:29 +02:00
HomeOS Bootstrap ea9e35883b Phase 3: MQTT ingest — Mosquitto bus, Shelly driver, live device state
Real bidirectional MQTT so devices are live, not mock (handoff §13.3):
- Mosquitto 2 broker (auth + per-client ACLs for laravel/shelly/sidecar from day
  one); passwd generated by docker/mosquitto/gen-passwd.sh (gitignored).
- mqtt-listener daemon: subscribes `+/status/#`, parse + dispatch only (H2),
  exponential reconnect backoff, graceful SIGTERM. php-mqtt/laravel-client.
- Ingest path (H4): IngestShellyMessage resolves device by mqtt_prefix, upserts
  device_states, refreshes last_seen, broadcasts DeviceStateChanged
  (ShouldBroadcastNow) on the private `home` channel.
- Control path (H1): DeviceDriver contract + ShellyMqttDriver (command topic +
  Shelly.Reboot RPC) behind DeviceCommandService, which audits every command to
  the new `commands` table. Device detail toggles + restart route through it;
  flash reflects the real result.
- Live UI: dashboard + device pages listen via Echo (#[On('echo-private:home,
  .DeviceStateChanged')]) and re-render instantly.
- Vendor specifics isolated in Support/Mqtt + Support/Drivers (H3).

Verified end-to-end in a real browser: publishing an MQTT status turned a light
"An" on the dashboard in 3.0s with no reload, 0 console errors. R12 30/30;
15 feature tests green (incl. ingest + command audit). README/bootstrap document
the broker passwd step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 22:51:14 +02:00
HomeOS Bootstrap 2a39f1cc4e Fix R15: require prod hardening in docs; drop N+1 in warnings
- Document that production must set APP_ENV=production + APP_DEBUG=false (else
  exceptions leak and the demo household seeds); note it in .env.example too.
- HomeStatus::warnings now iterates devices → entities using the already-loaded
  device, instead of $entity->device, removing an N+1 on dashboard render.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 22:03:20 +02:00
HomeOS Bootstrap 1b69c39a93 Fix R15 findings: fresh-clone bootstrap + never seed a blank admin password
- Document the first-run path (deps/assets/key/migrate aren't auto-installed
  because vendor/node_modules/public-build are gitignored): add
  docker/app/bootstrap.sh and a README with the exact sequence to run before
  `docker compose up`.
- Seeder: fall back with `?:` so a present-but-empty HOMEOS_ADMIN_PASSWORD can
  never create a blank-password admin; .env.example ships a non-empty dev value.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 21:24:10 +02:00
HomeOS Bootstrap fcb6daa6ab Home dashboard + Host tab: device state & warnings, server status split out
Reworks the dashboard into a home-control view per user feedback (it is not a
server dashboard):
- Dashboard now shows home data — rooms with live device state (lights on/off,
  power draw, window/door contacts, battery %), a home summary (devices online,
  lights on, open contacts, low batteries), and a Warnings panel that only lists
  what needs attention (offline device, open window, low battery, degraded host
  service). No server internals on the dashboard.
- Server/service health (DB, Redis, Reverb, Horizon) + version info moved to a
  dedicated "Host & Dienste" page (new nav item under System); dashboard surfaces
  a host problem only as a warning that links there.
- New domain slice (handoff §3, mock-first §13.2): rooms/devices/entities/
  device_states migrations + models (UUID route keys, R11) + DemoHomeSeeder with
  Shelly-like devices incl. deliberate faults. Extracted SystemHealth service.
- Sidebar decluttered further; new x-entity-state component; full DE/EN i18n.
- Fixed R15 findings: .env.example now ships matching non-empty dev defaults for
  DB_PASSWORD and Reverb keys so a fresh `cp .env.example .env` boots cleanly.

Verified: R12 21/21 in headless Chromium (0 console errors, 0 failed requests,
breakpoints 375/768/1280); 10 feature tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 21:20:38 +02:00
HomeOS Bootstrap beac04ec51 Phase 1: bootstrap — Docker stack, Laravel 13, design system, auth
Foundation for HomeOS (handoff §13.1). Verified in a real browser (R12):
HTTP 200, zero console errors, zero failed requests, breakpoints 1280/768/375,
no leaked template/lang literals. Feature test suite green (7 passing).

Stack (locked, handoff §12): Laravel 13, Livewire v3 (class-based, no Volt),
Tailwind v4 (@theme, no config), PostgreSQL 17 + TimescaleDB, Redis + Horizon,
Reverb (private channels, proxied same-origin via nginx), Vite. Everything runs
in containers (R8); one app image shared by app/horizon/scheduler/reverb.

- docker: app (php-fpm 8.4 + nginx + supervisor), db (timescale pg17), redis,
  reverb, horizon, scheduler; env-driven ports; HOST_UID/GID from id nexxo
- design system ported verbatim from design-mockup.html into @theme (§8);
  self-hosted Plus Jakarta Sans + IBM Plex Mono woff2 (R14)
- Blade component kit: icon, panel, kpi, status-dot/pill, badge, toggle,
  room-card, device-chip, sidebar, topbar; app + guest layouts (mobile drawer)
- auth: class-based Livewire Login (throttled) + Dashboard; English routes,
  German UI; full DE/EN localization (R16)
- rules.md + CLAUDE.md; admin user seeded from gitignored .env

Deferred by design: php-mqtt/laravel-client (Phase 3), mosquitto/mqtt-listener
(Phase 3), discovery sidecar (Phase 4).

R15 (Codex review) pending user `codex login`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 21:06:20 +02:00