88 lines
4.7 KiB
Markdown
88 lines
4.7 KiB
Markdown
# M089 — KWP-API-Connector (REST/OAuth über Apps-Engine)
|
||
|
||
**Block:** Block 4 · Modul 19
|
||
**Pflichtenheft-Quelle:** block4.md Modul 19 + Bauprinzip A.18 · **Re-Cut 2026-06-04 (KWP-API), siehe `docs/milestones/M19-KWP-API-RECUT.md`**
|
||
|
||
## Ziel
|
||
First-Party-Connector für die offizielle **KWP-REST-API**, aufgesetzt auf das M33a-Adapter-Interface. Eine `App{type:"kwp"}` + eine `DataConnection{type:"rest-api"|"oauth2"}` pro KWP-Server; API-Credentials verschlüsselt in `DataConnection.config` (Per-Tenant-DEK, AD-8). Ausgehende Calls via `adapterFetch()` (HTTPS-only, SSRF-Guard). Implementiert `connect / disconnect / validateConnection / syncPull / syncPush / handleWebhook`.
|
||
|
||
## Was sich durch die KWP-API ändert (Re-Cut)
|
||
- **Der ursprüngliche Windows-Client (`kwpsync.exe` + NSSM + MSSQL-Direktzugriff + DPAPI + Auto-Update) entfällt komplett.** Kein externes Programm mehr — der Connector lebt im Monorepo (`app/domain/integrations/kwp/**`).
|
||
- KWP wird ein **regulärer `rest-api`-Adapter** statt `windows_client`-Sonderweg; passt direkt ins `appsEngine.prisma`-Muster.
|
||
|
||
## Abhängigkeiten
|
||
- **Vorbedingung:** M008–M010 (M33a Adapter-Interface — `connect/syncPull/syncPush/...`, harte Vorbedingung); AD-8 (Per-Tenant-DEK)
|
||
- **Offen/blockierend:** konkreter **KWP-API-Vertrag** (Auth, Endpoints, Rate-Limits, Webhooks, Versionierung) — vor Detail-Planung mit KWP klären (siehe RECUT-Doku)
|
||
- **Wird benötigt von:** M090–M095
|
||
|
||
## Out of Scope
|
||
- `kwpsync.exe` / Windows-Service / NSSM / MSSQL-Direktzugriff (durch API obsolet)
|
||
- Andere ERPs (Taifun, TopKontor) → Phase 2
|
||
|
||
## Erfolgskriterium
|
||
KWP-App via Setup verbunden; `validateConnection` liefert grün; Test-`syncPull` liefert einen KWP-Datensatz; Test-`syncPush` schreibt einen Datensatz via API nach KWP; alles als `AppSyncRun`/`AppSyncItem` protokolliert.
|
||
|
||
## Hinweise für Slice-Planung
|
||
- Connector als reines Domain-Modul (`app/domain/integrations/kwp/**`), Layer-Trennung (AGENTS.md)
|
||
- `appsEngine.prisma`-Modelle nutzen; KWP-spezifische Modelle in eigenem `prisma/schema/kwp.prisma`
|
||
- Mapping HiveGrid↔KWP via `AppSyncItem`; Idempotenz via `IdempotencyKey`
|
||
|
||
|
||
---
|
||
|
||
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
|
||
|
||
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
|
||
|
||
### Erreichbarkeit
|
||
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
|
||
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
|
||
- [ ] **Breadcrumb** für Detail-Routes (§4)
|
||
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
|
||
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
|
||
|
||
### Querschnitt-Wiring
|
||
- [ ] **Audit** läuft (auto via M001 oder manuell)
|
||
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
|
||
- [ ] **Notifications** via `notify()` (M011), nicht direkt
|
||
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
|
||
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
|
||
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
|
||
|
||
### Code-Layer-Disziplin (PR-Block)
|
||
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
|
||
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
|
||
- [ ] Subframe-Output via Adapter, nicht direkt importiert
|
||
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
|
||
|
||
### Tests
|
||
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
|
||
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
|
||
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
|
||
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
|
||
|
||
### Klartext (User-facing)
|
||
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
|
||
- [ ] Empty-State mit Klartext + nächster Aktion
|
||
- [ ] Loading-State mit Klartext (kein leerer Spinner)
|
||
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
|
||
|
||
### Rollback-Pfad
|
||
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
|
||
- [ ] **Atomic-Slice-Commits** (TC-Default)
|
||
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
|
||
|
||
---
|
||
|
||
## Klick-Pfad zum Prüfen (für User)
|
||
|
||
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
|
||
|
||
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
|
||
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
|
||
3. Hauptaktion ausführen
|
||
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
|
||
|
||
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
|
||
|