Table of Contents

Web Service Backend Source Tree

The C# half of HiNC-2025-webservice is an ASP.NET Core process that serves the SPA, answers its REST calls, and pushes to it over SignalR. It is organised by the engine's domain vocabulary, not by web-framework artifact type: a controller, its hub, its DI service and its non-web scene objects sit together in one domain folder rather than in a Controllers / Hubs / Services split.

Folders below are ordered by how much of the shipped surface they answer for.

Reading a Filename

The role of a file is told by its suffix and base type, and the convention holds throughout:

Suffix What it is
*Controller.cs a REST controller with a route attribute
*Hub.cs a SignalR hub — but see the two traps below
*Service.cs a singleton registered in Program.cs
*Displayee.cs a scene-composition object handed to the engine; no HTTP surface at all
*Dtos.cs, *Config.cs plain wire or settings types

Two names deliberately break the reader's expectation. Controller/ControllerController.cs means CNC controller, not an MVC controller. And Mech/'s *DisplayController.cs files are ordinary REST controllers that attach a displayee to a rendering connection somebody else already owns — they are not hubs.

Important

Folder nesting does not predict the route. Mech/Topo/ and Mech/MechBuilder/ expose routes that carry no api/mech/ prefix at all, and even inside Mech/ two conventions coexist: the newer ports use kebab-case paths under api/mech/, while the older keyed-object editors use the controller-name default. Read the route attribute, never the path.

Composition Root

Program.cs is the only C# file at the repository root, and it is where the questions a reader usually has are actually answered: which services are singletons, which hubs are mapped, and what the middleware order is. Two facts about it are worth carrying:

  • A declared hub is not a mapped hub. Program.cs maps eight hub endpoints. Anything not in that list is unreachable however complete its class looks — see the trap under Execution/ below.
  • The tree is not self-contained. The project service types Program.cs leans on hardest live in the sibling HiNc engine repository, not here.

Documented in Program and Hosting.

Execution

Execution/ is the run cockpit's whole backend: playback control, the strip and cycle-line charts, the NC-program branch index, run-output queries, and the real-time push layer.

  • Execution/ExecutionController.cs — the playback surface.
  • Execution/ExecutionChartsController.cs and Execution/ClStripController.cs — the chart data. Three separate classes share the case-insensitive api/execution prefix on purpose, one of them routed there rather than under Mission with a comment saying why.
  • Execution/SessionSinkHub.csfour mapped hubs declared in one file, one per message sink, so hub-per-file does not hold here. Each pairs with a broadcast service that Program.cs resolves eagerly, so it subscribes to its sink before the first client connects.
  • Execution/ClStripHub.cs, Execution/ExecutionStatusHub.cs — the strip and status pushes.
Warning

Execution/ExecutionCanvasHub.cs declares a hub that Program.cs never maps and that nothing in the repository references. The Execution canvas rides Disp/RenderingHub.cs like every other canvas. A reader looking for “the hub behind the Execution page” by name will find this file first and be wrong.

Documented in Execution Page, Program Branch, Selected-Step Info Panel, Strip Charts and Cycle-Line Charts.

Mech

Mech/ is the largest domain folder: the REST surfaces for the machine tool, the tool house and cutter editing, fixtures and workpieces, spindle capability, background and coolant, and the three runner suits. It also holds the display controllers that bind a mechanism scene onto a rendering connection. Mech/CutterDtoBuilder.cs is the shared read-side DTO shape two controllers reuse, and Mech/NcSuitUsage.cs is what lets the Control Tree show the CSV and CL runner branches only when the loaded project actually plays them. No SignalR hub lives here.

  • Mech/MechBuilder/ — the standalone mechanism-building session, held by a process-wide singleton rather than per user. Documented in Mechanism Builder Page.
  • Mech/Topo/ — one thin controller per transformer kind, each editing an instance held in the keyed object store. Documented in Transformer Select Panel.
  • Mech/SoftNcRunnerController.cs — the one endpoint family behind the Controller branch, and the file whose snapshot decides which of that branch's nodes exist. Documented in Controller Branch, with Brand Matrix for the snapshot flags themselves.
  • Mech/CsvRunnerController.cs and Mech/ClRunnerController.cs — the two resident non-brand runner suits, reached from tree branches the Preference menu hides by default. Documented in Preference Menu Dropdown until those branches have a page.

Documented in General Setup Page and Tool House Page and the panels beneath them.

Missions

