Files
web-cad/umbauplan-v2.md
T

13 KiB
Raw Blame History

Umbauplan web-cad v2.0 — Plugin-first, WebGL, Voll-CAD

⚠️ STATUS: ARCHIVIERTE PLANREFERENZ — Die operative Umsetzung läuft über ROADMAP.md (Tasks mit exakten Arbeitsschritten, Status, Fortschritts-Log). Dieses Dokument bleibt als Begründung/Kontext stehen: Warum welche Entscheidungen getroffen wurden, Marktvergleich, Risikoanalyse. Bei Abweichungen gilt immer ROADMAP.md.

Stand: 2026-08-26 · Basis: Commit 126277a (main)

Zielbild

Web-CAD im Umfang einer Standard-2D-CAD-Software mit Event-Fokus:

  • Alle Werkzeuge sind Plugins — auch Kern-Werkzeuge (built-in Plugins haben keinen Sonderstatus mehr)
  • WebGL-Renderer (PixiJS) für große Pläne (50.000+ Elemente bei 60fps)
  • Branchenneutrale Basis: Grundrisse, Gelände, Flächen — nicht nur Veranstaltungen
  • Library als First-Class-System, erweiterbar durch Plugin-Kataloge
  • Zwei Bedienmodi: „Einfach“ für Einsteiger, „Pro“ für CAD-Anwender

Architektur-Grundsätze

  1. Core = Kernel only: Datenmodell (CADElement/Layer), SpatialIndex, ZoomPan, History, Yjs-Sync, CommandRegistry, PluginRegistry. Kein einziges konkretes Werkzeug im Kernel.
  2. Werkzeug = Plugin: Jedes Werkzeug implementiert ToolExtensionV2 mit eigenem Event-Zustand (onPointerDown/Move/Up/Key/Cancel), eigener Live-Vorschau über RenderAdapter-Overlay und Optionsleiste.
  3. InteractionEngine wird Dispatcher: Sie besitzt nur noch Event-Routing, aktives Tool delegieren, Undo-Transaktionen kapseln. Der aktuelle 1157-Zeilen-switch fällt weg.
  4. RenderAdapter als Schnittstelle: Alles Rendern läuft gegen eine schmale API (clear/draw*/overlay/hitTest), Implementierung PixiJS. Canvas2D entfällt (keine produktiven Nutzer → kein Legacy-Pfad).
  5. Backend spiegelt Plugin-Lifecycle: installierte Plugins, Versionen, Aktivierung pro Mandant/User in SQLite; Plugin-Bundles als ZIP mit Frontend-Code + optionalen Backend-Routen (sandboxed, manifest-signiert).
  6. Datenmodell offen für Branchen: element.type bleibt string; unbekannte Typen werden vom registrierenden Plugin gerendert (bereits vorhanden, wird zur Pflicht).

Phase A — Plugin-first Refactoring (Kernel) · ca. 2 Wochen

A1 Plugin-API v2 (frontend/src/plugins/types.ts)

  • ToolExtensionV2: id, label, icon, ribbonTab, shortcut, cursor, optionsSchema (PropertyFields für Optionsleiste), handlers: { onPointerDown/Move/Up/KeyDown/Cancel }, preview(adapter, state), commit() -> Operation[] (für Undo als eine Transaktion)
  • PanelExtension: eigene Sidebar-Panels (z.B. Bestuhlungsplaner, Gästeliste)
  • LibraryProviderExtension: liefert Kataloge (siehe Phase F)
  • SnapProviderExtension: zusätzliche Fangpunkte (z.B. Tangente eines Plugin-Elements)
  • ImportExportExtension behalten, um formatId, mime, export(doc), import(data) erweitern
  • Manifest: category erweitert um 'library'; neue Felder minAppVersion, permissions[] (canvas, network, storage)

A2 InteractionEngine zum Dispatcher umbauen

  • Neuer Vertrag: setTool(toolId) holt Tool aus PluginRegistry statt internem Switch
  • Undo/Redo: jedes Tool-commit wird eine HistoryManager-Transaktion (heute inkonsistent)
  • CommandRegistry bleibt; Commands aus Plugins bereits vorhanden
  • RibbonBar rendert dynamisch aus Registry (getToolExtensions() gruppiert nach ribbonTab) — Tabs bleiben konfigurierbar

A3 Kern-Tools als built-in Plugins migrieren

