Operations-Dashboard v3 — Requirements
Problem Frame
Marvin hat keinen aggregierten Blick auf:
- Was steht heute auf seinem Tisch — und was wartet auf andere
- Wie ist die Burn-Rate (Cloud, SaaS, Belege)
- Was passiert in welchem Projekt
- Welche Belege sind noch nicht in Papierkram
- Historische Entwicklung (Trends 2024/2025/2026) ueber alle Achsen
Daily-Briefing-Push deckt den Tag ab, ist aber linear/text. Marvin ist visueller Typ + ADHS — braucht Bilder, nicht Listen. Soll vom Handy unterwegs aufrufbar sein.
v2-Lineage: Plan v2 hatte ein Cloud-Backend (Lambda + EventBridge + S3-Daten) vorgesehen. Pivot am 2026-05-14: Backend wird verworfen. Begruendung: zusaetzlicher Always-On-Stack fuer Solo-User ohne Need. Stattdessen statischer Build + on-demand Backfill-Scripts. Snapshots leben im Vault.
v3 Requirements
Daten-Quellen (woher kommt was)
- R1 Projekte: parse aus
intern/projekte/*/_index.mdFrontmatter viagray-matterin Next.js Server Components (src/lib/vault.ts). Keine zusaetzliche Aggregations-Schicht noetig — Schema 5.5 ist schon strukturiert. - R2 Kunden: parse aus
intern/kunden/*.mdFrontmatter. Verlinkung zu Projekten viacustomer:-Field. - R3 Finanzen aktuell: build-time-Pull via lokalem Script
scripts/build-finanzen.tsaus gsuite-MCP (gleicher Pull wie heute, aber als pre-build statt Lambda). Output: ein JSON-File pro Build-Run insrc/data/finanzen-current.json. - R4 Finanzen historisch: einmaliger
scripts/backfill-finanzen.ts-Run dumpt Gmail-Belege 2024-2026 als monatliche Aggregat-Files nachintern/finanzen/snapshots/<jahr>-<monat>.json. Format: pro Monat Kategorien-Totals + Beleg-Count, KEINE Einzelpositionen (die bleiben in Papierkram / Gmail). Aggregate sind ausreichend fuer Trend-Charts. - R5 Cloud-Kosten aktuell: build-time-Pull via
aws ce get-cost-and-usage+ Hetzner-API + Cloudflare-API. Output:src/data/cloud-current.json. - R6 Cloud-Kosten historisch: einmaliger
scripts/backfill-cloud.ts-Run dumpt 13 Monate Cost-Explorer-History als monatliche Snapshots nachintern/finanzen/cloud-snapshots/<jahr>-<monat>.json. Cost-Explorer-Retention ist 13 Monate — alles davor existiert nicht und wird nicht rekonstruiert. - R7 Activity-Stream (optional Phase 2): parse aus
intern/runs/<jahr>-<monat>.mdals Aktivitaeten-Log.
Frontend / Tech
- R8 Next.js 16 + Tailwind v4 (bestehend in av-cockpit) + Recharts fuer Charts. Server Components lesen Vault-Daten, Client Components fuer interaktive Charts/Filter.
- R9 Chart-Library: Recharts (direkt, bereits installiert in av-cockpit). Tremor explizit nicht (effektiv unmaintained seit Mitte 2024). Observable Plot als Optional-Add fuer eine spaetere Sankey/Force-Graph-Page.
- R10 Typografie: Geist Sans (UI) + Geist Mono (Zahlen, Code), via
geist-Package (self-contained, kein CDN). - R11 Aesthetik: Vercel/Stripe-Lane — viel Whitespace, shadow-as-border statt echte Borders, monochrom (#0d1117 fg, ffffff bg), Akzent 533afd nur fuer aktive Nav + CTAs. CSS Custom Properties (
--color-*) statt Tailwind-Palette. - R12 Mobile-tauglich. Gleiche Funktionalitaet auf Desktop und Mobile (keine Lite-Variante). Charts shrinken, Cards stacken.
Customization
- R13 Saved Views statt Drag-and-Drop. Drei vorbereitete Views als JSON in
intern/firma/dashboard-views.json:morning— was muss ich heute, Burn-Rate, Belege-Driftcost-audit— alle Cloud-Charts, Burn-Trend, Provider-Verteilungsteuerberater— Belege-Listen, monatliche Aggregate, Pending-Pflege
- R14 Pro Karte ein Show/Hide-Toggle, persistiert in
localStorage(av-dashboard.hidden-cards.<view>Array von Card-IDs). Reorder via ↑↓-Buttons neben jeder Karte. - R15 Time-Range-Selektor (Tag / Monat / Quartal / Jahr / Custom). Globale Component, persistiert pro Page in
localStorage.
Routing
- R16 Bestehende Pages bleiben (
/,/projekte,/cloud,/finanzen), erweitert um Drill-Down-Routes und Uebersicht:/— „Heute” (Default Landing, 4 Bloecke wie unten)/uebersicht— vollkundenanpassbare Wall mit allen verfuegbaren Cards + Saved-View-Switcher/projekteund/projekte/<slug>— Liste + Detail/cloudund/cloud/<account>— Kosten + Account-Drill/finanzenund/finanzen/<jahr>/<monat>— Belege + Monatsdetail/kunden/<slug>— Kunden-Profil mit verlinkten Projekten/runs— Activity-Stream (Phase 2)
/heute v3 — vier Bloecke
- R17 „Was muss ich tun” — Liste der
ball_bei: mir-Projekte, sortiert nachnext_step_dueASC, max 5 sichtbar - R18 „Aktive Projekte” — Karten-Grid, max 6 sichtbar (Rest hinter „weitere zeigen”), sortiert nach
letzte_aktivitaetDESC, ball_bei-Color-Coding wie heute - R19 „Burn-Rate” — Cloud-Kosten letzte 30 Tage als Sparkline + grosse Zahl + ggf. Delta gegenueber Vormonat. Klick =
/cloud - R20 „Belege-Drift” — Anzahl Belege noch nicht in Papierkram als Counter + Liste der Top-3-Urgent. Klick =
/finanzen
Auth + Hosting
- R21 Cognito + Google IdP, hello@-Konto only. Stub ist im Code (
src/lib/auth.ts,Dashboard.astro) und wird in Phase 6 finalisiert. - R22 Hosting: S3 (eu-central-1, Frankfurt) + CloudFront. Aktivierung Cloudflare-DNS-Cutover auf
dashboard.agenticventures.dein Phase 6. - R23 Keine US-CDN-Embeds. Fonts self-hosted, keine Google-Analytics, keine Cloudfront-Bootstrap.
Success Criteria
- S1 /heute laedt in < 1s auf Desktop und Mobile, zeigt die vier Bloecke ohne Mock-Disclaimer
- S2 Trend-Charts (Cloud, Finanzen) zeigen mindestens 6 Monate Historie (ab Backfill-Run)
- S3 Marvin kann Karten auf /uebersicht ein-/ausblenden + reordern, persistiert ueber Page-Reload
- S4 Saved Views switchbar in einem Click, Layout wechselt sofort
- S5 Mobile-tauglich: alle Pages auf 375px-Viewport ohne horizontal Scroll, Charts shrinken sauber
- S6 Live unter
dashboard.agenticventures.demit Cognito-Schutz (Google-Login hello@-only)
Scope Boundaries
Nicht im MVP:
- Drag-and-Drop-Layout (kommt nur wenn Saved Views nach 3 Monaten nicht reichen)
- Echtzeit-Updates / WebSocket / Server-Sent-Events (Build-time + manueller Refresh reichen)
- Multi-User, Permission-Model, Steuerberater-Login
- Auto-Trigger Backfill (Backfill ist on-demand-Script, Marvin laeuft es bei Bedarf manuell)
- Echte historische Daten vor April 2025 fuer Cloud (Cost-Explorer-Retention-Limit)
- Einzel-Beleg-Drilldown fuer Historie (Aggregat-Files only, Einzelpositionen in Papierkram)
- Activity-Stream
/runs(Phase 2) - Knowledge-Graph / Vault-Graph (gestrichen aus v2, kein klarer Use-Case fuer Solo)
- Export (CSV/PDF) —
data_origin-Source ist die Wahrheit
Explizit ausgeschlossen:
- Kein Lambda, kein API-Server, keine DB
- Keine US-Hosted-Drittanbieter im Frontend
- Kein automatisches
next_step-Auto-Fill (bleibt Marvins manuelle Pflege)
Key Decisions
- Markdown-only ist Mittel, kein Selbstzweck. Build-Time-Scripts duerfen externe APIs ziehen, solange das Resultat im Vault als File landet. Reproduzierbarkeit + Git-Tracking sind das eigentliche Ziel.
- Aggregat-Snapshots statt Einzel-Belegen. Pro Monat ein JSON, Kategorien-Totals + Counts. Einzel-Positionen leben in Papierkram. Pflegearm.
- Saved Views statt Drag-and-Drop. Drei kuratierte Layouts decken Marvins Workflows ab. Reorder + Show/Hide reicht — kein dnd-kit, kein Library-Bloat.
- Recharts direkt statt Tremor. Tremor ist effektiv unmaintained. Recharts bereits in av-cockpit installiert und auf /cloud im Einsatz (Area-Chart 7-Tage-Trend).
- Cognito + Google bleibt. Stub ist da, Setup in Runbook v2 dokumentiert.
- Bestehende Page-Struktur erweitert, nicht ersetzt. /heute /projekte /cloud /finanzen /routinen bleiben + Drill-Down-Routes + /uebersicht.
- Geist Sans + Geist Mono via npm-Package. Self-contained, DSGVO-konform, kein CDN.
- [NEU 2026-05-16] av-cockpit ersetzt av-dashboard. Next.js 16 statt Astro 5. Vault-Bridge
src/lib/vault.tsliest Frontmatter direkt via gray-matter + fs in Server Components. Kein Content-Collections-Setup noetig. Static Export (next build→out/) nach S3. Deploy-Scriptscripts/deploy.shsynct nach S3 + CloudFront-Invalidation.
Dependencies / Assumptions
- AWS Cost Explorer API zugaenglich aus av-mgmt-Account fuer alle Linked-Accounts (Cross-Account-Cost-Aggregation aktiviert).
- Hetzner-API-Token + Cloudflare-API-Token verfuegbar (
.env.localim av-cockpit Repo). - Gmail-Belege-Label
Belegeist konsistent gepflegt (Marvin labelt eingehende Belege). - Projekt-Frontmatter Schema 5.5 ist im Vault konsistent (alle aktiven Projekte haben
status,customer,next_step,ball_bei). - Cognito User-Pool + Google-IdP-Config existiert in av-production (siehe Runbook v2).
- av-cockpit Repo (
~/source/av-cockpit/) ist aktuelles Code-Repo. av-dashboard (Astro) ist Vorgaenger und liegt noch in~/source/av-dashboard/als Referenz.
Outstanding Questions
Resolve Before Implementation
Keine.
Deferred to Build-Time
- [Affects R4] Wie genau parsen wir Belege-Mails fuer Kategorisierung? Heutige
data_origin: gmail-mcp (hello@ Gmail-Label-Belege + From-Filter)ist Vorbild — Script mussFrom:-Sender-Pattern matchen gegen Kategorie-Liste ausintern/finanzen/beleg-quellen.md. - [Affects R6] Hetzner historische Kosten — API gibt nur aktuelle laufende Periode. Backfill ist auf AWS-Daten beschraenkt, Hetzner laeuft ab heute „live”.
- [Affects R14] Wie verhalten sich
localStorage-Praeferenzen bei Saved-View-Switch? Pro View eigene Praefs oder global? - [Affects R20] Belege-Drift soll auch faellige Pending-Items zeigen — Datenformat im Finanzen-Snapshot dafuer?
Was gebaut ist (Stand 2026-05-17)
Lambda-Infrastruktur (agents-platform)
DashboardStack (3x taeglich, 9:00/13:00/18:00 UTC):
- AWS-Kosten via Cost Explorer →
aws-costs.json
LiveRefreshStack (alle 10 Minuten):
github_activity.py→repo-health.jsonroutines.py(CloudWatch-Logs-Parse) →routines-status.jsonemail_triage.py(Gmail readonly + Bedrock Haiku 4.5 EU) →email-triage.json- Kalender-Stub →
calendar-<datum>.json
Alle JSON-Files landen im DataBucket av-dashboard-data-425924867359 unter api/data/.
Sicherheits-Design Email-Triage:
- Gmail-OAuth nur
gmail.readonly— kein Write aus Lambda - Draft-Text nur als String in JSON, nie in Gmail gespeichert
- Marvin erstellt Drafts manuell via Cockpit oder gsuite-MCP
Frontend (av-cockpit)
Pages: /heute, /projekte, /infra (Cloud-Kosten + Routinen), /email, /finanzen
Sidebar: Heute / Projekte / Infra / Email / Finanzen
SWR: revalidateOnFocus: true only, kein refreshInterval (Lambda laeuft ohnehin nur 3x/10Min)
Email-Page /email:
- Relevante Mails: Importance-Badge + Bedrock-Einschaetzung + aufklappbarer Draft-Text + Copy-Button
- Ignorierte Mails: einklappbare Liste
- Meta-Zeile: total / gefiltert / klassifiziert
Finanzen-Page /finanzen (Phase 1, 2026-05-17):
- Forderungen offen: parsed
## Offene Forderungen-Tabellen ausintern/kunden/*.md, sortiert nach Faelligkeit, Summe + Ueberfaellig-Highlight - Zu stellen: Posten mit Status
zu stellen, gruppiert nach Kunde, Blocker-Hinweis (z.B. „wartet HR-Eintragung”) - Qonto-Slots: 3 Karten (Kontostand / Eingaenge 30d / Ausgaben Top 3) im Disabled-State, Hook
useQontoData()ist API-kompatibel zum spaeterenqonto.json - Ausgaben-Trend: Empty-State („Trend-Daten kommen mit Qonto”), echte Daten kommen via
intern/finanzen/snapshots/<jahr>-<monat>.json - Sidebar: neue „Outstanding”-Linie unter Pipeline-Block, zeigt offene Forderungen-Summe (klickbar →
/finanzen) - Plan: 2026-05-17-001-feat-finanzen-page-plan.md
Deployment
# Vollstaendiger Deploy inkl. Vault-Kontext-Upload:
./scripts/deploy.sh
# generate-context.mjs allein (wenn Projekte/Kunden sich geaendert haben):
node scripts/generate-context.mjs --uploadOffene Baustellen
- generate-context.mjs einmal mit
--uploadlaufen lassen — dann hat Bedrock Projekt-Kontext fuer Email-Klassifikation (aktuell leerer Kontext, weil das File noch nicht in S3 liegt) - Projekt-Detail-Route
/projekte/[slug]— Prototype unterassets/prototypen/bas-twin-overview.html - Vault-Bridge erweitern (
src/lib/vault.ts) —loadProject(slug)mit Pipeline-Stages fuer Detail-Route - Qonto-MCP + Snapshot-Lambda — wartet HR-Eintragung. Eigenbau
mcp-qonto(FastMCP, gleicher Pattern wiemcp-papierkram) + Lambdaqonto-snapshotinagents-platform(alle 10 Min) →qonto.jsonin DataBucket.useQontoData-Hook ist schon da, Slots in/finanzenwarten nur auf die Datenquelle. - Becker + Icking Forderungen ergaenzen — heute nicht in
/finanzenweil Vertrag nicht unterschrieben (Becker) bzw. komplett Pipeline-Stage (Icking HeyJulia v4 wartet auf Antwort). Sobald Meilenstein-Rechnungen anstehen: Tabelle## Offene Forderungenin den jeweiligen Kunden-Files anlegen. - Kalender-Integration — Google Calendar Service Account + Delegation statt Stub