Skip to content

Architektura CAD Product Studio & Spreadsheet Auto-Inspector

Dokumentová metadata 🗓️ Datum vytvoření / aktualizace: 2026-09-29 👤 Autor / Architekt: @Jules / Platform Engineering Team 🏷️ Stav: Schváleno (Living Reference Document) 🔗 Vazba na backlog: User Story #27 (CAD Product Studio & Parameter Auto-Inspection), Task #62 (Headless Spreadsheet Parser & Admin Inspection Endpoint), Task #63 (3D Viewport Interface & Studio Integration)


1. Přehled a Kontext (Overview & Scope)

Tento dokument definuje systémovou architekturu a technickou specifikaci pro CAD Product Studio a FreeCAD Spreadsheet Auto-Inspector.

Cílem modulu je automatizovat příjem, analýzu, validaci a konfiguraci parametrů z CAD šablon (.fcstd) v e-commerce / konfigurační platformě COVEROQ CAD Platform.

Hlavní cíle a odpovědnosti:

  1. Headless Auto-Inspekce: Po nahrání souboru .fcstd (prostřednictvím administrátorského rozhraní) systém automaticky extrahuje tabulku proměnných (primárně spreadsheet označený jako Vars).
  2. Dynamická registrace parametrů: Extrahované aliasy buněk, výchozí hodnoty, jednotky, meze (min/max/step) a popisy se transformují na strukturovaná C# DTO schémata a uloží do relační databáze prostřednictvím EF Core.
  3. Skeletové Sestavy & LCS Kotevní Osy (ModelType.Skeleton): Extrakce lokalizovaných souřadnicových systémů (Local Coordinate System - LCS) ze skeletového modelu a asynchronní přepočet kotevních bodů na CAD workeru pro pozicování dílů.
  4. Interaktivní CAD Product Studio (studio.html): Uživatelé a administrátoři mají k dispozici webové Studio s integrovaným 3D viewportem (Three.js), které komunikuje s konfigurátorem v reálném čase via REST / SignalR události.

2. Tok dat a Sekvenční Diagram (Data Flow & Sequence Diagram)

Následující sekvenční diagram zobrazuje kompletní životní cyklus .fcstd souboru od jeho nahrání administrátorem, přes headless analýzu na CAD workeru, až po zobrazení a konfiguraci v 3D studiu.

