Skip to content

COVEROQ CAD Platform - Architectural & Deployment Guide

Document Metadata
πŸ—“οΈ Last Modified: 2026-09-29
πŸ‘€ Author / Owner: @JakubDedik & @Jules
🏷️ Status: Active Reference
πŸ”— Linked System Components: Hetzner Cloud VPS (cad.coveroq.cz), .NET 10 C# Clean Architecture Backend, Shared PostgreSQL Cluster, SignalR CadHub Worker Station (pc-jakub)

This guide is a comprehensive reference explaining how the COVEROQ CAD Platform configurator ecosystem is structured, how the cloud C# .NET 10 backend and local CAD worker station (pc-jakub) communicate over SignalR WebSockets, and how to manage deployments and database persistence.


πŸ—οΈ High-Level System Architecture

COVEROQ CAD Platform uses a Distributed SignalR WebSocket CAD Worker Architecture. This keeps the public-facing e-shop and web configurator lightweight and highly responsive in the cloud while delegating heavy 3D geometry calculations to an on-premise GPU worker station (pc-jakub).

graph TD
    %% Define Nodes
    subgraph Cloud [Hetzner Cloud VPS - Germany (cad.coveroq.cz)]
        Frontend[Web App - HTML/TypeScript/Three.js Static Serving]
        API[C# .NET 10 Minimal APIs - Kestrel Server Port 8000/8005]
        CadHub[CadHub SignalR - /hubs/cad]
        TelemetryHub[TelemetryHub SignalR - /hubs/telemetry]
        DB[(Shared PostgreSQL Cluster - coveroq_cad DB)]
        Storage[Storage Directory - /app/storage]
    end

    subgraph Local [Dedicated CAD Worker - pc-jakub]
        WorkerService[Worker Service - Coveroq.Cad.Worker]
        SignalRClient[CadSignalRClient - /hubs/cad]
        Runner[FreeCAD Runner - runner.py / inspect_model.py]
        FreeCAD[FreeCAD 1.1 Geometry Engine - OpenGL / X11]
        Templates[(Master .fcstd Templates)]
    end

    %% Communication Links
    Browser[User Browser / E-Shop] -->|1. HTTP REST / WebApp| Frontend
    Browser -->|2. REST Minimal API Requests| API
    Browser -->|3. Live Telemetry Logs| TelemetryHub
    API -->|4. EF Core Npgsql Persistence| DB
    API -->|5. Serves GLBs, STEPs & Thumbnails| Storage

    WorkerService -->|6. Persistent SignalR WebSocket Link /hubs/cad| CadHub
    WorkerService -->|7. HTTP Multipart Artifact Uploads| API
    WorkerService -->|8. CLI Execution & Process Spawning| Runner
    Runner -->|9. Geometry Recomputes & Mesh Slicing| FreeCAD
    FreeCAD -->|10. Reads| Templates

πŸ›οΈ 1. C# .NET 10 Clean Architecture Backend

The backend is built following Clean Architecture v2 principles, enforcing strict unidirectionally nested dependencies (Domain ← Application ← Infrastructure ← Api). Domain purity and architectural rules are continuously verified by Coveroq.Cad.ArchitectureTests using NetArchTest and custom Roslyn Analyzers (CCAD001–CCAD015).

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚      Coveroq.Cad.Api     β”‚  (ASP.NET Core Minimal APIs & Hubs)
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚Coveroq.Cad.Infrastructureβ”‚  (EF Core, Serilog, SignalR Gateway)
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚ Coveroq.Cad.Application  β”‚  (MediatR CQRS, FluentValidation)
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚    Coveroq.Cad.Domain    β”‚  (Pure Domain Entities & Value Objects)
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Architectural Layers Overview

1. Coveroq.Cad.Domain

  • Purpose: Pure core domain entities, value objects, domain events, trace causality models, and business enums.
  • Key Components:
  • Entities: Entity<TId> base class, Order, ModelTemplate, Part, AssemblyStructure. All entities are sealed with private constructors for EF Core and static factory Create(...) methods returning Result<T>.
  • Value Objects: OrderId, ModelTemplateId, TraceId, CorrelationId, Dimension, Money.
  • Domain Events: IDomainEvent interface with OccurredOn timestamps.
  • Enums: OrderStatus (Pending, Processing, Completed, Failed), LogSource, Currency (Czk, Eur, Usd).
  • Purity Constraint: Zero dependencies on external libraries or frameworks.

2. Coveroq.Cad.Application

  • Purpose: Application orchestration, CQRS command and query handlers, validation, logging behaviors, and domain service abstractions.
  • Key Components:
  • CQRS Pattern: Requests dispatched via MediatR (ISender).
  • Pipeline Behaviors: ValidationBehavior<TRequest, TResponse> and LoggingBehavior<TRequest, TResponse> automatically trace context, measure execution time, and validate incoming requests before handlers execute.
  • Abstractions & Interfaces: IOrderRepository, IModelTemplateRepository, IAssemblyRepository, ICadWorkerGateway, IDiagnosticLogStore, ITraceContextAccessor.
  • Feature Slices: Structured into feature folders (Assemblies, Models, Orders, Publishing, Diagnostics).

3. Coveroq.Cad.Infrastructure

  • Purpose: External technical infrastructure implementations, EF Core ORM persistence, Serilog logging, external APIs, and worker SignalR gateway.
  • Key Components:
  • EF Core Persistence: CadDbContext with support for PostgreSQL (Npgsql.EntityFrameworkCore.PostgreSQL) and SQLite (Microsoft.EntityFrameworkCore.Sqlite).
  • Global Value Converters: Value object converters for OrderId, ModelTemplateId, TraceId, CorrelationId, and Money registered in CadDbContext.ConfigureConventions.
  • Repositories: OrderRepository, ModelTemplateRepository, AssemblyRepository.
  • Logging: InMemoryLogSink implementing Serilog ILogEventSink and IDiagnosticLogStore for streaming log broadcasts over SignalR (/hubs/telemetry).
  • SignalR Worker Gateway: RemoteCadWorkerGateway managing thread-safe job completion futures (TaskCompletionSource) for dispatched rendering jobs with native SignalR connection lifecycle handling over CadHub (/hubs/cad).

4. Coveroq.Cad.Api

  • Purpose: ASP.NET Core Minimal APIs web host, authentication middleware, static file webapp host, SignalR hubs, and OpenAPI endpoints.
  • Key Components:
  • Endpoints: Minimal API endpoint modules (ModelEndpoints, OrderEndpoints, PublishingEndpoints, LogEndpoints).
  • SignalR Hubs: CadHub (/hubs/cad) for worker coordination and TelemetryHub (/hubs/telemetry) for live log streaming and worker status updates.
  • Authentication: AdminTokenAuthHandler enforcing AdminOnly authorization policy on administrative endpoints via X-Admin-Token header or Bearer authorization token.
  • Static File & WebApp Serving: Serves webapp/ as root web app (/, /studio, /inspector, /models, /logs) and /storage for 3D GLB/STEP assets with proper MIME types.

⚑ 2. Zero-Fallback Principle (Rule 12)

The COVEROQ CAD Platform strictly enforces the Zero-Fallback Principle:

  • No Speculative Recoveries or Fallbacks: Alternate fallback execution paths, speculative retries, alternate GUI/offscreen hack retries, and client-side dummy fallback mocks are strictly and unconditionally forbidden.
  • Single Deterministic Execution Path: Every operation follows exactly ONE unambiguous, deterministic execution path.
  • Fail Fast & Explicitly: If a precondition or execution step fails, the system immediately fails fast, emits structured telemetry with full causality context (TraceId, SpanId, ParentSpanId, ElapsedMs), and returns an explicit error (Result.Failure(...) or HTTP error status).

πŸ—„οΈ 3. Database Infrastructure (Shared PostgreSQL Cluster)

The CAD platform utilizes a dedicated database (coveroq_cad) residing on a shared PostgreSQL cluster.

Database Setup & Isolation

  • Initialization Script (deploy/postgres/init-cad-db.sql): Creates the isolated database coveroq_cad and application role cad_user with restricted privileges.
  • Dynamic Connection Selection: CadDbContext detects the connection provider string keyword (Host=, Server=, User Id= for PostgreSQL vs .db for local SQLite).
  • EF Core Automatic Migrations & Seeding: In Development environment, DbInitializer.InitializeAsync applies EF Core database migrations (MigrateAsync). Test suites invoke SeedDefaultTemplatesAsync explicitly when required.

πŸ”Œ 4. SignalR CAD Worker Communication (pc-jakub)

Heavy 3D CAD operations (skeleton parametric solving, GLB mesh export, STEP CAD drawings, inspection, and BOM generation) are offloaded from the Cloud VPS to a dedicated GPU station (pc-jakub).

Communication Flow over CadHub (/hubs/cad)

  1. Connection Establishment:
  2. The worker service Coveroq.Cad.Worker on pc-jakub opens an outbound SignalR WebSocket connection to wss://cad.coveroq.cz/hubs/cad?client=worker:pc-jakub.
  3. CadHub registers the worker, stores telemetry tags, and broadcasts initial worker liveness state (WorkerStatusChanged).
  4. Job Dispatching:
  5. When a user configures or inspects a model, the C# Application handler calls ICadWorkerGateway.DispatchJobAsync(...).
  6. RemoteCadWorkerGateway constructs a strongly typed WorkerJobRequestDto populating trace causality metadata (TraceId, CorrelationId), creates an AsyncJobCompletionSource, and transmits the DTO across SignalR CadHub.
  7. Execution on pc-jakub:
  8. WorkerJobDispatcher receives the job, establishes ambient causality context (ITraceContextAccessor), spawns FreeCadProcessRunner passing environment causality (COVEROQ_TRACE_ID), and executes FreeCAD 1.1 Python scripts (solid_3d.py, inspect_model.py, drawing_2d.py).
  9. Binaries (GLB, STEP, WebP thumbnails) are uploaded back via HTTP artifact upload endpoints.
  10. Completion & Real-time Resolution:
  11. The worker invokes ReportJobCompleted or ReportInspectionCompleted on CadHub.
  12. RemoteCadWorkerGateway.CompleteJob(...) resolves the waiting asynchronous Task and returns result details to the client.
  13. Connection & Disconnect Resilience:
  14. SignalR native ping/pong keepalive monitors connection health. Upon disconnect, CadHub.OnDisconnectedAsync triggers UnregisterWorkerAsync, clearing metadata and immediately failing in-flight jobs with structured errors.

πŸ“¦ 5. Cloud VPS Containerization (Docker Compose & Portainer)

The cloud server runs a containerized .NET 10 application managed by Docker Compose & Portainer.

  • Dockerfile: Multi-stage container build compiling C# projects and publishing Coveroq.Cad.Api.
  • docker-compose.yml:
  • Port Mapping (127.0.0.1:8005:8000): Binds port 8005 locally on Hetzner VPS to port 8000 inside the container.
  • Automated Webhook Deployment: Portainer stack is redeployed automatically via GitHub Actions CI (ci.yml) on main branch pushes.
  • Zero SSH Portainer Tampering Rule: Direct manual modification of Portainer stack files or executing docker compose inside Portainer volume directories over SSH is strictly forbidden.

πŸš€ 6. Deployment Procedures

Cloud API Deployment (Hetzner VPS)

  1. Commit and push code changes to GitHub main branch.
  2. ci.yml runs tests, bumps CACHE_BUST in docker-compose.yml, and triggers the Portainer stack redeploy webhook.

Local Worker Station Updates (pc-jakub)

  1. Automated deployment executes via .github/workflows/deploy-worker.yml on pushes to backend-dotnet/** or cad/**.
  2. The workflow publishes Coveroq.Cad.Worker to /opt/coveroq-worker and restarts coveroq-cad-worker.service: bash sudo systemctl restart coveroq-cad-worker.service