Zum Hauptinhalt springen
w3yh.xyzLogin ↗

journal day

Donnerstag, 25. Juni 2026

Tagesansicht des öffentlichen Journals: konkrete Changelog-Outputs, Incidents und kuratierte Notes, ohne dass der Index alles auf einmal rendert.

Aktivität an diesem Tag: mittel

Donnerstag, 25. Juni 2026

codexw3yh

Health-Portal: REWE-Ernährungssignale angebunden

added

  • `scripts/grocery-health-signal.mjs`: read-only Generator für aggregierte REWE-Ernährungssignale aus Supabase. Schreibt `nutrition.json` und `ERNAEHRUNG-EINKAUFSSIGNAL.md` ausschließlich in den privaten Apple-Health-Datenordner außerhalb des Repos.
  • `/hub/health`: neue Ernährungskachel mit Bio-/Alkohol-/Obst-/Protein-KPIs, Süß-/Convenience-Trend, Signalen und Treue-Produkten.
  • Eigene Markdown-Sektion „Einkaufs-Findings im Dossier-Kontext" hinter dem Health-Gate.

changed

  • `scripts/health-data-service.mjs`: liest optional `nutrition.json` und hängt den Doc-Slug `ernaehrung-einkauf` an die private `/health`-Antwort.
  • `src/lib/private/health.ts`: optionales `HealthNutrition`-Schema ergänzt.

verified

  • `node scripts/grocery-health-signal.mjs --dry-run --json`: 295 Bons, 5.374 positive Artikel, Bio 11,0 %, Alkohol 0,8 %, Datenstand 2026-06-25.
  • Private Dateien live geschrieben mit `0600` unter `openclaw/workspace/data/apple-health/2026-06-13/`; keine Datenfiles im Repo-Diff.
  • `systemctl --user restart w3yh-health-api.service`; `/alive` aktiv; `/health` liefert `nutrition` + Doc-Slug `ernaehrung-einkauf`.
  • `npx tsc --noEmit` und `npx next build` erfolgreich.
  • Lokaler Browser-Smoke auf `/hub/health`: Route lädt ohne Overlay/Blank-Page; lokaler Private-Gate-Wartezustand erwartbar.
claudew3yh

REWE Grocery: Preissteigerungs-Tabelle gegen Gebinde-Vermischung gehärtet

fixed

  • **Phantom-Inflation:** Die „Größte Preissteigerungen"-Tabelle gruppierte Preispunkte nur nach `normalized_name` und ignorierte Einheit/Gebinde. Da REWE denselben Namen mal als Einzelflasche, mal als Kasten ausweist (z. B. ROSBACHER MEDIUM [Betrag]/Stk vs. [Betrag]/Stk), entstand eine Scheinsteigerung von +779 %. Durch den vorherigen Pagination-Fix (volle Historie) wurde das prominent sichtbar. Fix in [grocery.ts](file://`w3yh.xyz/src/lib/private/grocery.ts):` Gruppierung nach Name **+ Einheit**, plus Median-Band [0,4×…2,5×] das Gebinde-Ausreißer vor der first/last-Berechnung entfernt. Rosbacher jetzt 5,10 → [Betrag] (−19 %, n=19) statt +779 %.

improved

  • `grocery-dashboard.tsx`: InflationTable zeigt jetzt die Einheit (€/Stk, €/kg) am Produkt, damit klar ist, worauf sich der Preis bezieht.

verified

  • `npx tsc --noEmit` ohne Fehler.
  • Read-only Diagnose gegen Produktiv-Supabase: neue Top-10 durchweg plausibel (max +170 % SÜSSKARTOFFEL €/kg über ~6 Jahre); kein Phantom-Sprung mehr.
claudew3yh

REWE Grocery: Item-Pagination-Fix + Kategorisierung erweitert

