UI-Gesamtumbau: Du-Form, Inspector-Panel, Onboarding-Assistent, Tour, Palette
Deploy App / deploy (push) Successful in 1m1s
Deploy App / deploy (push) Successful in 1m1s
Rein an der Oberflaeche -- Berechnung, Datenmodell und API-Semantik unveraendert (103 Tests unveraendert gruen). Paket A (Fundament): - durchgehend Du-Form und echte Umlaute in allen sichtbaren Texten, inkl. API-Fehlermeldungen (vorher Mix aus Sie/Du und ae/oe/ue) - neue UI-Primitiven (ui.tsx): Button, Modal mit ESC/Fokus-Falle/Animation, Bestaetigungs-Dialog statt window.confirm, Toasts statt alert, Skeleton-Loader, EmptyState - eigene Attention-Farbe (Amber) fuer offene Entscheide, getrennt vom Akzent - Micro-Interactions mit prefers-reduced-motion-Fallback Paket B (Onboarding, Roadmap Nr. 10): - gefuehrter Plan-Assistent in 5 Schritten; Einkommen bewusst pro Person (raeumt die 9.9-AHV-Falle aus); reine Orchestrierung bestehender Endpunkte - Beispielplan mit einem Klick; Uebergaenge absichtlich offen - interaktive Tour ueber die Planansicht (localStorage, jederzeit neu startbar) - abgeleitete "Naechste Schritte"-Karte (offene Entscheide, fehlende Elemente, fehlende Pensionsphase, Ruin -> Einflussfaktoren) Paket C (Struktur): - Inspector-Panel rechts statt Modals fuer alle Einzel-Bearbeitungen; Matrix bleibt sichtbar, Zellklick wechselt den Inhalt - Phasenkopf auf vier Kern-Infos entschlackt (Rest in der 0.11-Detailansicht) - Matrix mit eigenem Scrollbereich, Koepfe beidachsig fixiert - Sidebar-Gruppen "Meine Plaene" / "Wissen"; "So rechnet FPT" statt SPEZIFIKATION; "Szenario-Profil" statt "Plan-Einstellungen" - Aktions-Icons ohne Hover sichtbar (Touch) Paket D (Extras): - Sparklines je Element-Zeile aus den 0.11-Verlaufswerten - Befehls-Palette (Ctrl/Cmd+K) - Ruin-Banner verlinkt auf die Einflussfaktoren Nebenbei: der ProfileMenu-Lint-Fehler und der Selection-Rest (9.17) sind behoben -- npm run lint laeuft erstmals fehlerfrei. SPEZIFIKATION auf 0.13: neue Kapitel 3.2.8, 3.7.6-3.7.9, 9.23, 9.24; 3.6.3 und 3.7.1 ueberarbeitet, 9.17 bereinigt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+11
-11
@@ -1,6 +1,6 @@
|
||||
// Spielt ALLE Migrationen gegen ein echtes PostgreSQL (PGlite, in-process) ein und prueft das
|
||||
// Ergebnis. Faengt kaputte oder nicht-idempotente Migrations-SQL ab, bevor sie beim Deploy
|
||||
// gegen die Live-Datenbank laufen -- lokal steht sonst keine Datenbank zur Verfuegung.
|
||||
// Spielt ALLE Migrationen gegen ein echtes PostgreSQL (PGlite, in-process) ein und prüft das
|
||||
// Ergebnis. Fängt kaputte oder nicht-idempotente Migrations-SQL ab, bevor sie beim Deploy
|
||||
// gegen die Live-Datenbank laufen -- lokal steht sonst keine Datenbank zur Verfügung.
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { PGlite } from "@electric-sql/pglite";
|
||||
import { readFileSync, readdirSync } from "node:fs";
|
||||
@@ -9,7 +9,7 @@ import path from "node:path";
|
||||
const MIG = path.join(process.cwd(), "prisma", "migrations");
|
||||
|
||||
describe("Datenbank-Migrationen", () => {
|
||||
it("laufen vollstaendig durch und ergeben das erwartete Schema", async () => {
|
||||
it("laufen vollständig durch und ergeben das erwartete Schema", async () => {
|
||||
const db = await PGlite.create();
|
||||
const dirs = readdirSync(MIG).filter((d) => !d.endsWith(".toml")).sort();
|
||||
expect(dirs.length).toBeGreaterThan(0);
|
||||
@@ -24,7 +24,7 @@ describe("Datenbank-Migrationen", () => {
|
||||
)
|
||||
).rows.map((r) => r.table_name);
|
||||
|
||||
// V6-Struktur: Behaelter Plan + berechenbares Scenario.
|
||||
// V6-Struktur: Behälter Plan + berechenbares Scenario.
|
||||
for (const t of ["User", "Plan", "Scenario", "Person", "Phase", "FinancialElement"]) {
|
||||
expect(tables, `Tabelle ${t} fehlt`).toContain(t);
|
||||
}
|
||||
@@ -37,27 +37,27 @@ describe("Datenbank-Migrationen", () => {
|
||||
)
|
||||
).rows.map((r) => r.column_name);
|
||||
|
||||
// Kind-Tabellen haengen am Szenario, nicht mehr am Plan.
|
||||
// Kind-Tabellen hängen am Szenario, nicht mehr am Plan.
|
||||
for (const t of ["Person", "Phase", "FinancialElement"]) {
|
||||
const c = await cols(t);
|
||||
expect(c, `${t}.scenarioId fehlt`).toContain("scenarioId");
|
||||
expect(c, `${t}.planId haette entfernt werden muessen`).not.toContain("planId");
|
||||
expect(c, `${t}.planId hätte entfernt werden müssen`).not.toContain("planId");
|
||||
}
|
||||
|
||||
// Herkunfts-Verweise fuer den Diff.
|
||||
// Herkunfts-Verweise für den Diff.
|
||||
expect(await cols("Phase")).toContain("sourcePhaseId");
|
||||
expect(await cols("FinancialElement")).toContain("sourceElementId");
|
||||
|
||||
// Der Plan traegt keine Finanzdaten mehr.
|
||||
// Der Plan trägt keine Finanzdaten mehr.
|
||||
const planCols = await cols("Plan");
|
||||
expect(planCols).not.toContain("householdType");
|
||||
expect(planCols).toContain("userId");
|
||||
|
||||
// Das Szenario traegt sie.
|
||||
// Das Szenario trägt sie.
|
||||
const scenCols = await cols("Scenario");
|
||||
for (const c of ["planId", "isBase", "parentScenarioId", "householdType", "initialCash"]) {
|
||||
expect(scenCols, `Scenario.${c} fehlt`).toContain(c);
|
||||
}
|
||||
expect(scenCols).not.toContain("userId"); // Eigentuemer haengt am Plan
|
||||
expect(scenCols).not.toContain("userId"); // Eigentümer hängt am Plan
|
||||
}, 60000);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user