Plugin-Paket Inhalt
core-drawing line, polyline, rect, circle, arc, polygon, point, xline, ray, ellipse, spline
core-modify select, move, copy, rotate, scale, mirror, trim, extend, fillet, chamfer, offset, stretch, break, join, explode, align, array-rect, array-polar, array-path
core-annotate text, mtext, dimension-linear/-angular/-radial, leader, revcloud, hatch
core-measure measure, distance-info, area-info
event-tools chair, seating-row, seating-block, table, stage, templates (bestehend, erweitert)

Akzeptanz: interaction/index.ts < 300 LOC (nur Routing); alle 380 bestehenden Tests grün; Ribbon zeigt identische Werkzeuge wie zuvor.

A4 Backend: Plugin-Registrierung

  • SQLite-Tabelle plugins(id, version, enabled_default, installed_at) + plugin_settings(plugin_id, scope, scope_id, json)
  • REST /api/plugins (list), /api/plugins/:id/settings (GET/PUT), Admin-Upload /api/plugins/install (ZIP)
  • Websocket-Event pluginStateChanged → Clients aktivieren/deaktivieren live

Phase B — Bugfixes (sofort, unabhängig) · 23 Tage

  1. seatingService.ts: rowId/blockId via UUID-Counter statt Date.now(); Block-Reihen erhalten eigene rowId
  2. geometry.ts findIntersection: LineCircle, CircleCircle, LineArc ergänzen (trim/extend/fillet funktionieren dann auf Kreisen/Bögen)
  3. Offset-Tool: Richtungssinn aus zweitem Klick (Vorzeichen der Seitigkeit per Kreuzprodukt)
  4. RenderEngine.drawBackground: Bild cachen (einmal laden), kein img.onload → render() pro Frame
  5. countSeats: byRow auch für Blöcke korrekt

Jeder Fix mit Unit-Test. Diese Phase läuft parallel zu A und ändert Dateien, die B später ohnehin anfasst (Konflikt klein halten durch Reihenfolge: erst B, dann A-Migration je Tool).


Phase C — WebGL-Renderer (PixiJS) · 35 Wochen

C1 RenderAdapter-Schnittstelle (frontend/src/render/types.ts)

interface RenderAdapter {
  init(canvas), resize(w,h,dpr), setViewport(vp), destroy()
  beginFrame(), endFrame()
  drawGrid(cfg), drawBackground(img,cfg), drawRuler(cfg)
  drawElement(el, layerStyle, scale)
  drawPreview(el), drawSelection(el, handles), drawSnapPoints(pts)
  drawOverlay(fn)   // Freihand-Overlays von Tools (Gummibänder, Arc-Row-Vorschau)
}

