Files
HiveGrid-Wireframes/hivegrid-cloud/docs/boilerplate-mapping/M19-kwp-integration.md
T

22 KiB

Boilerplate-Abgleich: M19 — KWP-Integration

Feld Wert
Modul-ID M19
Name KWP-Integration
Milestones M089 (Sync-Programm), M090 (Heartbeat+Recovery), M091 (Warteschlange+Replay), M092 (Schema-Drift-Sentinel), M093 (Konflikt-Auflösung „KWP gewinnt"), M094 (Plantafel-Sync), M095 (Dokumenten-Archiv-Sync)
Block Block 4 — USP-Säulen (Modul 19), sitzt auf M33a Apps-Engine (M008-M010)
Reuse-Level medium

Verifikations-Basis: Eigene Greps/Reads direkt in /Users/raffaelsheikh/Documents/GitHub/boilerplate (nicht nur Inventur). Wo Inventur und Realität abweichen, ist das markiert.


Kernbefund in einem Satz

Die Boilerplate hat kein KWP-, MSSQL-, Heartbeat-, Schema-Drift- oder Windows-Sync-Code (grep über *.ts/*.prisma leer außer einem Test-Match in packages/cli). Was sie liefert, ist ein solides Querschnitt-Fundament: ein generisches Data-Sync-Datenmodell (appsEngine.prisma), eine Public-API-Runtime mit Tenant-API-Key/Webhook-Auth (apps/api), eine Cron+Queue-Worker-Runtime mit Transactional-Outbox (apps/worker), gehashte API-Keys (core.prisma), Idempotenz, Storage/Signed-URLs und Notifications. Die gesamte KWP-Fachlogik (Queue-Semantik, Mapping-Registry, Drift-Diff, Konflikt-Default „KWP gewinnt", Projektnummern-Sequenz/Reservierung) ist neu zu bauen.


Übernehmbar aus Boilerplate

Boilerplate-Pfad Was Wie nutzbar
prisma/schema/appsEngine.prisma App, DataConnection, AppSyncRun, AppSyncRunLog, AppSyncItem — generische Data-Sync-Engine mit Status/Mode/Metriken + Source→Destination-Mapping + Rollback-Daten anpassen — deckt KwpSettings (als App/DataConnection), KwpProjectQueue/Sync-Lauf (als AppSyncRun) und KwpRegistry (als AppSyncItem) teilweise ab; KWP-spezifische Felder fehlen (s.u.)
prisma/schema/core.prisma → ApiKey + ApiKeyLog Gehashte Keys (keyHash/keyPrefix/keyLastFour/keyVersion/hashedAt/expires/active), @@unique([tenantId, alias]), Request-Logging 1:1 für KwpApiKey (Token-Auth des kwpsync.exe bzw. KWP-API). Rotation/Expiry-Felder vorhanden
prisma/schema/core.prisma → IdempotencyKey @@unique([scope, key]), Response-Caching, expiresAt 1:1 für die in der Spec geforderte idempotency_key-Doppel-Push-Erkennung (Block D)
prisma/schema/core.prisma → FileObject (+ FileUploadProgress/FileChunk) Storage-Metadaten (provider/bucket/key/checksum/byteSize/metadata Json) anpassen — Basis für KwpDocument/Dokumenten-Archiv-Sync (M095); KWP-Herkunfts-Felder (direction, kwp_path, gelöscht-Badge) ergänzen
apps/api (@toolctrl/api, Hono) + apps/api/src/route-access-inventory.ts Public-API-Runtime mit Auth-Klassen tenant-api-key, service-token, webhook-signature, optional-api-key-validation; apps/api/src/auth.ts (extractApiKeyFromRequest, extractBearerToken, createServicePrincipal); Error-Envelope + Request-ID als-vorlage / anpassen — exakt die Ingress-Schicht für /api/v1/integrations/kwp/queue/{token}/... (Pull/Push/Heartbeat). Neue Routes + Auth-Klasse für den kwpsync-Token andocken
apps/api/src/webhooks/mailersend-signature.ts, billing/stripe-webhook-route.ts, email-sequences/provider-webhook-route.ts Bestehende inbound-Webhook-Handler mit Signatur-Verifikation als-vorlage — Muster für handleWebhook (kwpsync.exe pusht Delta + Heartbeat) bzw. KWP-API-Webhook
apps/worker (@toolctrl/worker) + apps/worker/src/jobs/*-cron.ts Cron+Queue-Runtime, single-instance Cron-Scheduler (Bsp. dsgvo-grace-cron.ts 24h, plugin-audit-retention nächtlich), DI-HandlerDependencies, Health/Admin-Server als-vorlage — für Daily-Schema-Drift-Check (M092), Heartbeat-Watchdog (M090), Rate-Limited-Replay-Worker (M091). Neuen Queue-Namen + Handler registrieren
apps/worker/src/outbox/{dispatcher,event-router}.ts + prisma/schema/outbox.prisma Transactional-Outbox: Event in DB-Tx committen, Worker fan-out per Prefix-Routing (longest-prefix-wins), Exponential-Backoff-Retry, DLQ anpassen — Push aus HiveGrid → KWP-Queue als Outbox-Event (kwp.push.* Prefix-Routing ergänzen). Garantiert „nichts geht verloren" (Spec 19.3.3) ohne eigene Queue-Mechanik
packages/queue (@toolctrl/queue) BullMQ-Wrapper: enqueueJob, buildIdempotentJobId(), plan-basierte Prioritäten (resolveJobPriorityForTenant), Idempotenz 1:1 / anpassen — Cloud-Queue-Verarbeitung + Idempotenz. Neuer Queue-Name toolctrl.kwp-sync o.ä. hinzufügen (Queue-Namen sind hartcodiert in packages/queue/src/names.ts)
packages/foundation/src/adapters.ts defineAdapter()/getAdapter() + AdapterStatus = not_configured|configured|healthy|degraded|unavailable anpassen — die 5 Status-Werte mappen direkt auf die M33a-/Spec-Status (wartet auf Setup/aktiv/eingeschränkt/defekt/getrennt). ACHTUNG: das ist nur eine 18-Zeilen-Status-Registry, kein Sync-Connector-Framework — siehe „Lücken"
packages/storage (@toolctrl/storage) S3/Scaleway-Adapter, Signed-Upload/Download-URLs, Virus-Scan (ClamAV + magic-bytes), Quarantäne 1:1 für Dokumenten-Archiv-Sync (M095) — KWP-Dokumente in Scaleway-S3 ablegen, Signed-URLs zum Lesen/Download
packages/marketing-outbound/src/types.ts → adapterFetch() + SSRF-Guard Timeout + SSRF-Allowlist (nur HTTPS, kein RFC1918/metadata) für ausgehende HTTP-Calls als-vorlage — falls die KWP-API direkt von HiveGrid Cloud aufgerufen wird (API-Variante, s.u.), als sicherer HTTP-Egress
packages/realtime (@toolctrl/realtime) SSE-Event-Serialisierung (notification.snapshot/update) 1:1 für sichtbaren Re-Sync-Fortschritt („847/1.230 abgearbeitet") und Live-Status-Indicator
packages/db/generated/prisma/client/models/{App,DataConnection,AppSyncRun,AppSyncRunLog,AppSyncItem}.ts Generierter Prisma-Client für die Apps-Engine-Modelle (bereits vorhanden) 1:1 — Modelle sind generiert und tenant-relation-verdrahtet; sofort nutzbar

Vorhandene Daten-Modelle (konkret, mit Pfad)

Direkt für M19 relevante, bereits existierende Prisma-Modelle:

  • prisma/schema/appsEngine.prisma
    • App (tenantId, type-Identifier, config JSON-String, isActive, installedByUserId, @@unique([tenantId, type])) → Basis für „KWP-App ist installiert" + KwpSettings.enabled_features
    • DataConnection (tenantId, name (sprechender Name „Geerkens Hauptbüro KWP"), type z.B. "rest-api"/"webhook", config = verschlüsselte JSON-Credentials) → Basis für KwpSettings/data_connection_id
    • AppSyncRun (status pending/running/completed/partial/failed/cancelled/reverted, executionMode manual/scheduled/webhook, itemsProcessed/Created/Updated/Failed, startedAt/completedAt, error, metadata JSON) → Basis für Sync-Lauf-Historie + M33a-Sync-Verlauf
    • AppSyncRunLog (type info/success/warning/error, message, metadata) → Klartext-Log pro Sync-Vorgang (M33a.4.2)
    • AppSyncItem (objectType, sourceId, destinationId, action, sourceData/destinationData JSON, status, rolledBackData/rolledBackAt, @@index([objectType, sourceId])) → Basis für KwpRegistry-Mapping + Konflikt-Restore (M093)
  • prisma/schema/core.prisma
    • ApiKey + ApiKeyLog → KwpApiKey (gehasht, Rotation, Request-Logging)
    • IdempotencyKey → Idempotenz-Schlüssel der Push-Operationen
    • FileObject / FileUploadProgress / FileChunk → KwpDocument-Storage-Metadaten
    • Credential (globaler Secret-Store, value Json) → falls Cloud-seitige Secrets nötig
  • prisma/schema/featureFlags.prisma → FeatureFlag/FeatureFlagFilter/FeatureFlagAudit (DoD-Pflicht „Modul ohne Deploy abschaltbar")
  • prisma/schema/permissions.prisma → Role/Permission/RolePermission/UserRole (generisches RBAC; die 6 kwp.*-Permissions sind hier zu registrieren, nicht neu zu erfinden)
  • prisma/schema/notifications.prisma → NotificationDelivery/UserNotificationPreference/DeviceToken (Push/Email-Alerts bei broken/drift)
  • prisma/schema/outbox.prisma → OutboxEvent (Transactional-Push-Queue)
  • prisma/schema/workflows.prisma → Workflow/WorkflowExecution/… (M17-Engine; KWP-Trigger kwp.auftrag_pulled/kwp.push_auftrag und KWP-Actions docken hier an, nicht in M19 selbst neu bauen)

Lücken / komplett neu zu bauen

Es existiert KEIN KWP-spezifischer Code. grep über das gesamte Boilerplate-Repo (kwp|KWP|mssql|MSSQL|heartbeat|schema.drift|nssm|sqlserver) liefert nur einen einzigen Treffer in packages/cli/.../doctor.test.ts (unbezogen). Konkret fehlt:

  1. Der komplette kwpsync.exe Windows-Client (Block F). Nichts davon ist in der Boilerplate — kein .NET-/Go-Projekt, kein MSSQL-Treiber, kein NSSM-Wrapper, keine lokale SQLite-Queue, kein DPAPI-Verschlüsselungs-Code, kein Auto-Update. Das ist ein eigenständiges externes Programm außerhalb des Monorepos (M089). (Bei API-Variante entfällt das ganz — siehe KWP-API-Auswirkung.)
  2. defineAdapter ist NICHT das Apps-Engine-Connector-Pattern. Die AGENTS.md-Tabelle (Zeile 134: „Apps-Engine-Adapter | M008-M010 | defineAdapter()") suggeriert ein fertiges Adapter-Framework. Realität: packages/foundation/src/adapters.ts ist eine 18-Zeilen-Status-Registry (Map mit key→status). Das in Spec Block I geforderte Adapter-Interface (connect/disconnect/validateConnection/syncPull/syncPush/handleWebhook + Capabilities) existiert nicht und muss als Teil von M008-M010 (M33a) erst gebaut werden. M19 setzt darauf auf — ist also von M008-M010 blockiert (Vorbedingung steht korrekt in M089).
  3. KWP-spezifische Datenmodelle, die appsEngine.prisma nicht abdeckt:
    • KwpProjectNumberSequence (pro Jahr fortlaufende Auftragsnummern „2026-0042") — komplett neu, kein Sequenz-Modell vorhanden
    • KwpProjectNumberReservation (24h-Reservierung mit expires_at/consumed_at) — komplett neu
    • KwpSchemaSnapshot (schema_hash, tables_metadata JSON für Diff) — komplett neu
    • KwpErrorReport (error_kind schema_drift/connection_lost/sync_conflict/…, severity, summary_text/tech_details, acknowledged_by) — teilweise via AppSyncRunLog, aber Tenant-Acknowledge-Flow + Severity-Filter fehlen → neu
    • KwpSettings-Spezialfelder: kwpsync_token, kwpsync_version, kwpsync_last_heartbeat_at, polling_interval_seconds — als App.config/DataConnection.config-JSON ablegbar oder eigene Felder → anpassen/ergänzen
  4. Sync-Mechanik-Fachlogik (Block D/G/H): Cursor-basierter Delta-Pull, Rate-Limited-Replay (max 100 Ops/Min mit Fortschritt), Konflikt-Default „KWP gewinnt immer" (M093, [N14]) inkl. HiveGrid-eigene-Felder-Schutz, Optimistic-Locking mit version_hash, Last-Known-Stand-Restore. AppSyncRun/AppSyncItem liefern die Tabellen-Hülle, aber keinerlei dieser Algorithmen.
  5. Schema-Drift-Sentinel-Fachlogik (M092): Snapshot-Algorithmus, Hash-Vergleich, Auto-Pause, Plattform-Admin-zuerst-Benachrichtigung, Diff-Tool im Plattform-Admin (M37). Cron-Hülle vorhanden, Logik neu.
  6. Setup-Wizard-UI + alle Routes/View-Models/i18n (Block C). Keine app/routes-Integration, keine ui-hivegrid-Components, kein Sidebar-Eintrag „KWP-Verbindung" (in INTEGRATION-CONTRACTS §1 unter Einstellungen vorgesehen → M089-M095, aber Code existiert nicht). Subframe-Design + Adapter-Layer komplett neu.
  7. Permissions registrieren: kwp.read/connect/manage/manual_sync/disconnect/admin sind in packages/entitlements/src/permissions.ts (HiveGrid-Seite) noch zu definieren; RBAC-Tabellen existieren generisch.
  8. Plantafel-Sync (M094) und Dokumenten-Archiv-Sync (M095) Fachlogik — Storage-/File-Modelle vorhanden, Spiegelungs-Logik (Kunden-Archiv vs. Projekt-Archiv, einseitig, „in KWP gelöscht"-Badge) neu.

Empfohlenes Vorgehen (Reihenfolge)

Phase 0 — Voraussetzung außerhalb M19: Erst M008-M010 (M33a Apps-Engine) bauen — das echte Adapter-Interface (connect/syncPull/syncPush/handleWebhook + Status + Setup-Wizard-Shell). M19 ist davon hart abhängig; defineAdapter reicht NICHT.

  1. Daten-Layer aus Boilerplate übernehmen + KWP-Felder ergänzen: appsEngine.prisma-Modelle als Basis nehmen (App/DataConnection/AppSyncRun/AppSyncItem), ApiKey+IdempotencyKey 1:1 nutzen. Neue Modelle in eigenem prisma/schema/kwp.prisma: KwpProjectNumberSequence, KwpProjectNumberReservation, KwpSchemaSnapshot, KwpErrorReport. Forward-Only-Migration mit Inverse-SQL-Kommentar (DoD F.28).
  2. Querschnitt 1:1 verdrahten, nicht nachbauen: Token-Auth via ApiKey, Idempotenz via IdempotencyKey+buildIdempotentJobId, Push-Queue via Outbox (kwp.push.*-Prefix in event-router.ts), Notifications via notify() (M011), Storage via @toolctrl/storage, Status-5-Werte via foundation/adapters AdapterStatus, Feature-Flag via FeatureFlag.
  3. Ingress-Schicht aus apps/api ableiten: KWP-Queue/Heartbeat/Pull-Endpoints unter /api/v1/integrations/kwp/..., Auth-Klasse tenant-api-key aus route-access-inventory.ts, Webhook-Handler nach Vorbild mailersend-signature.ts.
  4. Worker-Crons aus apps/worker ableiten: Heartbeat-Watchdog (M090), Daily-Schema-Drift (M092), Rate-Limited-Replay (M091) — nach Muster dsgvo-grace-cron.ts; neuen Queue-Namen in packages/queue/src/names.ts registrieren.
  5. KWP-Fachlogik neu bauen (Kern-Aufwand): Mapping-Registry-Semantik auf AppSyncItem, Konflikt-Default „KWP gewinnt" (M093) inkl. Restore aus rolledBackData, Projektnummern-Sequenz/Reservierung, Schema-Snapshot-Diff. Reine Domain-Funktionen in app/domain/** (AGENTS.md Layer-Trennung).
  6. UI komplett neu (Subframe → Adapter → Routes): Setup-Wizard, Status-Dashboard, Sync-Verlauf, Fehlerbericht-Liste, Konflikt-Diff-View. Sidebar-Eintrag „KWP-Verbindung" (Einstellungen-Gruppe), Breadcrumbs, i18n, Smoke-Tests, Visual-Regression — alle DoD-Punkte.
  7. kwpsync.exe als separates Repo/Artefakt (M089) — nur in der Sync-Programm-Variante nötig (siehe nächster Abschnitt).

KWP-API-Auswirkung (Pflicht-Abschnitt — Stand 2026-06-04, NEU/WICHTIG)

Kontext: KWP bekommt jetzt eine offizielle API-Anbindung. Der bisherige Plan (lokaler Windows-Service + NSSM + persistente lokale SQLite-Queue + Schema-Drift-Sentinel, M089-M095) war für KWP OHNE API konzipiert. Die Spec selbst hat das antizipiert (19.11.2: „Native KWP-API … würde die Architektur stark vereinfachen"). Mit API wird aus der Drei-Komponenten-Architektur eine Zwei-Komponenten-Architektur (HiveGrid Cloud ↔ KWP-API direkt), der „Kunde-vor-Ort"-Mittelteil entfällt.

(1) Was die API-Anbindung am Architektur-Plan ändert

  • kwpsync.exe entfällt als Mittelschicht. Statt Cloud → kwpsync.exe (Poll) → MSSQL wird es Cloud → HTTPS → KWP-API. Damit fallen weg: MSSQL-Direktzugriff, DPAPI-Config, lokale SQLite-Queue, NSSM-Service-Wrapper, Auto-Update-Mechanismus, Code-Signing.
  • Aus „windows_client" wird ein Standard-Connection-Type. Die Spec Block I nennt connection_type = windows_client als KWP-Spezialfall. Mit API wird daraus ein regulärer rest-api/oauth2-Adapter — exakt das, was DataConnection.type in appsEngine.prisma ohnehin als Werte vorsieht ("rest-api", "oauth2", "webhook"). Damit passt KWP plötzlich nahtlos ins generische Apps-Engine-Muster statt Sonder-Pattern zu sein.
  • Egress statt Ingress: Statt dass kwpsync.exe in die Cloud pollt, ruft die HiveGrid Cloud die KWP-API aktiv auf. Dafür ist packages/marketing-outbound/src/types.ts → adapterFetch() (HTTPS-only, SSRF-Allowlist, Timeout) die passende sichere HTTP-Egress-Vorlage. Pull wird zu einem normalen Cron-Job (apps/worker), Push zu einem Outbox-getriebenen API-Call.
  • DSGVO-Punkt verschiebt sich: Spec 19.1.2 („KWP-Zugangsdaten liegen lokal beim Kunden, niemals in der Cloud") gilt bei API-Anbindung nicht mehr 1:1 — API-Credentials liegen verschlüsselt in DataConnection.config in der Cloud. Das ist DSGVO-konform (Plattform-Schlüssel, Pflichtenheft 33a.9.3), erfordert aber eine bewusste Neubewertung des „rohe DB-Zugriffe verlassen das Netzwerk nie"-Versprechens.

(2) Welche Milestones M089-M095 sich vereinfachen oder entfallen

Milestone Mit Windows-Sync (alt) Mit KWP-API (neu) Verdict
M089 kwpsync.exe (Win-Service+NSSM) komplettes externes .NET/Go-Programm — ENTFÄLLT (ggf. Restaufwand: API-Connector-Adapter statt Programm, aber innerhalb des Monorepos)
M090 Heartbeat + Auto-Recovery 5-Min-Heartbeat des Clients, 15-Min-Watchdog, Auto-Restart API-validateConnection = einfacher Health-Probe-Call (Spec/M33a haben das ohnehin: aktiv=5min/eingeschränkt=1min/defekt=15min) STARK VEREINFACHT → reduziert auf den generischen M33a-Connection-Health-Check; kein Client-Recovery mehr
M091 Persistente Warteschlange + Replay zwei Queues (Cloud + lokale SQLite), Rate-Limited-Replay nach Outage nur eine Cloud-Queue (Outbox) + Rate-Limit-Replay bei KWP-API-Down VEREINFACHT → lokale SQLite-Queue entfällt komplett; Outbox + packages/queue decken den Rest ab
M092 Schema-Drift-Sentinel Daily-MSSQL-Schema-Snapshot via Client abhängig von API-Vertrag: versionierte API → Drift wird zu API-Versions-/Contract-Check (deutlich leichter); KWP ändert MSSQL nicht mehr „still" hinter dem Rücken VEREINFACHT bis ggf. ENTFÄLLT (bei stabiler versionierter API). Bleibt sinnvoll als API-Response-Schema-Validierung (zod)
M093 Konflikt „KWP gewinnt" unverändert relevant (fachliche Regel, nicht transport-abhängig) unverändert relevant BLEIBT (Domain-Logik, transport-unabhängig)
M094 Plantafel-Sync bidirektional via kwpsync.exe (Poll/Write MSSQL) bidirektional via API (Webhook KWP→HiveGrid + API-Call HiveGrid→KWP) VEREINFACHT falls KWP-API Webhooks bietet (Spec 19.11.3 „Trigger-basierter Pull" wird dann Phase-1-fähig statt Phase-2)
M095 Dokumenten-Archiv-Sync KWP→HiveGrid via Client-Filezugriff KWP→HiveGrid via API-Dokumenten-Endpoint VEREINFACHT (kein lokaler Dateizugriff; @toolctrl/storage + API-Download)

Netto: M089 entfällt, M090/M091/M092/M094/M095 vereinfachen sich teils erheblich, nur M093 (Konflikt-Regel) bleibt unverändert. Der Gesamt-Aufwand des Moduls sinkt deutlich, und das Reuse-Level steigt faktisch von medium Richtung medium-high, weil die generische appsEngine.prisma + apps/api/apps/worker-Fundamente bei einer API-Anbindung direkter passen als beim Windows-Client-Sonderweg.

(3) Wie Apps-Engine/Adapter (defineAdapter, plugins, plugin-sdk) statt des Sync-Programms genutzt werden

  • appsEngine.prisma ist der richtige Boden — nicht das WASM-Plugin-System. Wichtige Abgrenzung (auch in der Inventur betont, integrations-ki.md §4 + „Wichtige Abgrenzungen"): Es gibt zwei „Apps-Engine"-Bedeutungen.
    • packages/plugin-runtime + packages/plugin-sdk = WASM-Sandbox für Drittanbieter-Plugins (Capability-Consent, Ed25519-Signatur, Hook-Lifecycle). In Prod sind nur log+audit-Capabilities freigeschaltet (PLUGIN_AVAILABLE_HOST_CAPABILITY_NAMES), http.outbound/db/storage sind productionAvailable: false. → Für KWP NICHT geeignet: KWP ist ein First-Party-Connector mit DB/HTTP-Bedarf, kein sandboxed Drittanbieter-WASM-Modul. Marketplace ist ohnehin Phase 2 (33a.9.1).
    • prisma/schema/appsEngine.prisma (App/DataConnection/AppSyncRun/AppSyncItem) = die First-Party-Data-Sync-Engine. → Das ist das richtige Fundament für eine KWP-API-App.
  • defineAdapter() (packages/foundation/src/adapters.ts) liefert nur Status-Registry (not_configured/configured/healthy/degraded/unavailable). Diese 5 Werte mappen sauber auf die M33a-Connection-Status. Die eigentliche Connector-Verhaltens-Schnittstelle (connect/syncPull/syncPush/validateConnection/handleWebhook aus Spec Block I) muss in M008-M010 (M33a) gebaut werden; KWP-API ist dann der erste konkrete Adapter dahinter — als rest-api/oauth2-DataConnection.
  • Empfohlene Mapping-Strategie bei API-Variante:
    • KWP-App = App{ type: "kwp" }, eine DataConnection{ type: "rest-api" | "oauth2", config: <verschlüsselte API-Creds> } pro KWP-Server.
    • Token/Key der KWP-API = ApiKey (gehasht) bzw. OAuth-Token in DataConnection.config.
    • Pull-Lauf = AppSyncRun{ executionMode: "scheduled" }; Push-Lauf = AppSyncRun{ executionMode: "webhook"/"manual" }; Mapping HiveGrid↔KWP-Entität = AppSyncItem (sourceId/destinationId); Konflikt-Restore = AppSyncItem.rolledBackData.
    • Connector-Adapter als reines Domain-Modul in app/domain/integrations/kwp/**, das adapterFetch() für Egress nutzt; Cron/Outbox aus apps/worker.
  • Konsequenz für die Planung: Vor Umsetzung von M19 muss der Plan M089-M095 gegen die API neu geschnitten werden (M089 streichen, M090-M092/M094-M095 als API-Adapter-Tasks neu fassen, M093 unverändert lassen). Die Boilerplate unterstützt die API-Variante besser als die ursprünglich geplante Windows-Client-Variante.

Reuse-Level-Begründung: medium

  • Pro (warum nicht low): Komplettes Querschnitt-Fundament vorhanden — Data-Sync-Datenmodell (appsEngine.prisma), gehashte Token (ApiKey), Idempotenz, Outbox-Push-Queue, Cron+Queue-Worker, Public-API-Auth-Schicht, Storage, Notifications, Status-Registry, Feature-Flags, RBAC. Bei API-Anbindung passt das Apps-Engine-Datenmodell sogar direkt (type: "rest-api").
  • Contra (warum nicht high): Null KWP-/ERP-Fachlogik in der Boilerplate. Das in AGENTS.md angedeutete Adapter-Framework (defineAdapter) ist nur eine Status-Map; das echte Connector-Interface (M33a Block I) existiert nicht. Alle KWP-spezifischen Modelle (Projektnummern-Sequenz/Reservierung, Schema-Snapshot, Error-Report), die gesamte Sync-/Konflikt-/Drift-Algorithmik und die komplette UI sind neu. In der Windows-Sync-Variante kommt ein komplettes externes Programm dazu (low-touch zur Boilerplate). In der API-Variante entfällt das und das Modell rutscht praktisch Richtung medium-high.