# 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](./CLAUDE.md), Architekturdiagramme in [ARCHITECTURE.md](./ARCHITECTURE.md), Zustandsregeln in [STATE_MANAGEMENT.md](./STATE_MANAGEMENT.md). ## Starten ```bash 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` / `ItemResponse`. - **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 ``, 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.