Missions/ is the mission command tree's backend. Two things here surprise readers:

  • The folder is plural and the route is singular — and the SPA folder is singular too.
  • Missions/NcOptOptionEndpoints.cs is not a minimal-API endpoint file despite the name. It is a second file of the same partial controller class, which is why its routes resolve under the mission prefix.

Missions/MissionCommandCatalog.cs reflects over every session command carrying the catalog attribute once per process, replacing hand-maintained kind switches, and Missions/MissionCommandFields.cs does the same for annotated scalars — which is how a simple command gets an editor without a bespoke panel. Missions/ScriptCompletionService.cs and Missions/ScriptCompileCheckService.cs are the Roslyn pair behind the script editor; the compile check reuses the same options and globals type the script command uses at run time.

Documented in Mission Root Panel and the command panels under it.

Disp

Disp/ is the rendering layer. Disp/RenderingHub.cs is the single transport surface for every 3D canvas in the application — canvas initialization, pointer, key and touch input, resize, view presets, cache clearing and snapshots — and the SPA's canvas component defaults to it, so all pages share one hub rather than one hub per page. Disp/RenderingService.cs owns the per-connection engines the hub resolves against. Disp/StlPreviewController.cs is the only other REST surface here.

The *Displayee.cs files are scene-graph composition objects rather than web types, and each has a live instantiation site: the execution scene, the equipment-setup scene, the step-subtraction scene and the two coordinate-frame displayees the first two compose in.

Documented in Rendering Canvas on Web Service, RenderingCanvas Tool Bar and — for Disp/StlPreviewController.cs and the per-connection slot behind it — STL Preview Pane.

Environments

Environments/ is session and environment scope: the project lifecycle, per-user preference persistence, the Execution page's division flags, and the shipped localized step-present catalog. It is also where the Log Viewer's data comes from — the log endpoints sit on the project controller beside status, new, load, save, reload, save-as and close.

Documented in Main Panel, Session State, Preference Menu Dropdown, Internationalization, Log Viewer Page and Step Present Dialog.

Common, Geom and Widget

  • Common/ — cross-cutting infrastructure with no single domain owner: the optional login gate, the named-root file explorer, path guards, the daily file logger, and two pieces the whole application rests on. Common/IndexService.cs is the keyed object store behind the index a backend object, then edit it by key pattern every geometry, transformer and widget controller uses. Common/CleanupHub.cs is not a messaging hub, and it is not what bounds that store either. Its key registry is an ordinary instance property and SignalR builds a fresh hub instance for every invocation, so the entry Add records is discarded with the instance that received it and the disconnect handler always walks an empty registry. The bound comes from the browser instead: wwwroot-src/src/composables/useCleanupHub.ts posts the index-remove endpoint on Common/IndexController.cs for every key it holds when its host unmounts, and again whenever a key it registered is replaced. Documented in Dictionary Service Pattern, WebAPI Hub Cleanup Pattern, Login and Authentication and Log Viewer Page.
  • Geom/ — one CRUD controller per geometry kind, on the same keyed-object pattern, and nothing else: no hubs, no services. Documented in Geometry Panels.
  • Widget/ — the generic value and lifecycle controllers the reusable inputs post to: the 3D vector, the 4×4 matrix, and the object-management surface that handles file operations, XML editing and copy-paste for indexed objects. Documented in Object Management Menu Button, Vec3dControl Component and Mat4dControl Component.

Controller and Demo

Controller/ is the single-file surface over the legacy HardNcEnv model, MachiningProject.NcEnv. The Legacy Controller page that drove it was removed on 2026-09-11, but the controller is still mounted: its routes edit the legacy tables, a different store from the runner tables that Mech/SoftNcRunnerController.cs — its successor, as that file's own doc comment says — edits. The successor covers the brand, the axis limits and rapid feedrates, the tooling time, the work coordinates, the datum tables and the tool offsets, but not every route — among them the work-coordinate Align P0 pair, the shortest-rotary toggle, the per-axis max rotary speed and the Heidenhain master-axis character have no soft-runner endpoint. Only GET cnc-brand still has a client — the Execution tool bar's Heidenhain Coordinate gate. Documented in Legacy Controller Model (HardNcEnv).

Demo/ is customer-facing sample code — a custom colour guide and a per-step optimization sweep — compiled into the assembly with no call site in the running application. Read it as an example of how to extend the engine, not as part of the shipped behaviour.

See Also