Benjamin Sutter 177641386a refactor(team): zweite Überarbeitungsrunde — Oberfläche bereinigen
Gezielte UI-Bereinigung ohne neue Architektur. Bestehende Komponenten angepasst,
Datenstrukturen und Routing unverändert.

GLOBAL
Chip «Verwaltung» und Seitenname in der Kopfzeile entfallen auf /supply/team/*;
die Seiten tragen ihren Titel bereits gross im Inhalt. Andere Module behalten die
Zeile. Demo-Modus-Hinweis und alle Untertitel entfernt. Autonomiegrad aus der
Oberfläche genommen — die Daten bleiben unangetastet.

PERSONALVERWALTUNG
Beschrieb auf zwei Sätze gekürzt, Input/Kernablauf/Output entfallen: das war
Prozessnotation, sie beschrieb wie gearbeitet wird, nicht wofür man jemanden hat.
Zuständigkeiten stehen jetzt im Kopfbereich statt tief im Dossier. Reiterfolge
neu: Agentenbeschrieb, Aufgaben, Kennzahlen, Kanäle & Systeme, Protokoll.
Kanäle und Systeme sind über eine dünne Hülle zusammengeführt — die bestehende
Logik samt Konfigurationsdialog bleibt unberührt. Aufgaben dreispaltig ohne
Zeitplan, Ereignisfilter im Protokoll entfernt.

Der abgelöste Reiter «Systeme» wird weiterhin aufgelöst, damit bestehende
Verweise nicht still auf den ersten Reiter zurückfallen.

ORGANIGRAMM — die eigentliche Korrektur
Der falsch gewählte Agent lag an der Geometrie: `rotate(a) translateY(r)` schiebt
bei a = 0 nach UNTEN, die Drehung wurde aber als `180 − index·step` berechnet.
Damit stand der gewählte Mitarbeitende oben und das Dossier darunter gehörte zum
falschen. Jetzt `−index·step`.

Dazu beruhigt: Zugempfindlichkeit von 0.5 auf 0.22 Grad je Pixel, 10 px Totzone
gegen Zittern, kurzer Zug wechselt höchstens einen Platz, Einrasten in 250 ms,
Auswahl erst nach dem Einrasten. Kreis von 720 auf 460 px.

BEARBEITUNGSVERLAUF
Filter ohne Vorgangstyp, Priorität und Kanal; Suche in Zeile eins, Rest in Zeile
zwei. Karten tragen nur noch Agent, Titel mit Liegenschaft, zwei Zeilen Text und
Zeitstempel — Priorität, Status, Vorgangstyp und Kanal standen auf praktisch
jeder Karte und trugen damit keine Information mehr.

Drawer ohne Verarbeitungsschritte und Aktionshistorie; nur die auslösende
Nachricht plus Quicklink ins Anfragencenter statt des ganzen Verlaufs.
«Fundstellen» heisst «Quellen». Der Entscheidungshinweis heisst jetzt
«Hierzu brauche ich Ihre Entscheidung». Aktionsleiste: pendent Freigeben,
Zurückweisen, Quellen anzeigen, Inserat anzeigen — erledigt nur «Objekt anzeigen».

KANÄLE & SYSTEME, TEAMÜBERSICHT
Kanäle vor Systemen als eigene Abschnitte, vier Karten pro Zeile, Beschreibung
und Statusbadge raus, Regler mit Klartext Aktiv/Inaktiv/Geplant. Die Kreisgrafik
skaliert nach Anzahl sichtbarer Ringe und ist auf die Viewport-Höhe begrenzt,
damit das Kernteam ohne Scrollen vollständig sichtbar bleibt.

Drei Testzusicherungen prüfen jetzt die Abwesenheit statt der Anwesenheit von
Objekt-ID und Rückfragegrund auf der Karte — beides wurde bewusst entfernt.

Typecheck grün, ESLint über die geänderten Dateien grün, Build grün, 413 Tests grün.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 13:30:32 +02:00
2026-05-15 00:48:18 +02:00
2026-05-15 00:48:18 +02:00
2026-05-15 00:48:18 +02:00
2026-05-15 00:48:18 +02:00
2026-05-15 00:48:18 +02:00

Property Match

Decision-Intelligence-Plattform für kommerziell genutzte Immobilien — kein Portal, sondern eine Oberfläche, die Treffer bewertet, Trade-offs erklärt und eine nächste Handlung empfiehlt.

Verbindliche Entwicklungsregeln stehen in CLAUDE.md, Architekturdiagramme in ARCHITECTURE.md, Zustandsregeln in STATE_MANAGEMENT.md.

Starten

npm install
npm run dev          # Entwicklungsserver auf http://localhost:5173

Es gibt kein Backend und keine Datenbank. Sämtliche Daten stammen aus TypeScript-Mockdaten unter src/mock-data/ und werden über Mockup-Provider bereitgestellt.

Skript Zweck
npm run dev Entwicklungsserver mit HMR
npm run build Typecheck (tsc -b) und Produktionsbuild
npm run lint ESLint über das gesamte Projekt
npm test Vitest einmalig ausführen
npm run test:watch Vitest im Watch-Modus
npm run check:tokens Zählt rohe Hex-Farbwerte gegen einen Schwellwert

Architektur in vier Schichten

Provider  →  Service  →  Hook (React Query)  →  Component
  • Provider (src/provider/) sind der einzige Ort, der Datenhaltung berührt.
  • Services (src/services/) tragen die Fachlogik und liefern ListResponse<T> / ItemResponse<T>.
  • Hooks (src/hooks/) kapseln React Query; Stale-Zeiten kommen aus src/lib/constants.ts.
  • Komponenten (src/components/, src/pages/) sind reine Darstellung.

Drei geschützte Arbeitsbereiche: /supply/* (Bewirtschaftung), /demand/* (Suche), /ops/* (interner Betrieb).


Property On — «Teamübersicht»

Property On ist als Funktionsbereich in Property Match eingebettet, nicht als eigene Anwendung. Es gibt keine zweite App-Shell, keine zweite Sidebar und kein eigenes Branding. Erreichbar über den Hauptreiter Teamübersicht in der Bewirtschaftungs-Navigation, mit den Subreitern Personalverwaltung, Bearbeitungsverlauf und Kanäle & Systeme.

Bedienprinzip: human-led, agent-operated. Sieben digitale Mitarbeiter führen Arbeiten aus, der Mensch gibt frei, passt an oder weist zurück. Jede Entscheidung erzeugt einen Protokolleintrag, aktualisiert die Kennzahlen und meldet sich mit einer Rückmeldung.

Routen

/supply/team                                            Teamübersicht (Startseite)
/supply/team/personalverwaltung                         Agentenliste + Dossier
/supply/team/personalverwaltung/:agentId                Personalblatt
/supply/team/personalverwaltung/:agentId/:tab           Dossier-Reiter, deep-linkbar
                                                        tab: aufgaben | kanaele | systeme
                                                             einstellungen | protokoll
/supply/team/bearbeitungsverlauf                        Vorgänge
/supply/team/bearbeitungsverlauf/:tab                   tab: pendente-anfragen | erledigte-auftraege
/supply/team/kanaele-systeme                            Verbindungen der Organisation

Architekturentscheidungen

Der Entitätstyp heisst TeamAgent, nicht Agent. Im Repo existiert bereits PowerOn als Name des KI-Backend-Proxys, und Claude Code legt Arbeitskopien unter agent-* ab. Ein nackter Typ Agent wäre in Suchen praktisch nicht auffindbar. Alle Satellitentypen tragen das Präfix Agent*AgentStatus, AgentChannelType, AgentProtocolEntry —, weil src/domain/index.ts per export * bündelt und generische Namen dort kollidieren würden.

Eigener Protokolltyp statt ActivityEvent. Den Namen gibt es im Repo dreifach und gegenseitig inkompatibel: in domain/activityEvent.ts, lokal in services/governanceService.ts und noch einmal in components/supply/PropertyActivityLogPanel.tsx. Ein Anschluss an einen dieser Typen hätte den Konflikt zementiert; AgentProtocolEntry steht bewusst daneben.

Verbindungen sind von DataSource getrennt. DataSource/ConnectorRun modelliert Crawler-Quellen mit AGB-Status und Crawl-Läufen. «Kanäle & Systeme» beschreibt angebundene Kommunikationskanäle und Fachsysteme — fachlich etwas anderes. Die Ops-Komponenten dienten als visuelles Vorbild, das Datenmodell ist eigenständig.

Eine Demo-Uhr statt der Systemzeit (src/lib/teamClock.ts). Die Mockdaten sind fachlich auf den 20.05.2026 verankert. Gegen die echte Systemzeit gerechnet wären die Zeitraumfilter «heute / diese Woche / dieser Monat» an jedem anderen Kalendertag leer, und die Auswertung sähe kaputt aus, obwohl sie korrekt arbeitet. Die Demo-Uhr startet am Anker und läuft ab Anwendungsstart in Echtzeit weiter — jede Freigabe während einer Vorführung landet damit verlässlich im Bucket «heute». Sie gilt ausschliesslich für Property On.

Persistenz liegt in der Providerschicht. Geänderte Einstellungen, Aufgabenschalter, erledigte Vorgänge, Verbindungsstatus und pausierte Mitarbeiter überleben einen Reload über den Local Storage. Die Bestände tragen eine Schemaversion (TEAM_SCHEMA_VERSION): passt sie nicht, greift wieder der Seed aus src/mock-data/ — sonst überlagerte ein alter Eintrag stillschweigend geänderte Mockdaten. «Demo zurücksetzen» löscht genau diese Schlüssel.

Subreiter sind echte Routen, keine lokalen Tabs. Die Anwendung kannte bis dahin keine Feature-Route mit eigenem <Outlet/>, und Tabs werden sonst über lokalen useState gebaut. Hier war das nicht tragfähig: die drei Subreiter müssen in der Sidebar sichtbar sein und deep-linkbar bleiben. Das NavItem-Modell in appShellConfig.ts wurde deshalb um children erweitert; die Routen sind flache Geschwister, kein Outlet-Baum.

Kein neuer Stack. Der ursprüngliche Auftrag nannte shadcn/ui, React Hook Form, date-fns und Playwright. Nichts davon ist installiert, und die Vorgabe, die bestehenden Property-Match-Muster zu übernehmen, wiegt schwerer. Umgesetzt mit MUI v9, TanStack Query, Zustand und Zod; Datumsformatierung über Intl in src/lib/utils.ts und src/lib/teamClock.ts. Besonders relevant: Tailwind-Preflight ist bewusst nicht importiert — shadcn erwartet es und würde den CssBaseline-Reset von MUI überschreiben.

Simulation

Alles ist Frontend-Simulation. Es gibt keine echten Systemverbindungen, keine echten Zugangsdaten und keine echten Modellaufrufe. Simulierte Ladezeiten liegen zwischen 300 und 800 ms. Der Test einer Verbindung ist deterministisch und nicht zufällig: verbundene Kanäle gelingen, nicht verbundene und geplante scheitern reproduzierbar — ein Zufallsfehler würde eine Kundendemo unvorhersehbar machen.

Bekannte Altlasten

  • npm run check:tokens liegt bei 2249 rohen Hex-Werten über dem Schwellwert von 1958. Der Wert stammt vollständig aus dem Bestand; Property On hat null hinzugefügt. Der Schwellwert darf laut Skript nicht angehoben werden.
  • npm run lint meldet im Bestand weiterhin Fehler und Warnungen. Der Property-On-Code ist frei davon: npx eslint src/components/team src/pages/supply/Teamuebersicht.tsx … ist grün.
  • In tsconfig ist strict entgegen CLAUDE.md §14 nicht gesetzt; strictNullChecks fehlt damit projektweit.
S
Description
No description provided
Readme 7.8 MiB
Languages
TypeScript 99.7%
CSS 0.2%
JavaScript 0.1%