fixed

  • **Kritisch:** `loadGroceryDashboard` lud nur die ersten 1000 von 5983 Items. Die Item-Query nutzte `.limit(20000)`, aber PostgREST kappt jede Antwort serverseitig bei ~1000 Zeilen. Folge: alle item-basierten Auswertungen (Kategorien, Inflation, Preisverlauf, saisonale Produkte, „Artikel"-KPI) rechneten nur auf ~17 % der Daten — die „Wohin fließt das Geld?"-Box summierte auf [Betrag] statt [Betrag]. Fix: beide Tabellen seitenweise via `.range()` laden, bis alle Zeilen geladen sind ([grocery.ts](file://`w3yh.xyz/src/lib/private/grocery.ts)).`
  • `grocery.ts`: Typo in der Discount-Heuristik `PROCENT` → `PROZENT`.
  • `grocery-dashboard.tsx`: redundante `inflationSorted`-Kopie entfernt, Length-Check direkt auf `data.inflationRanking`.
  • `page.tsx`: `GroceryFilters` als `import type` getrennt.

improved

  • `grocery-categories.ts`: Kategorisierung datengetrieben erweitert — ASCII-Umlautformen (`KAES`, `HAEHNCHEN`, `MUESLI`, `OLIVENOEL`), Bon-Abkürzungen (`BROETCH`, `LEBERW`) und Marken (Rosbacher, Gerolsteiner, Zewa, Alpro, Zott u. a.). „Sonstiges" von 47 % auf ~25 % der Ausgaben reduziert; Reihenfolge-Konflikte (LEBERKAES→Fleisch, ALPRO MANDEL→Milch) verifiziert.

verified

  • `npx tsc --noEmit` ohne Fehler.
  • Read-only Diagnose gegen Produktiv-Supabase: paginiert 295 Bons / 5983 Items / [Betrag]; Kategorie-Summe == Ausgaben-KPI (Δ [Betrag]).
  • Diagnose-Tooling abgelegt: `scripts/grocery-sum-diagnose.mjs`, `scripts/grocery-cat-diagnose.ts`.
antigravityw3yh

REWE Grocery Tracker Filter & Bugfixes

fixed

  • `src/components/private/grocery-dashboard.tsx`: Bug behoben, bei dem die `InflationTable` fälschlicherweise auf die 12 häufigsten Preisverlaufsprodukte statt auf das vollständige `data.inflationRanking` zugriff.
  • `src/components/private/grocery-dashboard.tsx`: Legenden-Slice von `.slice(0, 10)` auf alle 15 Kategorien erweitert, damit die aufsummierten Kategoriewerte der all-time Auswertungen mit der Gesamtsumme übereinstimmen.
  • Wochentagsstatistik: Sonntag aus der Wochenauswertung entfernt.

added

  • **Interaktives Cross-Filtering**: URL-Suchparameter (`?year=...&month=...&category=...`) werden nun über Next.js `searchParams` serverseitig geladen ([page.tsx](file://`w3yh.xyz/src/app/hub/grocery/page.tsx))` und in der Datenberechnung ([grocery.ts](file://`w3yh.xyz/src/lib/private/grocery.ts))` in-memory gefiltert.
  • **Interaktive UI-Komponenten**: Jahre, Monate, Kategorien und Heatmap-Zellen sind anklickbar ([grocery-dashboard.tsx](file://`w3yh.xyz/src/components/private/grocery-dashboard.tsx))` und toggeln die URL-Suchparameter. Das aktive Feld in der Heatmap wird fokussiert.
  • **Filter-Badges**: Aktive Filter-Badges im Dashboard-Header ermöglichen das Deaktivieren einzelner Parameter oder ein vollständiges Zurücksetzen der Filter.
  • **Kollabierbare Monatsausgaben**: Die monatlichen Ausgaben sind nun nach Jahren gruppiert und über native HTML `<details>`/`<summary>` Elemente kollabierbar. Die Jahressumme wird im Header angezeigt.

verified

  • `npx tsc --noEmit` ohne Fehler.
  • `npm run build` erfolgreich (`/hub/grocery` als ƒ Dynamic Route erzeugt).
antigravityopenclaw

REWE Grocery Tracker Cron eingerichtet und Clawledge Mention Scan deaktiviert

what

  • **Crontab-Aktualisierung:**
  • `clawledge:mention-scan` deaktiviert (auskommentiert).
  • Neuer Zwei-Wochen-Cronjob `w3yh:rewe-import` eingerichtet: Läuft sonntags in geraden ISO-Wochen um (11:00 Europe/Berlin).
  • **`direct-cron-runner.sh`:**
  • Neue Job-Definition `w3yh:rewe-import` hinzugefügt. Sie führt den Import-Skript `rewe-ebon-import.mjs --limit 100 --apply` im w3yh-Scope aus.

verification

  • `crontab -l` Backup unter `openclaw/backups/crontab-before-grocery-and-clawledge-disable[id].txt` erstellt.
  • Modifizierte Version erfolgreich als aktive Crontab eingespielt.
  • POSIX-Kompatibilität der Datumsberechnung für gerade Kalenderwochen erfolgreich in `sh` verifiziert.
  • `direct-cron-runner.sh w3yh:rewe-import --dry-run` erfolgreich ausgeführt.
antigravityw3yh

REWE Grocery Tracker Dashboard-Ausbau

added

  • `src/lib/private/grocery-categories.ts`: Heuristischer Kategorisierer für deutsche REWE-eBon-Produktnamen (13 Kategorien, keyword-basiert).
  • UI: Stacked Bars für Kategorien, SVG-Sparklines für Preisentwicklungen der Top-Produkte, Quartals-Peaks für saisonale Gelüste, Ausgaben-Heatmap (Wochentag × Monat) und Rhythmus-KPIs (Ø Tage, €/Tag).

changed

  • `src/lib/private/grocery.ts`: Berechnet nun 7 zusätzliche Analytics-Dimensionen serverseitig (Jahresvergleich, Wochentag-Verteilung, Kategorie-Breakdown, Preisentwicklung-Sparklinedaten, saisonale Muster, Rhythmus und Fun Stats).
  • `src/components/private/grocery-dashboard.tsx`: Massiv ausgebaut (von ~290 auf ~700 Zeilen) für 12+ Visualisierungs-Sektionen (YoY, Heatmap, SVG-Sparklines, Inflations-Ranking, Saisonale Muster, Fun Insights).
  • `src/components/private/private-gate-shell.tsx`: Hub-Karte für Grocery ("Einkaufsradar") ergänzt und `/hub/grocery` als Gate-Ziel registriert.
  • `src/lib/private/auth-config.ts`: `getPrivateGroceryPath` Helper ergänzt.
  • `package.json`: `rewe:import` npm-Skript registriert.

verified

  • `npx tsc --noEmit` ohne Fehler.
  • `npm run build` erfolgreich (`/hub/grocery` als ƒ Dynamic Route erzeugt).
codexw3yh

REWE Grocery Tracker Supabase-Import ausgeführt

fixed

  • `scripts/rewe-ebon-import.mjs`: internes Parser-Hilfsfeld `quantity_line` aus dem Supabase-Insert-Payload entfernt, damit `grocery_receipt_items` exakt dem Schema entspricht.

imported

  • `npm run rewe:import -- --limit 500 --apply`: 68 Gmail-REWE-eBons gescannt, 68 geparst, 68 nach Supabase importiert, 0 übersprungen.
  • Supabase-Zählung nach Import: 68 `grocery_receipts`, 1117 `grocery_receipt_items`, Datumsbereich 2025-06-28 bis 2026-06-25, Receipt-Summe 2531,82 EUR.
  • `grocery_members` mit dem GWS-Default-Account als aktivem Admin geseedet, damit `/hub/grocery` hinter dem Private Gate lesbar ist.

verified

  • `node --check scripts/rewe-ebon-import.mjs` grün.
  • `npm exec -- eslint scripts/rewe-ebon-import.mjs --max-warnings=0` grün.
codexw3yh

REWE Grocery Tracker MVP begonnen

added

  • Plan für Gmail→PDF→Supabase→Private-Gate-Pipeline dokumentiert: `docs/rewe-grocery-tracker-plan.md`.
  • Supabase-Migration `20260625_rewe_grocery_tracker.sql` für `grocery_members`, `grocery_receipts`, `grocery_receipt_items` und `grocery_product_aliases` mit RLS vorbereitet.
  • REWE-eBon-Importer `scripts/rewe-ebon-import.mjs` plus `pdfplumber`-Texthelper ergänzt; Default ist Dry-Run, Supabase-Schreiben nur mit `--apply`.
  • Private Dashboard-Route `/hub/grocery` samt Datenlade-Schicht und Hub-Karte ergänzt.

verified

  • `npm run rewe:import -- --limit 25 --json`: 25/25 REWE-eBons geparst, keine Summenfehler, kein OCR nötig.
  • `node --check scripts/rewe-ebon-import.mjs`, `python3 -m py_compile scripts/lib/rewe_pdf_text.py`, gezieltes ESLint, `npx tsc --noEmit` und `npx next build` grün.
  • Lokaler Dev-Server `:4063`, Browser-Smoke via `browse`: `/hub/grocery` lädt, kein Next-Error-Dialog, Screenshot unter `/tmp/w3yh-grocery-smoke.png`.
  • Remote-Supabase-Apply bewusst nicht durchgeführt: Migration ist noch nicht angewendet; Importer bricht mit klarem Schema-Hinweis ab.

Incidents

W3YH / REWE Grocery Dashboard [hybrid]
~30 minclaude

Problem: "Größte Preissteigerungen" zeigte Phantom-Inflation (ROSBACHER MEDIUM +779 %); Dominik fiel auf, dass [Betrag] vs [Betrag] nach Einzelflasche-vs-Mehrfachpack klingt

Ursache: Preisentwicklung gruppierte nur nach `normalized_name`, ignorierte Einheit/Gebinde; derselbe Name enthält bei REWE Einzelflaschen ([Betrag]/Stk) und Kästen ([Betrag]/Stk) → first/last verglich inkompatible Gebinde. Vorheriger Pagination-Fix machte es durch volle Historie sichtbar

Fix: Gruppierung nach Name + Einheit; Median-Band [0,4×…2,5×] entfernt Gebinde-Ausreißer vor first/last; Einheit (€/Stk, €/kg) in der Tabelle angezeigt. Rosbacher jetzt −19 % (n=19) statt +779 %, neue Top-10 live-verifiziert plausibel

W3YH / REWE Grocery Dashboard [hybrid]
~50 minclaude

Problem: "Wohin fließt das Geld?"-Box summierte nur ~[Betrag] statt [Betrag]; "Artikel"-KPI zeigte 912 statt ~5.400; alle item-basierten Panels rechneten auf einem Bruchteil der Daten

Ursache: Item-Query in `loadGroceryDashboard` nutzte `.limit(20000)`, aber PostgREST kappt jede Antwort serverseitig bei ~1000 Zeilen → nur 1000 von 5983 Items geladen. KPI "Ausgaben" blieb korrekt, weil receipt-basiert (295 < Cap). Dominik lieferte den Screenshot, der die Diskrepanz KPI vs. Kategorie-Box sichtbar machte

Fix: Beide Tabellen seitenweise via `.range()` paginiert (Stop bei `< PAGE`); zusätzlich Kategorisierung in `grocery-categories.ts` um ASCII-/Marken-/Abkürzungs-Keywords erweitert (Sonstiges 47 %→25 %), `PROCENT`→`PROZENT`-Typo, `inflationSorted`-Cleanup; read-only Diagnose-Scripts ergänzt; Pagination per Live-Query gegen Supabase verifiziert (5983 Items / [Betrag]); tsc grün

W3YH / REWE Grocery Dashboard
~25 minantigravity

Problem: Tabelle "Größte Preissteigerungen" war fälschlicherweise auf die 12 häufigsten Produkte beschränkt; "Sonstiges"-Kategorie ergab beim manuellen Aufsummieren nicht die Gesamtsumme der Jahre

Ursache: Die Dashboard-Komponente übergab fälschlicherweise `data.priceEvolution` statt `data.inflationRanking` an die `InflationTable`. Im Kategorien-Legend-Panel waren Kategorien auf die Top-10 per `.slice(0, 10)` beschränkt

Fix: `data.inflationRanking` an `InflationTable` übergeben, `.slice(0, 10)` Limit aus der Kategorienlegende entfernt und alle 15 Kategorien interaktiv und filterbar gerendert

W3YH / REWE Grocery Import
~10 mincodex

Problem: Produktiver `npm run rewe:import -- --apply` importierte nur einen Teil der Bons; viele Item-Inserts scheiterten mit `PGRST204` wegen Spalte `quantity_line`

Ursache: Parser hängte ein internes Hilfsfeld für Mengenzeilen an Item-Objekte und reichte es ungefiltert an Supabase weiter; die Migration enthält diese Spalte bewusst nicht

Fix: `quantity_line` aus dem Item-Payload entfernt, Syntax/ESLint geprüft, Import erneut ausgeführt: 68/68 Bons und 1117 Items importiert; GWS-Default-Account als `grocery_members` Admin geseedet

W3YH / Health-Portal REWE-Ernährung [hybrid]
~55 mincodex

Problem: REWE-Einkaufs-Findings waren noch nicht im privaten Health-Dossier sichtbar

Ursache: Analyse lag nur als Plan/Einzelbefund vor; Health-Service las bisher nur Apple-Health-JSON und Markdown-Dossiers

Fix: Read-only Generator `grocery-health-signal.mjs` gebaut, private `nutrition.json`/`ERNAEHRUNG-EINKAUFSSIGNAL.md` erzeugt, Health-Service um Nutrition-Payload und Doc-Slug erweitert, `/hub/health` um Ernährungskachel und Dossier-Sektion ergänzt; Service/Build/Browser-Smoke verifiziert

Persönliches Build-Journal. Aufgaben werden über ein Agentensystem (OpenClaw, verschiedene LLMs) per Cron- und Telegram-Trigger ausgeführt; die Heatmap zeigt eine relative Compute-Aktivität in fünf Stufen.