docs: roadmap progress phase B complete (B0-B5), log updated
This commit is contained in:
+224
@@ -0,0 +1,224 @@
|
||||
# Umbauplan web-cad v2.0 — Plugin-first, WebGL, Voll-CAD
|
||||
|
||||
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) · 2–3 Tage
|
||||
|
||||
1. `seatingService.ts`: `rowId`/`blockId` via UUID-Counter statt `Date.now()`; Block-Reihen erhalten eigene `rowId`
|
||||
2. `geometry.ts findIntersection`: Line–Circle, Circle–Circle, Line–Arc 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) · 3–5 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) · 3–4 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 · 2–3 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 · 1–2 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 | 16–17 |
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user