C2 PixiJS-Implementierung

  • Layer-Konzept: Graphics pro CAD-Layer, statische Elemente in Container mit Cache-as-Texture, dynamisches (Selection/Snap/Preview) in Overlay-Layer
  • Text: PIXI.Text/BitmapText; Dimensionen als Graphics + Label
  • Chair/Table/Stage: Texture-Atlas (einmal generiert, tausendfach instanziert) — der große Performance-Hebel für Bestuhlung
  • Grid/Ruler als getrennte Ticker-Layer, DPR-korrekt
  • Hintergrundbild als Sprite (löst gleichzeitig Bug #4 endgültig)

C3 Kompatibilität Plugin-Element-Renderer

  • ElementTypeExtension.render(ctx) erhält Adapter-Wrapper: zeichnet in Offscreen-Canvas → Texture.from(canvas) → Sprite. Bestehende Event-Elemente (curtain, spotlight, barrier) laufen unverändert weiter; später können Plugins nativen Pixi-Renderer liefern (renderPixi?).

C4 Tests & Benchmarks

  • 29 RenderEngine-Tests auf Adapter-Mock umschreiben (ca. 1 Tag Aufwand)
  • PerformanceBenchmark neu: 10k / 25k / 50k Chairs, Zielschwelle 60fps (Playwright + trace)
  • Feature-Flag renderer=webgl während Migration, danach Flag entfernen

Akzeptanz: visuelle Parität zu Canvas2D (Screenshot-Vergleichstests), 50k Chairs @60fps auf Referenz-Hardware, alle Tests grün.


Phase D — CAD-Werkzeuge komplettieren (alles Plugins) · 34 Wochen

D1 core-drawing Ergänzungen

  • Ellipse + Ellipsenbogen (Achsen-, Rotations-Eingabe)
  • Spline: Bézier (CV-Kontrolle) + Glättungs-Polyline-Interpolation; Speicherung als Kontrollpunkte
  • Punkt, Konstruktionslinien (XLine/Ray, eigene Layer-Klasse „construction“)
  • MTEXT: mehrzeilig, Inline-Formatierung (fett/kursiv/Größe), Autowrap-Box

D2 core-modify Ergänzungen

  • Stretch (Fenster über Polygonecken, Endpunkte verschieben)
  • Break (Element am Punkt teilen), Join (kollineare Segmente/Polylines fusionieren)
  • Chamfer (wie Fillet, gerade Kante), Explode (Block→Einzelelemente, Polyline→Segmente)
  • Align (2-Punkt-Ausrichtung inkl. Skalierung optional)
  • Lengthen (DElta/Total/Dynamisch)
  • Polyline-Editor: Segment hinzufügen/löschen, Kurven glätten, Breite
  • Grip-Editing: Ankerpunkte (Endpunkte/Mitte/Centre) direkt ziehen — großer Bedienkomfort-Gewinn

D3 Arrays

  • Rechteckig (Zeilen×Spalten×Abstände), Polar (Zentrum, Anzahl, Winkel, rotieren ja/nein), Pfad (entlang Polyline/Arc) — für Bestuhlung kritisch

D4 Snaps erweitern (SnapEngine + SnapProviderExtension)

  • Tangente, Senkrecht, Parallel, Quadrant, Center, Knoten, From-Offset (Basispunkt+Versatz)

D5 Block-Attribute

  • Datenmodell: Blockdefinition mit attrDefs[], Instanz mit attrValues[]
  • Editor-UI (Attribut-Formular beim Einfügen), Anzeige im RenderAdapter
  • DXF-Interop: ATTDEF/ATTR lesen/schreiben (Phase F nutzt es)

Phase E — Event-Domain ausbauen · 2 Wochen

  1. Interaktives Bestuhlungs-Werkzeug (im event-tools Plugin): Klick-Drag definiert Reihe/Block, Live-Vorschau via Overlay, Parameter (Anzahl, Abstand, Kurvenradius) in Optionsleiste
  2. Arc-Rows: Reihen entlang Kreisbogen um Bühnenpunkt (Radius, Winkelspread, Versatz)
  3. Sitzplatzzählung robust: byRow/byBlock/byZone, Summen in StatusBar, Klick auf Zahl highlightet Reihe
  4. Vorlagenkatalog: Kino, Bankett-Rundtische, Stehtische, Podeste, Parlamentarisch, U-Form
  5. Sitzplatzliste export (CSV/XLSX: Reihe, Platz, Zone, Gast optional)
  6. Optional (Backend): guests-Tabelle + Zuordnung seatId↔guest, CSV-Import — Vorbereitung Social-Tables-ähnlicher Funktion
  7. Event-Elemente veredeln: Bühne (mit Höhen-Angabe), Vorhang, Scheinwerfer (Farbe/Winkel), Barrieren (Kettenstücke), Fluchtweg-Signaturen

Phase F — Library-System & Import/Export · 23 Wochen

F1 Library-Kern

  • Backend-Schema erweitern: library_folders (Baum, Mandant-scope), library_blocks (+ tags, thumbnail, attrDefs, source: builtin/user/plugin)
  • Suche (Name/Tags), Favoriten pro User, Drag-Drop ins Canvas, „Als Block speichern“ aus Auswahl
  • Thumbnail-Generierung client-seitig beim Speichern (kleines PNG dataURL)

F2 Library-Plugins

  • LibraryProviderExtension: id, label, listFolders(), listBlocks(folder), getBlock(id)
  • Built-in Provider: builtin-catalog (mitgelieferte Kataloge: event, architecture, landscape), user-library, global-library
  • Plugin-Katalog-Pakete liefern Provider + Blöcke (Beispiel: „messe-plugin“ mit Standwand-Katalog)

F3 Import

  • DXF: Parser erweitern um ELLIPSE, SPLINE, MTEXT, POINT, HATCH (Basis), ATTDEF/ATTR; INSERT→Blockdefinition + Instanz; Layer-Mapping
  • SVG→Block (Vektor in Elemente konvertieren oder als referenzierter Render-Typ)
  • Bibliotheks-Pakete .wcadlib (ZIP: manifest.json + blocks.json + thumbnails) importieren
  • PNG/JPG als Hintergrund (vorhanden) + PDF-Unterlage beibehalten

F4 Export

  • .wcadlib Paket-Export (eigene Bibliothek teilen)
  • DXF-Export mit BLOCKS/INSERTS (Austausch mit AutoCAD/LibreCAD)
  • Bestehende Formate behalten: SVG, PDF, JSON

Phase G — Layouts & Plot (Standard-CAD-Niveau) · 2 Wochen

  1. Paperspace/Layouts: mehrere Layouts pro Zeichnung, Viewports mit Maßstab 1:1…1:500, Rahmen/Titelblock als Block mit Attributen (Projekt, Datum, Maßstab, Bearbeiter)
  2. PDF-Export pro Layout in echtem Ausgabemaßstab (pdf-lib vorhanden)
  3. Plot-Stil: Linienstärken nach Farbe/Layer, monochrom-Option
  4. Drucken über Browser-Print (CSS @page) zusätzlich

Phase H — Branchenneutralität & Einfachheit · 12 Wochen

  1. Modus „Einfach/Pro“: User-Setting; Simple-Mode blendet Ribbon nach tool.tags:['basic'] (Auswahl, Stühle, Vorlagen, Text, Maß), versteckt CommandLine/Layer-Tiefe; Pro zeigt alles. Gleiche Engine, gleiche Daten.
  2. Projekt-Templates: Halle, Open Air, Saal, Messehalle, Bürogrundriss, Garten/Gelände — Template aktiviert passende Bibliotheks-Ordner + Plugin-Set + Rastermaßstab (m/cm/ft)
  3. Rollen: Library-Admin (global bearbeiten) vs. Nutzer (lesen, eigene Ordner) — an bestehendes 4-Rollen-Auth andocken
  4. i18n-Vorbereitung: Strings zentral (de/en), UI-Texte aus Bundle
  5. Gelände-Tauglichkeit: Polygon-Flächen mit Flächenberechnung (m²), Hang-/Höhen-Annotation als Text/Leader reicht v1; GIS-Anbindung bewusst out-of-scope

Phase I — Qualität, CI, Release · 1 Woche

  • CI (Forgejo Actions): lint + tsc + vitest (FE 400+/BE 255+) + Playwright-Smoke + Performance-Gate (50k@60fps)
  • Test-Deckung Tools: jede ToolExtension braucht Workflow-Test (ziehen, snappen, committen, undo)
  • Docker/Coolify unverändert; Migrations-Scripte für SQLite-Schema (plugins, library, guests, layouts)
  • Docs: Plugin-Entwickler-Guide (API v2), Library-Paket-Spec, Changelog 2.0

Meilensteine & Timeline

Milestone Inhalt ca. Woche
M1 Phase B Bugfixes + A Plugin-first Kernel, Ribbon dynamisch 2
M2 C WebGL live hinter Flag, Parität + Benchmarks grün 6
M3 D volle Werkzeugpalette (Ellipse/Spline/Array/Grip/Attribute) 10
M4 E Event-Domain + F Library/Import-Export fertig 13
M5 G Layouts/PDF + H Modi/Templates + I Release 2.0 1617

Einzelarbeit ~4 Monate. Parallelisierung (z.B. B+C ein Track, D+F zweiter Track) verkürzt auf ~3 Monate.

Risiken

  1. PixiJS-Textqualität bei Dimensionen → früh Screenshot-Paritätstest, ggf. DOM-Overlay für Labels
  2. Plugin-Sandboxing (fremder Code im Browser) → v2 nur Admin-installierte, signierte Bundles; CSP; später Worker-Isolation
  3. DXF-Sonderfälle (SPLINE-Grad, HATCH-Grenzen) → Grenzen dokumentieren, Fehlertoleranz-Importer mit Report
  4. Yjs + Layouts → Layouts als Yjs-Map pro Projekt, Konfliktfreiheit gegeben

Offene Entscheidungen

  • PixiJS vs. Three.js-2D-Mode → Empfehlung PixiJS (Szene-Graph, Texture-Atlasten, kleiner)
  • Fremd-Plugins sofort erlaubt? → Empfehlung nein (nur first-party bis M5)
  • Gästemodul (E6) in 2.0 oder 2.1? → Empfehlung 2.1