sequenceDiagram
    autonumber
    actor Admin as Admin / Product Manager
    participant Studio as CAD Product Studio (studio.html)
    participant API as .NET 10 API Gateway (Coveroq.Cad.Api)
    participant Worker as Headless CAD Worker (Coveroq.Cad.Worker na pc-jakub)
    participant Repo as ModelRepository (EF Core)
    actor Client as Konfigurační Klient / Zákazník

    %% Fáze 1: Upload a Auto-Inspekce
    rect rgb(235, 245, 255)
    Note over Admin, Worker: Fáze 1: Nahrání & Headless Auto-Inspekce
    Admin->>Studio: Vybere a nahraje soubor .fcstd
    Studio->>API: POST /api/models/inspect (multipart/form-data)
    API->>Worker: Dispatch InspectJob over SignalR CadHub (/hubs/cad)
    Worker->>Worker: Otevře .fcstd v headless FreeCAD Python prostředí (inspect_model.py)
    Worker->>Worker: Vyhledá Spreadsheet 'Vars' & extrahuje aliasy, vzorce, jednotky, LCS body
    Worker-->>API: ReportInspectionCompleted (InspectionReportDto)
    API-->>Studio: 200 OK (Extrahovaná C# DTO struktura parametrů a LCS bodů)
    Studio->>Admin: Zobrazí náhled parametrů a kotevních bodů
    end

    %% Fáze 2: Registrace a Uložení
    rect rgb(240, 255, 240)
    Note over Admin, Repo: Fáze 2: Registrace v Databázi
    Admin->>Studio: Potvrdí registraci modelu
    Studio->>API: POST /api/models/confirm
    API->>Repo: ConfirmModelImportCommand -> EF Core Add & SaveChangesAsync
    Repo-->>API: Potvrzení zápisu (Model ID + Parameter IDs)
    API-->>Studio: 200 OK
    end

    %% Fáze 3: Interaktivní Konfigurace v 3D Studiu
    rect rgb(255, 250, 235)
    Note over Client, Worker: Fáze 3: Interaktivní 3D Konfigurace (Three.js Studio & LCS)
    Client->>Studio: Změna posuvníku / parametru (např. Width = 1200 mm)
    Studio->>Studio: Debounce (300 ms) & odeslání události `PARAM_CHANGE`
    Studio->>API: POST /api/orders/configure nebo /api/admin/assembly/{id}/recompute
    API->>Worker: Dispatch ExecuteJob over SignalR (Model + Validated Params)
    Worker->>Worker: Aktualizuje 'Vars' tabulku, recomputuje skelet & exportuje GLB
    Worker-->>API: ReportJobCompleted Signal
    API-->>Studio: Response (GLB URL / Recomputed LCS Anchors)
    Studio->>Studio: Hot-swap GLB v Three.js scéně & přepočet pozic kotevních bodů
    end

Popis kroků toku dat:

  1. Příjem a předání: Soubor .fcstd je přijat přes endpoint POST /api/models/inspect.
  2. Headless Parsing: CAD Worker načte soubor do FreeCAD C++ App vrstvy bez grafického rozhraní (headless mode via inspect_model.py).
  3. Analýza Spreadsheetu Vars & LCS Kotevních Bodů: Worker projde buňky v objektu Vars a načte definované souřadnicové systémy LCS (LCS_Leg_Left, LCS_Leg_Right).
  4. Validace a Formátování: Vytvoří se seznam DTO objektů ParameterDefinitionDto a LcsPointDto.
  5. Potvrzení a Uložení: Data jsou uložena v databázi prostřednictvím EF Core repository ModelRepository.
  6. 3D Konfigurace: Změna parametrů spouští recompute na CAD workeru a aktualizuje vizualizaci i přichytávání v Three.js viewportu.

3. Specifikace Extrakce Tabulky Vars (Spreadsheet Extraction Specification)

Každý parametrický CAD model v platformě COVEROQ CAD Platform využívá FreeCAD Spreadsheet::Sheet objekt, který slouží jako centrální tabulka parametrů. Standardní název tohoto objektu ve FreeCADu je Vars (případně systém akceptuje i jiné Spreadsheet objekty označené příznakem is_parameter_table).

3.1 Extrakční Pravidla a Algoritmus

Extrakční modul na CAD Workeru (inspect_model.py) postupuje podle následujících pravidel:

+-----------------------------------------------------------------------+
|                       FreeCAD Spreadsheet ('Vars')                    |
| +----+-----------------+-----------+--------+--------+--------------+ |
| |    | A (Label)       | B (Value) | C (Min)| D (Max)| E (Comment)  | |
| +----+-----------------+-----------+--------+--------+--------------+ |
| | 1  | Šířka skříně    | 1000 mm   | 500 mm | 2500 mm| Sirka korpusu| |
| |    | [Alias: Width]  |           |        |        |              | |
| | 2  | Výška skříně    | 2000 mm   | 1000 mm| 2800 mm| Vyska        | |
| |    | [Alias: Height] |           |        |        |              | |
| | 3  | Vypočítaná plocha|=Width*Height| -    | -      | EXPR         | |
| |    | [Alias: Area]   |           |        |        |              | |
| +----+-----------------+-----------+--------+--------+--------------+ |
+-----------------------------------------------------------------------+
  1. Identifikace Aliasů (Cell Aliases):
  2. Extrahují se výhradně buňky, které mají definovaný cell.alias.
  3. Název aliasu (cell.alias) se použije jako primární technická vlastnost key (např. Width, Height, Door_Type).

  4. Literály vs. Vzorce (Literals vs. Expressions):

  5. Literál (Literal): Buňka obsahuje přímou skalární hodnotu (např. 1000 mm nebo text "Laminát"). Vzniká standardní nastavitelný parametr (is_read_only = False).
  6. Vzorec (Expression / Formula): Pokud buňka obsahuje výraz začínající =, jedná se o odvozenou proměnnou (např. =Width - 2 * Wall_Thickness). Těmto buňkám se nastaví příznak is_read_only = True a jejich vzorec se uloží do expression_formula.

  7. Jednotky a Normalizace (Units & Conversion):

  8. FreeCAD ukládá fyzikální veličiny s jednotkami (FreeCAD.Units.Quantity).
  9. Parser rozšiřuje hodnoty na numerickou složku (default_value) a řetězec jednotky (unit):

    • mm (délka - Length) -> převedeno na float hodnotu v mm.
    • deg / ° (úhel - Angle) -> převedeno na float v stupních.
    • kg (hmotnost - Mass) -> převedeno na kg.
    • Bez jednotky (skalár / kusu / integer) -> unit = "mm" (default pro rozměry) nebo unit = "unitless".
  10. Detekce Mezí (Min / Max / Step Bounds):

  11. Konvenční sloupce: Parser kontroluje sousední buňky na stejném řádku (např. sloupce C a D pro Min a Max).
  12. Meta-komentáře: V pravém sloupci (komentář buňky) lze uvést JSON nebo strukturovaný řetězec: @bounds: min=500, max=2500, step=10
  13. Defaultní odvození: Pokud meze nejsou v tabulce explicitně uvedeny, Parser použije výchozí heuristiku:
    • min_value = default_value * 0.1 (nebo 0.0 u pozitivních dimenzí)
    • max_value = default_value * 3.0
    • step_value = 1.0 (pro mm/deg) nebo 0.1

4. Skeletové Sestavy & Extrakce Kotevních Bodů (LCS)

U modelů typu ModelType.Skeleton FreeCAD projekt obsahuje definované souřadnicové systémy (Local Coordinate Systems - LCS):

  1. Detekce LCS Objektů: Worker projde strom dokumentu a identifikuje všechny objekty typu Part::Attachment / App::LocalCoordinateSystem nebo objekty označené prefixem LCS_.
  2. Přepočet Globální Pozice: Při recomputaci parametrů skeletu worker vyhodnotí transformace a vrátí aktualizované $X, Y, Z$ souřadnice a rotace.
  3. Magnetické Přichytávání v UI (LcsSnapController): Frontend Web Studios načte LCS body a při přetahování dílu z filmového pásu automaticky zvýrazní a přichytí nový díl k nejbližší kotevní ose.

5. C# DTO Schémata a REST API Specifikace (.NET 10 Clean Architecture)

5.1 Datové Modely (Coveroq.Cad.Application/Models/DTOs/ModelDtos.cs)

Pro endpoint POST /api/models/inspect a navazující správu parametrů jsou definována následující C# record DTO schémata:

public record ParameterDefinitionDto(
    string Key,
    string Label,
    decimal Min,
    decimal Default,
    decimal Max,
    decimal Step,
    string? Unit = "mm",
    string? Group = "Základní",
    bool IsReadOnly = false,
    bool IsVisible = true,
    string? ExpressionFormula = null
);

public record LcsAnchorPointDto(
    string Name,
    decimal X,
    decimal Y,
    decimal Z,
    decimal RotX = 0,
    decimal RotY = 0,
    decimal RotZ = 0
);

public record ModelInspectionResultDto(
    string OrderId,
    string Status,
    string DetectedType,
    IReadOnlyList<ParameterDefinitionDto> Parameters,
    IReadOnlyList<LcsAnchorPointDto>? LcsPoints = null,
    string? ThumbnailUrl = null,
    string? GlbUrl = null,
    string? ErrorMessage = null
);

5.2 Specifikace Endpointu POST /api/models/inspect

  • URL: /api/models/inspect
  • Metoda: POST
  • Autentizace: Admin Token (X-Admin-Token nebo Authorization: Bearer <token>)
  • Content-Type: multipart/form-data (přijímá file: IFormFile) nebo application/json

Příklad odpovědi API:

{
  "orderId": "ord_insp_8f91a0c",
  "status": "success",
  "detectedType": "Skeleton",
  "parameters": [
    {
      "key": "Width",
      "label": "Šířka korpusu",
      "min": 400.0,
      "default": 800.0,
      "max": 1200.0,
      "step": 10.0,
      "unit": "mm",
      "group": "Rozměry",
      "isReadOnly": false,
      "isVisible": true,
      "expressionFormula": null
    }
  ],
  "lcsPoints": [
    { "name": "LCS_Leg_Left", "x": 50.0, "y": 50.0, "z": 0.0 },
    { "name": "LCS_Leg_Right", "x": 750.0, "y": 50.0, "z": 0.0 }
  ],
  "thumbnailUrl": "/storage/models/Cabinet_Standard/thumb.webp",
  "glbUrl": "/storage/orders/ord_insp_8f91a0c/model.glb",
  "errorMessage": null
}

6. Verifikace a Bezpečnost (Verification & Quality Assurance)

uv run python -m mkdocs build
dotnet build backend-dotnet/Coveroq.Cad.slnx
dotnet test backend-dotnet/Coveroq.Cad.slnx
npm run test