Commit Graph

5 Commits (feat/phase-1-bootstrap)

Author SHA1 Message Date
HomeOS Bootstrap 97dc49e577 fix: adversarial-review fixes + themed checkboxes
Multi-agent review of the feedback batch (7 confirmed):
- [P2] Low-battery sweep excluded a genuine 0% reading (`$pct > 0`) — a dead
  battery never alerted. Now `< 20` (missing reading still defaults to 100).
- [P2] SMTP encryption rule `required|in:,tls,ssl` rejected the "None" option it
  offered → unencrypted relays uncofigurable. Now `in:,tls,ssl`.
- [P2] Avatar preview called temporaryUrl() on any upload → 500 for HEIC/
  non-previewable files. Guarded with isPreviewable() + real-time
  updatedAvatar() validation for a friendly error.
- [P3] NotificationService::send() now catches transport errors so one SMTP
  failure can't abort a whole sweep / automation run.
- [P3] Mailer config is now purged (Mail::purge) so long-running Horizon workers
  pick up SMTP setting changes instead of reusing a cached mailer.
- [P3] Alert dedup TTL 1 day → 1 month, so a persistent outage mails once, not
  daily.
- User: themed .checkbox (accent, dark-surface, custom check) replaces the
  default browser checkbox in SMTP/automation/device modals.

+2 tests (0% battery alerts, no-encryption saves). Suite 84 green, 12/12 clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 10:48:22 +02:00
HomeOS Bootstrap aceb140aac Fix mobile sidebar readability; rework device list for scale
- Sidebar drawer is now opaque (.sidebar-tint solid), so on mobile the bright
  content no longer bleeds through and it stays readable.
- Devices index reworked for ~50 devices: live search (name/model/vendor),
  room + online/offline filters (URL-persisted), grouped by room with counts —
  scannable instead of one long list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 23:30:15 +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 f00a1ac069 Warnings → modal, device detail page, stable mock online state
- Warnings no longer clutter the dashboard: a compact "Warnungen (n)" button in
  the topbar opens a themed wire-elements/modal (R5) listing all messages. Dark
  modal wrapper overridden; HomeStatus service shared by dashboard + modal.
- Device detail page (/devices/{uuid}, UUID route key): edit name, room and
  active state; view info + live capabilities; Neustart (with confirm modal) and
  "Update prüfen" as mock commands (Phase 3 routes them through the real driver).
  Devices index (/devices) added; "Geräte" nav activated; dashboard device rows
  and index link to the detail. Generic Confirm modal + x-detail component.
- Mock devices no longer rot: online is now "active and (no last_seen or seen
  <10min)", so the demo stays healthy; the one offline device keeps a stale
  timestamp. Full DE/EN i18n for devices + modal copy.

Verified: R12 30/30 in headless Chromium (0 console errors, 0 failed requests);
10 feature tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 21:52:57 +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