Commit Graph
37 Commits
Author SHA1 Message Date
florian.wildeandClaude Opus 5 ca2af0c2fc feat(ui): Tabellen als Karten auf dem Handy, Standort am Host (#035, #036)
Breite Tabellen (Kunden, Rechnungen, Ablauf-Kalender) werden unterhalb von
768 px zu Karten: jede Angabe mit ihrer Beschriftung, statt rechts
abgeschnitten zu sein. Kartenkoepfe brechen um, die Jahresbahn bekommt eine
schmalere Namensspalte und einen Hinweis aufs Wischen.

Standort am Host (#036): Das Formular sendete nur den Kunden, die Aktion las
aber auch standortId - jede Kundenzuweisung hat den Standort still geloescht.
Jetzt stehen Kunde und Standort in einem Formular, die Liste richtet sich nach
dem Kunden, und die Aktion prueft, dass der Standort zum Kunden gehoert.

Nebenbefund: Das Kontrollkaestchen fuer den Rechnungsstatus trug
pl-touch-target und wurde dadurch selbst zum 44 Pixel hohen leeren Kasten.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-03 16:20:20 +02:00
florian.wildeandClaude Opus 5 09bb98235b fix(ui): Seitenmenue auf dem Handy schliessbar machen (#034)
Das Markup stammt von AdminLTE, dessen JavaScript wir bewusst nicht
einbinden. Die Klasse sidebar-open liess sich damit setzen, aber nichts nahm
sie wieder weg: keine Flaeche zum Antippen, kein Schliessen beim Navigieren,
kein Escape. Auf dem Telefon blieb das Menue ueber dem Inhalt stehen.

Jetzt gibt es einen eigenen Zustand, auf den Kopfzeile und Menue gemeinsam
hoeren, eine abdunkelnde Flaeche dahinter, einen Schliessen-Knopf im Menuekopf
und das Schliessen beim Navigieren. Der Inhalt dahinter scrollt nicht mehr mit.

Ausserdem zeigt die Dashboard-Tabelle auf dem Telefon nur Host und Ablauf, den
Kunden klein darunter - vorher war rechts die Haelfte abgeschnitten.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-03 15:55:59 +02:00
florian.wildeandClaude Opus 5 94d5edbc6c fix(adresse): Weiterleitungen nie aus der Lausch-Adresse bauen (#033, #032)
Abmelden fuehrte im Docker-Betrieb auf 0.0.0.0:3000 - eine Adresse, die kein
Browser aufrufen kann. Ursache war hausgemacht: ENV HOSTNAME=0.0.0.0 aus
#031 reparierte die Zustandspruefung und lenkte zugleich alle Weiterleitungen
aus Server Actions dorthin, weil Next sie serverseitig absolut macht. Vorher
stand dort der Containername - derselbe Fehler, nur unauffaelliger.

Neuer Helfer eigenerPfad() baut die Adresse aus Einstellung, APP_URL oder den
Kopfzeilen der Anfrage. Betroffen waren Abmelden, die Sitzungspruefung und das
Loeschen eines Kunden. Zusaetzlich uebergeht oeffentlicheBasis() eine als
Lausch-Adresse eingetragene APP_URL, statt sie zu uebernehmen.

Gegen einen Docker-Stapel geprueft: Mit APP_URL=http://0.0.0.0:3000 leitet die
Anwendung jetzt auf den tatsaechlich aufgerufenen Namen.

Dazu #032: Das ct-Skript setzt die Herkunft der App-Skripte selbst, und die
Speichervorgabe steht auf 4 GB.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-03 15:35:19 +02:00
florian.wildeandClaude Opus 5 11e514dd25 feat(deploy): Update und Sicherung fuer beide Installationsarten (#031)
Prüfung / pruefung (push) Canceled after 0s
deploy/update.sh und deploy/backup.sh konnten nur Docker. Beide erkennen die
Installationsart jetzt selbst und beherrschen auch die Installation als
Dienst: npm ci, prisma migrate deploy, bauen, systemctl restart - und
pg_dump ueber DATABASE_URL fuer die Sicherung.

Beim Durchspielen gegen einen laufenden Stapel zwei Fehler gefunden:

1. Die Zustandspruefung des Web-Containers konnte nie gelingen. Next bindet
   im Standalone-Modus an die Adresse aus HOSTNAME, und Docker setzt dort
   den Containernamen - der Server lauschte nur auf der Container-IP. Der
   Dienst web blieb dauerhaft auf "health: starting". Behoben mit
   ENV HOSTNAME=0.0.0.0; geprueft wird jetzt ueber 127.0.0.1.
2. Eine fehlgeschlagene Sicherung hielt die Aktualisierung nicht auf. Jetzt
   bricht sie ab, bevor etwas veraendert wird, und nennt die Auswege.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-03 07:26:30 +02:00
florian.wildeandClaude Opus 5 ddca903687 docs(betrieb): netbird Reverse Proxy (Beta) aufnehmen (#030)
netbird bringt seit v0.65 einen eigenen Reverse Proxy mit, v0.72 ergaenzte
private Dienste. Damit entfaellt ein zusaetzlicher nginx: TLS-Terminierung
und Weiterleitung durchs Mesh, ohne offenen Port.

Wichtigster Hinweis in der Anleitung: Eine Anmeldehuerde vor dem Dienst
(SSO, Passwort, PIN) gilt auch fuer /api/agent. Die Agents weisen sich mit
eigenem Token aus und koennen sich nirgends anmelden - sie wuerden stumm ins
Leere melden. Zwei Auswege beschrieben: zwei Dienste oder ein privater
Dienst, der nur aus dem netbird-Netz erreichbar ist.

Beta-Einschraenkungen benannt: kein Rosenpass, selbst gehostet nur mit
Traefik (TLS-Passthrough).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 10:56:05 +02:00
florian.wildeandClaude Opus 5 b6fdd4f64a docs(betrieb): Einrichtung Schritt fuer Schritt dokumentieren (#029)
Vier Anleitungen unter docs/betrieb/: Inbetriebnahme in der richtigen
Reihenfolge, HTTPS mit nginx Proxy Manager sowie netbird als privates Netz,
OIDC mit authentik samt Fehlerbildern, und Sicherung einschliesslich
Zurueckspielen.

Beim Aufschreiben zwei Fehler gefunden, die nur hinter einem Reverse Proxy
auftreten: Die OIDC-Rueckkehradresse uebersah die im Dashboard eingetragene
Adresse, und beim Einloesen des Codes wurde die interne Adresse verwendet -
der Anbieter haette den Tausch abgelehnt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 00:51:16 +02:00
florian.wildeandClaude Opus 5 2f45e33e20 feat(auth): Rollen, Benutzerverwaltung und Passkeys (#027, #028)
Drei Rollen: Administrator, Techniker, Kunde. Jede der 28 Aktionen nennt das
Recht, das sie verlangt; die Rechte stehen an einer Stelle. Kundenkonten
haengen an genau einem Kunden und sehen nur dessen Hosts und Rechnungen -
ohne Einkaufspreise und Marge. Die Einschraenkung sitzt in den Abfragen
selbst, damit keine Seite vergessen kann, sie weiterzugeben; sechs Tests
pruefen das.

Dabei gefunden: Neu ueber OIDC angelegte Konten haetten die Vorgabe des
Datenmodells geerbt - ADMIN. Jetzt gibt es dafuer eine Einstellung mit der
Vorgabe Techniker.

Passkeys (#028) als gleichwertiger, passwortloser Anmeldeweg neben Passwort
und OIDC. Mehrere je Konto, Aufgabe in einem kurzlebigen Cookie, rpID aus der
oeffentlichen Adresse. Ohne HTTPS sagt die Seite es, statt still zu scheitern.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 00:46:29 +02:00
florian.wildeandClaude Opus 5 6c3729bae8 feat(deploy): Auslieferung als Docker-Stack und als Helper-Script (#026)
Docker: deploy/update.sh sichert, baut, migriert und prueft die
Erreichbarkeit; der Worker hat jetzt eine Zustandspruefung. Der ganze Stapel
wurde durchgespielt - bauen, starten, migrieren, anmelden, Agent-Skript
abrufen.

Dabei ein echter Fehler aufgefallen: Nach der Anmeldung zeigte die
Weiterleitung auf den internen Containernamen. Hinter einem Reverse Proxy
waere das eine tote Adresse gewesen. Weiterleitungen nehmen jetzt die
eingetragene Adresse, sonst APP_URL, sonst die Proxy-Kopfzeilen.

Dazu Skripte nach Art der Proxmox VE Helper-Scripts (Node und PostgreSQL
direkt im LXC, ohne Docker). Vorerst intern: Eine Einreichung setzt
oeffentlichen Quelltext voraus und laeuft ueber ProxmoxVED.

Ausserdem docs/roadmap.md: Bis 1.0.0 fehlt kein Code mehr, sondern
Erprobung.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 00:11:33 +02:00
florian.wildeandClaude Opus 5 d416f3869a feat(einstellungen): Betriebswerte im Dashboard einstellbar (#025)
Vier Bereiche unter Einstellungen -> System: Adresse und Agent,
Kaufmaennisches, Sicherheit sowie Firma und Darstellung. Alles liegt als
eine JSON-Zeile in der Tabelle Einstellung; fehlende Felder bekommen ihren
Vorgabewert, eine kaputte Zeile legt den Betrieb nicht lahm.

Die Werte wirken auch wirklich: Die Dashboard-Adresse und der Melderhythmus
landen im ausgelieferten Einzeiler und im systemd-Timer (live geprueft),
der Steuersatz in neuen Rechnungspositionen, die Sitzungsdauer im Token,
die Firmenangaben im Kopf der PDF-Dateien.

Nebenbei geschlossen: die OIDC-Luecke aus #024. Erlaubte Domaenen und ein
Schalter gegen automatisch angelegte Konten. Dazu raeumt der Worker nachts
nach den eingestellten Fristen auf - der juengste Report je Host bleibt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 23:58:30 +02:00
florian.wildeandClaude Opus 5 7775b6211f feat(security): Haertung nach OWASP Top 10 (#024)
Drei echte Luecken gefunden und geschlossen:

1. Die 27 Server Actions verliessen sich allein auf proxy.ts. Jede prueft die
   Sitzung jetzt selbst und schlaegt gegen die Datenbank nach, ob das Konto
   noch gilt - damit lassen sich Sitzungen ueberhaupt erst widerrufen.
2. Der Anmelde-Endpunkt prueft die Herkunft des Formulars; vorher war
   Login-CSRF moeglich.
3. Content-Security-Policy mit Nonce je Anfrage und strict-dynamic.

Dazu: npm audit ist ohne Befund (mysql2 und deepmerge-ts per overrides
angehoben statt Prisma zurueckzustufen), eine Benutzerverwaltung fuer die
Kommandozeile und docs/sicherheit.md mit allem, was bewusst offen bleibt -
keine Rollen, keine Zwei-Faktor-Anmeldung.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 23:45:35 +02:00
florian.wildeandClaude Opus 5 1bfd549838 fix(agent): PBS-Ausgaben richtig auswerten (#023)
Feldtest auf einem echten Proxmox Backup Server 4.2: `proxmox-backup-manager
subscription get` gibt eine Rahmentabelle aus, keine "feld: wert"-Zeilen. Der
Agent hat dort bisher nichts gelesen - nicht einmal die Server-ID. PBS kann
(anders als PVE) `--output-format json`; das wird jetzt genutzt, die Tabelle
dient als Rueckfall. Die Testfaelle stammen ab sofort vom echten Host, der
bisherige PBS-Testfall war erfunden und hat den Fehler verdeckt.

Ausserdem: die PBS-Version enthielt die laufende Fassung doppelt, und die
Versionspruefung meldete "neue Version" auch bei aelteren Fassungen.

Installation, Report, Warnungen und Uninstall wurden auf dem Host vollstaendig
durchgespielt - damit ist auch der letzte offene Punkt aus #018 erledigt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 23:27:02 +02:00
florian.wildeandClaude Opus 5 52466eee3f docs(feldtest): Feldtest fuer PBS und PMG als #023 festhalten
Prüfung / pruefung (push) Canceled after 0s
PBS-Hosts stehen spaeter zur Verfuegung, allerdings nur unlizenziert; fuer
PMG gibt es derzeit keinen Host. Der heutige PBS-Testfall im Testlauf ist
erfunden (JSON) und gehoert gegen echte Ausgaben geprueft - bei PVE war
genau diese Annahme falsch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 18:45:36 +02:00
florian.wildeandClaude Opus 5 7728fcb565 feat(cluster): Cluster-Knoten ohne Agent erkennen (#022, #018)
Feldtest auf zwei echten Proxmox-VE-9.2-Hosts (#018): Installation, Timer,
Zwischenspeicher und Nachsenden laufen wie vorgesehen. `pvesubscription get`
kennt kein JSON, ohne Subscription fehlen fast alle Felder, `pveversion`
enthaelt den Kernel doppelt - alles im Agent beruecksichtigt.

Dabei zeigte sich: in Proxmox hat jeder Knoten eine eigene Subscription.
Der Agent meldet darum die Cluster-Mitglieder aus `pvecm nodes`, und eine
elfte Warnregel meldet Knoten, von denen sich kein Agent meldet (#022).

Ausserdem behoben: die Bilder des Handbuchs zeigten allesamt die
Anmeldeseite, weil Firefox eine selbst erzeugte Cookie-Datei stillschweigend
verwirft. Das Skript nutzt jetzt einen lokalen Vermittler und bricht ab,
wenn alle Aufnahmen gleich gross sind.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 18:05:08 +02:00
florian.wildeandClaude Opus 5 db3d38aa3c feat(security): Zugangsdaten verschluesselt speichern (#021)
AES-256-GCM mit Schluessel aus APP_SECRET fuer SMTP-Passwort und
Webhook-Geheimnis. Bestehende Klartextwerte werden weiter gelesen und beim
naechsten Speichern umgeschluesselt. 156 Tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 23:50:46 +02:00
florian.wildeandClaude Opus 5 0d16dfd379 ci: Pruefung bei jedem Push und Konsistenzpruefung der Doku (#019)
Gitea-Actions-Workflow mit Lint, Typen, Tests gegen PostgreSQL, Build,
ShellCheck und einem Skript, das Version, Issue-Uebersicht und Handbuch-Bilder
abgleicht.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 23:47:38 +02:00
florian.wildeandClaude Opus 5 9c0cefcfe8 feat(ui): Symbole fuer Tab, Startbildschirm und Manifest (#017)
npm run icons erzeugt SVG, ICO und PNG aus den Vorlagen in assets/. Fuer kleine
Groessen kommen die vereinfachten Fassungen zum Einsatz.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 23:46:21 +02:00
florian.wildeandClaude Opus 5 4423d17b15 docs: Handbuch mit Bildern und Skript zum Auffrischen (#016)
Elf Kapitel von der Installation bis zur Fehlersuche, 16 Bilder. Das Skript
meldet sich fuer die Aufnahmen selbst an, ohne Hintertuer im Code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 23:43:19 +02:00
florian.wildeandClaude Opus 5 2c2f842d20 fix(auth): Sitzungs-Cookie auch ueber http nutzbar, Anmeldung als Formular (#013)
Das Cookie erhielt im Produktionsbau immer Secure und wurde ueber http vom
Browser verworfen – nach der Anmeldung landete jeder Klick wieder auf der
Anmeldeseite. Massgeblich ist jetzt das Schema in APP_URL.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 23:41:01 +02:00
florian.wildeandClaude Opus 5 4c65c9ddab perf(alerts): Warnungen sammelweise anlegen, Dark-Mode und Mobilansicht verbessern (#015)
Lasttest mit 200 Hosts und 365.000 Reports: Auswertung der Warnregeln von 3813
auf 293 ms. Logo im dunklen Design sichtbar gemacht, Tabellen blenden auf
schmalen Bildschirmen Spalten aus, Aufgaben-Karte begrenzt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 23:27:23 +02:00
florian.wildeandClaude Opus 5 0af9187079 feat(deploy): Docker-Abbild, Compose, LXC-Installer und Sicherung (#014)
Mehrstufiges Abbild mit Standalone-Ausgabe, eigener Migrationsdienst, Worker als
ESM-Buendel, LXC-Installer fuer Proxmox, Reverse-Proxy-Beispiele, Sicherungsskript
und Zustandspruefung. Stapel gebaut und mit Agent-Durchlauf geprueft.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 23:12:29 +02:00
florian.wildeandClaude Opus 5 ee487775ec feat(auth): Anmeldung mit Passwort und OIDC, Schutz aller Seiten (#013)
Signierte Sitzungs-Cookies mit jose, OIDC ueber openid-client (authentik),
Schutz in proxy.ts, Anmeldeseite, Audit-Log-Ansicht, Sicherheits-Kopfzeilen und
Rate-Limit. Kein Auth.js, weil Version 5 Beta ist. 147 Tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 22:40:03 +02:00
florian.wildeandClaude Opus 5 9e770a99b1 feat(alerts): Benachrichtigungen per E-Mail und Webhook (#012)
SMTP mit STARTTLS fuer Microsoft 365, Webhook mit HMAC-Signatur, taegliche oder
woechentliche Zusammenfassung, Versandprotokoll und Testversand. Keine
Doppelmeldungen dank Pruefung gegen das Protokoll. 134 Tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 22:33:17 +02:00
florian.wildeandClaude Opus 5 8a299f6c5e feat(alerts): zehn Warnregeln mit Worker, Liste und Einstellungen (#011)
Regeln als reine Funktionen, Abgleich oeffnet und schliesst Warnungen anhand
eines Fingerabdrucks. Worker wertet stuendlich aus, zusaetzlich nach jedem
Report. 123 Tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 22:25:33 +02:00
florian.wildeandClaude Opus 5 cb009efd7d feat(export): CSV- und PDF-Ausgaben fuer Hosts, Kunden und Rechnungen (#010)
PDFs entstehen serverseitig mit @react-pdf/renderer, mit einfarbigem Logo,
wiederholtem Spaltenkopf und Summenzeile. Alle Exporte uebernehmen die Filter
der jeweiligen Ansicht.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 22:12:58 +02:00
florian.wildeandClaude Opus 5 1a5327dced feat(jahresbahn): Zeitleiste und Ablauf-Kalender aus der Datenbank (#009)
Zwoelf-Monats-Bahn mit Heute-Linie und Gruppierung nach Kunde, 90-Tage-Kalender
mit Rechnungsstatus sowie eine Karte fuer bereits abgelaufene Subscriptions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 21:57:09 +02:00
florian.wildeandClaude Opus 5 558dfea34c feat(rechnungen): Laufzeiten bestaetigen, Rechnungen erfassen und Status setzen (#008)
Rechnungen mit Positionen: gleiche Nummer ergibt eine Sammelrechnung ueber mehrere
Laufzeiten. PDF-Upload mit Inhaltspruefung und Ablage unter der Pruefsumme,
Haekchen direkt in der Tabelle, Filter nach Status, Kunde und Jahr. 78 Tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 21:54:45 +02:00
florian.wildeandClaude Opus 5 2dbb30041b feat(tooling): Gitea-Token aus den Git-Zugangsdaten lesen (#020)
Serveradresse und Repository stammen aus dem Remote, der Token aus dem
Schluesselbund bzw. ~/.git-credentials. Ein zweiter Token in der .env entfaellt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 21:44:01 +02:00
florian.wildeandClaude Opus 5 2df43e1517 feat(tooling): Issue-Dateien mit dem Gitea-Tracker abgleichen (#020)
Skript liest docs/issues/, legt Labels und Meilensteine an, erkennt vorhandene
Issues an der Nummer im Titel und schliesst erledigte. Trockenlauf ohne Token.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 21:17:23 +02:00
florian.wildeandClaude Opus 5 0ae96a50cd feat(hosts): Host-Tabelle mit Filtern, CSV-Export und Detailansicht (#007)
Suche ueber Hostname, Key, Server-ID, IP und Rechnungsnummer, fuenf Filter,
Sortierung mit nulls-last, Seitenblaettern und CSV-Export. Detailansicht mit
sechs Tabs, Notizen, Tags und Token-Widerruf. 59 Tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 21:12:41 +02:00
florian.wildeandClaude Opus 5 6aa6a20f63 docs: Issues #017 bis #019 aus den Erkenntnissen der bisherigen Phasen (#006)
Favicon-Dateien, Feldtest des Agents auf echten Proxmox-Hosts und CI-Pipeline
waren bisher nur Notizen in anderen Issues.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 21:04:24 +02:00
florian.wildeandClaude Opus 5 f9a5ad2daa feat(kunden): Kundenverwaltung, Hostzuweisung und Token-Verwaltung (#006)
Kunden und Standorte pflegen, nicht zugeordnete Hosts in einem Schritt zuweisen,
Enrollment- und Host-Tokens verwalten, Audit-Log. Dashboard, Kundenseiten und
globale Suche laufen jetzt auf der Datenbank. 45 Tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 21:02:44 +02:00
florian.wildeandClaude Opus 5 d9455db311 feat(agent): Bash-Agent mit Installer, systemd-Timer und Spool (#005)
Produkterkennung fuer PVE, PBS und PMG, JSON-Erzeugung ohne jq, Retry mit
Backoff, Nachsenden aus dem Spool, Update und Uninstall. Das Dashboard liefert
install.sh und agent.sh mit eingesetzter Adresse aus. 38 Tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 20:44:38 +02:00
florian.wildeandClaude Opus 5 bef51eb863 feat(api): Agent-API mit Enrollment, Report und Ping (#004)
Gehashte Tokens mit Praefix, Rate-Limit je IP und Token, zod-Validierung mit
durchgaengig optionalen Feldern, idempotente Reports ueber reportId, Key- und
Server-ID-Historie sowie automatischer Laufzeit-Vorschlag. 32 Tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 20:39:33 +02:00
florian.wildeandClaude Opus 5 293bcf4b5a feat(db): Datenmodell, erste Migration und Seed (#003)
Prisma 7.10 mit Postgres-Adapter, 23 Modelle inklusive Rechnungen mit Positionen,
Seed fuer Administrator, Warnregeln und Demo-Daten, Testdatenbank fuer Vitest.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 20:32:04 +02:00
florian.wildeandClaude Opus 5 8596a18a27 feat(ui): klickbarer Prototyp mit Beispieldaten (#002)
Layout im AdminLTE-Stil (Sidebar, Kopfleiste, Inhaltskopf, Footer), Logo als
SVG-Komponente, Farbschema mit Dark-Mode, Dashboard, Kunden- und Host-Ansichten,
Rechnungsuebersicht, Jahresbahn und globale Suche (Strg+K).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 20:03:15 +02:00
florian.wildeandClaude Opus 5 783d2fd7bd docs: devlog und Issue #001 abgeschlossen
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 19:44:08 +02:00
florian.wildeandClaude Opus 5 a54c1b6285 docs: Projektorganisation, Architekturplan und Issues pro Phase (#001)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 19:42:04 +02:00