Projekt-Dashboard v3 — Implementations-Plan
Overview
Statisches Operations-Dashboard unter dashboard.agenticventures.de. Next.js 16 + Tailwind v4 + Recharts (Repo: av-cockpit). Server Components lesen Vault-Markdown direkt via gray-matter. Static Export nach S3 + CloudFront. Geist Sans/Mono, Vercel/Stripe-Aesthetik (monochrom, shadow-as-border, Akzent 533afd).
Pivot von v2: Lambda + EventBridge + S3-Daten-Bucket sind raus. Stattdessen Build-Time-Scripts + Snapshot-Files im Vault. Cognito + S3 + CloudFront bleiben (Frontend-Hosting only).
Pivot von v3-Astro zu av-cockpit (2026-05-16): Astro 5 (av-dashboard) ersetzt durch Next.js 16 (av-cockpit). Begruendung: Server Components + gray-matter ist simpler als Astro Content Collections fuer Vault-Reads. Recharts direkt statt shadcn-charts-Wrapper. Geist-Fonts statt Inter/JetBrains Mono. Bestehende Pages: /heute, /projekte, /cloud, /finanzen, /routinen.
Requirements Trace
Trace zu _index.md v3 — Anchor-IDs sind die R*-Marker:
- R1-R7 Daten-Quellen → Phase 1 (Foundation) + Phase 4 (Backfill)
- R8-R12 Frontend/Tech → Phase 2 (Design-System) + Phase 3 (Charts)
- R13-R15 Customization → Phase 5
- R16 Routing → Phase 2 + Phase 3
- R17-R20 /heute v3 vier Bloecke → Phase 2 (Mock) + Phase 3 (Live-Daten)
- R21-R23 Auth/Hosting → Phase 6
Scope Boundaries
Siehe _index.md §Scope Boundaries. Hier nur Plan-Ebene:
- Plan deckt MVP-Live unter
dashboard.agenticventures.deab. Activity-Stream/runs, Observable-Plot-Visualisierungen und Drag-and-Drop sind explizit Phase-Out und nicht in diesem Plan. - Backfill ist on-demand-Skript, kein Cron. Plan beschreibt das Skript, nicht eine Automatik.
Context & Research
Relevant Code
~/source/av-cockpit/— Aktives Repo. Next.js 16 + Tailwind v4 + Recharts. 5 Pages live:/heute,/projekte(Kanban),/cloud(AWS-Kosten + 7d-Trend),/finanzen,/routinen. Vault-Bridge insrc/lib/vault.ts(gray-matter + fs). Deploy viascripts/deploy.sh(S3 sync + CloudFront invalidation).~/source/av-cockpit/src/lib/vault.ts— Vault-Bridge: liestintern/projekte/*/_index.md+intern/kunden/*.mdvia gray-matter, typesafe Types (ProjectCard,Customer,Task), Filter-Helpers (isActiveProject,getMyTasks,getWaitingProjects).~/source/av-cockpit/src/app/cloud/page.tsx— Cloud-Kosten-Page mit Recharts Area-Chart, Kundenabrechnung, Service-Breakdown. Nutzt SWR +/api/data/aws-costs.json.~/source/av-dashboard/— Vorgaenger (Astro 5). Archiviert, nicht mehr aktiv entwickelt. Liegt noch als Referenz fuer Design-Tokens (ink-Palette, MetricCard-Pattern).~/source/agents-platform/lambdas/dashboard-refresh/— v2-Lambda, wird NICHT geloescht (steht als Referenz). Keine Dependency aus v3/v4 darauf.
Relevant Vault-Quellen
- beleg-quellen.md — Gmail-Label-Konvention + Sender-Pattern fuer Kategorisierung
- web-properties.md — Cloudflare-DNS-Convention fuer den Subdomain-Cutover
- _index.md — av-mgmt-Account + Cross-Account-Cost-Aggregation
- gsuite.md — Gmail-Pull fuer Belege im Backfill-Script
Institutional Learnings
- ADHS-Pattern — System unsichtbar, nur das Relevante zeigen. /heute hat 4 Bloecke, nicht 10. Mehr Karten = weniger Klarheit.
- AWS-First Hosting — S3 + CloudFront im av-production-Account, kein Vercel/Cloudflare-Pages-Alternative.
- Schreibstil — Deutsche Umgangssprache in UI-Texten, keine em-dashes, ganze Saetze.
- [2026-05-16] Astro → Next.js Pivot — Astro Content Collections waren Over-Engineering fuer den Use-Case. gray-matter + fs in Next.js Server Components ist direkter und braucht keine Symlinks/Loader-Hacks fuer Vault-Pfade ausserhalb des Repos.
External References
- Recharts Docs — Chart-Library (direkt, ohne shadcn-Wrapper)
- Next.js 16 Docs — Server Components, Static Export
- gray-matter — Frontmatter-Parser fuer Vault-Reads
- Geist Font — Geist Sans + Geist Mono via
geistnpm-Package - AWS Cost Explorer GetCostAndUsage — 13-Mo-Retention beachten
Phasen-Overview
flowchart LR P0[Phase 0\nCleanup + Foundation] --> P1[Phase 1\nContent Collections\n+ Zod-Schemas] P1 --> P2[Phase 2\nDesign-System\n+ Mock /heute v3] P2 --> P3[Phase 3\nshadcn-charts\n+ Live-Daten] P3 --> P4[Phase 4\nBackfill-Scripts\nFinanzen + Cloud] P4 --> P5[Phase 5\nCustomization\nSaved Views + localStorage] P5 --> P6[Phase 6\nDeploy\nS3 + CloudFront + Cognito]
Zeitlich grob: P0-P3 = MVP-Live (Sprint 1, ~3-5 Tage), P4-P5 = Komfort (Sprint 2), P6 = Production-Cutover (1 Tag wenn AWS-Vorarbeit aus Runbook v2 nutzbar).
Phase 0 — Cleanup + Foundation
Goal: Bestand inventarisieren, v2-Reste sauber abklemmen, av-dashboard auf den v3-Ready-Zustand bringen ohne Funktionalitaet zu verlieren.
Unit 0.1 — v2-Lambda-Code als Referenz-Frieren
~/source/agents-platform/lambdas/dashboard-refresh/bleibt unangetastet. README darin updaten mit Vermerk „v2 Plan, ersetzt durch v3 (static)“. Kein Cron mehr in CDK aktiv lassen.- Acceptance: EventBridge-Rule fuer dashboard-refresh ist disabled (oder Stack entfernt). README hat v3-Pointer.
Unit 0.2 — av-dashboard Repo aufraeumen
public/api/data/*.jsonbleibt als Read-Fallback waehrend Migration. Spaeter (Phase 3) wird der Pfad obsolet.src/lib/data.ts— Typen bleiben, werden Vorbild fuer Zod-Schemas in Phase 1..env.exampleergaenzen um neue Build-Vars:AWS_PROFILE_MGMT,HETZNER_API_TOKEN,CLOUDFLARE_API_TOKEN,GSUITE_OAUTH_PATH.- Acceptance:
npm run devstartet noch ohne Fehler, alle 4 Pages laden Mock-Daten.
Unit 0.3 — Astro-Integrations vorbereiten
- React-Integration installieren:
npx astro add react— fuer Charts + interaktive Komponenten. - Astro-Content-Collections aktivieren in
src/content/config.ts. - shadcn-Setup:
npx shadcn@latest initfuer Tailwind-Preset +components.json. Default-Theme als Basis, Customizing in Phase 2. - Acceptance: Astro-Build laeuft mit React-Integration, leere
src/content/config.tsda,components.jsonda.
Phase 1 — Content Collections + Zod-Schemas
Goal: Vault-Markdown wird zu typesafe Daten beim Build. Bestehende Mock-JSONs werden parallel weiter genutzt.
Unit 1.1 — Content-Collection projects
src/content/config.ts: Collectionprojectsmit Zod-Schema entsprechend Schema 5.5 (id, type, project_type, customer, status, ball_bei, next_step, next_step_due, code_repos, tags).- Glob-Source:
~/source/agentic-ventures/intern/projekte/*/_index.md. Astro Content Collections supportetloader-Pattern fuer externe Pfade — sonst Symlink-Bridgesrc/content/projects/→ Vault. - Mapping-Function
mapProject(entry) -> Projekt(kompatibel zum bestehendenProjekt-Type insrc/lib/data.ts). - Acceptance:
getCollection('projects')liefert validierte Liste, fehlerhafte Frontmatter wirft beim Build mit klarer Message.
Unit 1.2 — Content-Collection customers
- Analog
projects, Sourceintern/kunden/*.md. Schema 5.2 (customer). - Acceptance: validierte Kunden-Liste, Cross-Ref
customer:-Field in Projekten wird via Zod-Refine geprueft (Kunde muss existieren).
Unit 1.3 — Snapshot-Collections cloud-snapshots + finanzen-snapshots
- Zwei JSON-Collections (Astro 5 support JSON-Content).
- Source:
intern/finanzen/cloud-snapshots/<jahr>-<monat>.json+intern/finanzen/snapshots/<jahr>-<monat>.json. - Schema: monatliche Aggregate (Kategorien-Totals, Provider-Totals, Beleg-Count). Detail-Schema im File selbst dokumentiert.
- Phase 1 erstellt die Schemas + leere Collection (keine Files da). Files kommen aus Phase 4 Backfill.
- Acceptance: Collections sind definiert + leer, Build laeuft ohne Fehler.
Unit 1.4 — Current-Data-Schema fuer Build-Zeit-Pulls
- Zwei TypeScript-Files in
src/data/:finanzen-current.json+cloud-current.json. Initial leer / Mock-Inhalt. - Schema in
src/lib/schemas.tszentralisiert (Zod). Re-Export der bestehenden Types insrc/lib/data.ts. - Acceptance: Build laeuft, Pages lesen aus
src/data/*.json(statt auspublic/api/data/*.json) perimport.
Unit 1.5 — Migration der bestehenden Pages
- /heute, /projekte: switch von
fetchKpi(...)auf direkte Imports der Content-Collections. - /cloud, /finanzen: switch auf direkte Imports der Snapshot-Collections (wenn leer: Mock-Fallback aus Phase 0).
- Acceptance: Alle 4 Pages laden Daten aus Content-Collections statt aus
/api/data/. Mock-JSONs sind nicht mehr referenziert.
Phase 2 — Design-System + Mock /heute v3
Goal: Visueller Anker. Inter + JetBrains Mono installiert, Farb-Palette finalisiert, /heute v3 als statisches Mock. Kein State, kein Live-Daten — nur Form.
Unit 2.1 — Fonts self-hosted
public/fonts/mit Inter Variable + JetBrains Mono Variable. Latin + Latin-Extended Subsets.@font-faceinsrc/styles/globals.css.font-display: swap.tailwind.config.mjs:fontFamily.sans→ Inter,fontFamily.mono→ JetBrains Mono, mit System-Fallbacks.- Acceptance: Fonts laden in
npm run devohne Netzwerk-Roundtrip zu Google. Visueller Vergleich vorher/nachher.
Unit 2.2 — Farb-Palette finalisieren
- Erweitere
ink-Palette um200,300,500,600,800(heute Luecken). - Akzent: behalte
#0066cc, ergaenzeaccent.50(Hintergrund-Wash),accent.muted(Subtle-Variante). - Semantic-Colors
ok,warn,errbehalten, ergaenzeinfo(=accent). - Acceptance: Tailwind-Build laeuft, Beispiel-Komponente nutzt erweiterte Palette in Mock.
Unit 2.3 — shadcn-Komponenten installieren
npx shadcn@latest add button card badge separator dialog dropdown-menu tabs.- Dunkel-Modus via
tailwindcss-animate+class-Strategy. - Acceptance: Komponenten in
src/components/ui/da, Beispiel-Card rendert.
Unit 2.4 — Mock /heute v3
- Vorab frontend-design-Skill aufrufen mit Brief: vier Bloecke (R17-R20), Linear/Mercury-Aesthetik, Inter+Mono, Dark+Light, Mobile 375px.
- Output ist statische Astro-Page
src/pages/index-mock.astro(parallel zu existierendemindex.astro). - Mock-Daten inline im File (kein Fetch).
- Acceptance: Marvin sieht Mock im Browser, nimmt Look ab oder gibt Iteration-Feedback.
Unit 2.5 — Mock → echte /heute
- Sobald Look abgenommen:
index-mock.astroersetztindex.astro. Datenquellen via Phase-1-Content-Collections. - Acceptance: /heute zeigt live-Daten im neuen Look, alle 4 Bloecke aktiv.
Phase 3 — shadcn-charts + Live-Daten
Goal: Charts auf /cloud + /finanzen + /heute Burn-Rate. Build-Time-Pulls fuer aktuelle Daten.
Unit 3.1 — shadcn-charts installieren + erste Chart
npx shadcn@latest add chart.- Burn-Rate-Sparkline-Component
src/components/charts/BurnRateSparkline.tsx— React-Island, kleine SVG-Sparkline letzte 30 Tage. - Eingebunden in /heute Block 3 (R19).
- Acceptance: Sparkline rendert mit Mock-Daten, responsive.
Unit 3.2 — Cloud-Charts auf /cloud
- Drei Charts:
- Stacked-Bar 30 Tage pro Tag, Stack nach Provider (aws/hetzner/cloudflare)
- Pie/Donut Verteilung nach Business-Kategorie (current month)
- Stacked-Area 13 Monate Trend (nutzt Snapshot-Collection wenn vorhanden, sonst nur aktueller Monat)
- Zeit-Range-Selektor oben: 7d / 30d / 90d / 12mo / Custom — React-Island, schreibt
localStorage. - Acceptance: Charts laden, Range-Selektor wechselt Daten.
Unit 3.3 — Finanzen-Charts auf /finanzen
- Zwei Charts:
- Bar pro Monat (letzte 12 Monate), Stack nach Kategorie — aus
finanzen-snapshots-Collection - Donut Top-Kategorien current month
- Bar pro Monat (letzte 12 Monate), Stack nach Kategorie — aus
- Belege-Drift-Counter bleibt prominent (R20).
- Acceptance: Charts laden, leerer Zustand graceful wenn keine Snapshots da.
Unit 3.4 — Build-Time-Pull-Scripts (aktuelle Daten)
scripts/build-finanzen.ts— nutzt gsuite-MCP-CLI oder direkter Gmail-API-Call, schreibtsrc/data/finanzen-current.json.scripts/build-cloud.ts— aws-cli + Hetzner-API + Cloudflare-API, schreibtsrc/data/cloud-current.json.package.jsonScriptprebuildruft beide Scripts. Auch alsnpm run pullseparat triggerbar.- Acceptance:
npm run pullschreibt frische Daten,npm run buildruft pull vorher.
Unit 3.5 — Projekt-Detail-Pages /projekte/<slug>
- Astro Dynamic Routes via Content-Collection.
- Layout: Projekt-Header (name, status, customer-Link, next_step) + Activity-Timeline (aus
last_activityFrontmatter falls vorhanden) + Code-Repos-Liste (mit Links auf~/source/<slug>/). - Acceptance: /projekte/bas-twin laedt, Header korrekt.
Unit 3.6 — Kunden-Detail-Pages /kunden/<slug>
- Analog Projekt-Detail. Profil aus Frontmatter, Liste verlinkter Projekte.
- Acceptance: /kunden/becker laedt.
Phase 4 — Backfill-Scripts
Goal: Historische Snapshots in den Vault dumpen. On-demand, kein Cron.
Unit 4.1 — scripts/backfill-finanzen.ts
- Liest Gmail-Belege via gsuite-MCP fuer alle Monate seit 2024-01.
- Pro Monat: Kategorien-Totals + Beleg-Count berechnen (Pattern aus
intern/finanzen/beleg-quellen.mdSender-Mapping). - Output:
intern/finanzen/snapshots/<jahr>-<monat>.jsonmit Schema aus Unit 1.3. - Idempotent: bestehende Files werden ueberschrieben.
- Dry-Run-Mode
--dry-runzeigt was geschrieben wuerde. - Acceptance: Backfill schreibt ~28 Monats-Files (2024-01 bis 2026-04), Spot-Check 2-3 Files inhaltlich korrekt.
Unit 4.2 — scripts/backfill-cloud.ts
- Liest AWS Cost-Explorer fuer alle erreichbaren Monate (max 13 zurueck).
- Pro Monat: pro Linked-Account Kategorien-Totals (mapping in
intern/capabilities/aws/_index.md). - Hetzner + Cloudflare: NUR aktueller Monat (API gibt nicht mehr her). Ab heute live, History startet bei dem ersten Backfill.
- Output:
intern/finanzen/cloud-snapshots/<jahr>-<monat>.json. - Acceptance: ~13 AWS-Monats-Files + 1 Hetzner/Cloudflare-Current-Snapshot geschrieben.
Unit 4.3 — Charts wechseln von leer auf real
- /cloud Stacked-Area zeigt 13 Monate echt.
- /finanzen Monats-Bar zeigt 12+ Monate echt.
- /heute Burn-Rate vergleicht Current-Month mit Vormonat-Aggregat aus Snapshot.
- Acceptance: Visueller Smoke-Test, Zahlen plausibel (gegen Papierkram-Stand abgleichen).
Unit 4.4 — Vault-Commit fuer Snapshots
- Backfill commitet NICHT automatisch. Marvin reviewed
git diff intern/finanzen/snapshots/+ commitet manuell mitchore(dashboard): backfill finanzen-snapshots <jahr>-<monat>..<jahr>-<monat>. - Acceptance: Snapshot-Files sind im Vault-Git-Log nachvollziehbar.
Phase 5 — Customization (Saved Views + localStorage)
Goal: Marvin kann Karten ein-/ausblenden, reordern, zwischen Saved Views switchen.
Unit 5.1 — Card-Registry + Stable-IDs
- Jede Card auf /uebersicht hat eine stable ID (
card.projects.today,card.cloud.burn-rate, etc.). - Zentrale Registry
src/lib/cards.tsmit Card-Definitionen (id, title, default-visible, default-order). - Acceptance: Registry vollstaendig, alle Cards auf /uebersicht registriert.
Unit 5.2 — localStorage-Layer
src/lib/preferences.ts— typesafegetPref(key) / setPref(key, value), mit Defaults aus Registry.- Keys:
av-dashboard.<view>.hidden-cards,av-dashboard.<view>.order,av-dashboard.<page>.time-range. - Acceptance: Praefs persistieren ueber Reload, kein React-State-Issue.
Unit 5.3 — Card-Toolbar (Show/Hide + Reorder)
- Pro Card kleines
MoreMenu(shadcn Dropdown) mit „verbergen” + ↑ + ↓. - Hidden-Cards in einem Footer-Akkordeon „verborgene Karten (n)” wieder einblendbar.
- Acceptance: Verstecken + Reordern funktioniert, Reload behaelt Zustand.
Unit 5.4 — Saved-View-Switcher
- Top-Bar auf /uebersicht: drei Buttons
Morning/Cost-Audit/Steuerberater+ „Custom” (Marvins Manual-Edit-Zustand). - View-Definitionen aus
intern/firma/dashboard-views.json(per Content-Collection geladen). - Click switched localStorage-Keys, Page re-rendert.
- Acceptance: View-Switch in 1 Click, Layout aendert sich sichtbar.
Unit 5.5 — Time-Range-Selektor (globale Component)
- React-Island
<TimeRangeSelector />, eingebunden in /cloud, /finanzen, /uebersicht. - Optionen: 7d / 30d / 90d / 12mo / Custom (Date-Picker shadcn-Component).
- Filtert die geladenen Snapshots client-side.
- Acceptance: Range-Wechsel re-rendert Charts, persistiert pro Page.
Phase 6 — Deploy
Goal: Live unter dashboard.agenticventures.de, Cognito-protected.
Unit 6.1 — S3 + CloudFront aus Runbook v2 reaktivieren
runbook.mdaus v2 hat die CDK-Steps. Re-use ohne Lambda-Stack (nur S3 + CloudFront + Route53 + ACM).- Deploy in
av-production(eu-central-1). - Acceptance: CloudFront-Distribution erreichbar via temporaere CloudFront-Domain mit Static-Build.
Unit 6.2 — Cognito User-Pool + Google IdP
- Cognito-User-Pool + Hosted UI + Google-IdP (hello@-only via Email-Filter im Pre-Sign-Up-Trigger).
- Frontend bereits vorbereitet (
src/lib/auth.ts,Dashboard.astro-Redirect-Logik). .env.productionmitPUBLIC_COGNITO_DOMAIN,PUBLIC_COGNITO_CLIENT_ID,PUBLIC_AUTH_REDIRECT_URI.- Acceptance: Login via Google funktioniert, andere Accounts werden blockiert.
Unit 6.3 — Cloudflare-DNS Cutover
- CNAME
dashboard.agenticventures.de→ CloudFront-Domain. - ACM-Cert in us-east-1 (CloudFront-Constraint) fuer den Subdomain.
- Acceptance: HTTPS-Cert valid, Domain liefert Dashboard.
Unit 6.4 — Smoke-Test in Production
- Alle 4 Hauptpages + Detail-Routes per Browser-Klick durchgehen.
- Mobile-Test auf iPhone (375px) und iPad (768px).
- Console-Errors? Network-Tab auf US-Drittanbieter pruefen.
- Acceptance: Keine US-CDN-Calls im Network, keine Console-Errors, alle Pages rendern.
Risk Log
| Risk | Wahrscheinlichkeit | Impact | Mitigation |
|---|---|---|---|
| Gmail-MCP-Pull schlaegt aus Build-Skript fehl (OAuth-Token expired) | Mittel | Mittel | Skript-Output ist gecached in src/data/*.json — Build laeuft mit Stand-Daten weiter, Warning im Footer. Marvin re-authet on-demand. |
| AWS Cost-Explorer braucht Cross-Account-Aktivierung die noch nicht laeuft | Mittel | Mittel | Phase 0 Smoke-Test aws ce get-cost-and-usage --profile av-mgmt. Falls Fehler: Aktivierung in av-mgmt-Account ist 1-Klick-Setting. |
| Astro Content Collections + Vault-Pfade ausserhalb des Repos | Mittel | Niedrig | Loader-Pattern (Astro 5 unterstuetzt) oder Symlink im Repo. Symlink ist robuster fuer File-Watcher. |
| Snapshot-File-Format aendert sich rueckwirkend, alte Snapshots brechen | Niedrig | Mittel | Zod-Schema versioniert (schema_version im Snapshot-File). Migration-Script falls aenderung noetig. |
| Inter Variable Font-File ist zu gross (>500kb) | Niedrig | Niedrig | Variable-Font mit Subsetting via glyphhanger oder direkt das offizielle latin-subset von rsms.me. |
| Cognito Google-IdP Filter-Trigger nicht straight-forward | Mittel | Niedrig | Pre-Sign-Up-Lambda akzeptiert nur hello@-Email. Templates online, ~30min Setup. |
| Backfill-Skript laeuft 20 Minuten (~261 Belege, 28 Monate, Pro-Monat-Pull) | Niedrig | Niedrig | On-demand-Script, Marvin laeuft es einmal abends. Progress-Bar. |
| Recharts-Tree-Shaking schlaegt fehl, Bundle wird gross | Niedrig | Niedrig | shadcn-charts-Pattern importiert nur was gebraucht wird. Bundle-Analyzer-Check vor Deploy. |
Open Questions for Implementation
- [Phase 1] Astro 5 Loader-Pattern fuer Glob ausserhalb
src/content/testen — alternativ Symlinksrc/content/projects→~/source/agentic-ventures/intern/projekte/? - [Phase 4] Belege-Kategorie-Mapping ist heute in beleg-quellen.md als Prosa. Plan: vor Backfill in
scripts/lib/beleg-kategorien.tsals typesafe Mapping ueberfuehren. - [Phase 5] Saved-View JSON-Format finalisieren — Plan-Vorschlag:
{ "morning": { "visible": ["card.today.tasks", "card.projects.active", "card.cloud.burn-rate", "card.finanzen.drift"], "order": [...] }, "cost-audit": { ... }, "steuerberater": { ... } }
Next Steps
- Phase 0 Unit 0.3 startklar machen (Astro-React + Content-Collections-Setup).
- Parallel: frontend-design-Skill fuer Mock /heute v3 (Unit 2.4) — visueller Anker BEVOR Phase 1 los geht.
- Nach Mock-Abnahme: Phase 1 + Phase 2 in Reihenfolge, dann Phase 3.