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/ exposes 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.csmaps eight hub endpoints. Anything not in that list is unreachable however complete its class looks — see the trap underExecution/below. - The tree is not self-contained. The project service types
Program.csleans on hardest live in the sibling HiNc engine repository, not here.
Program.cs also holds the hooks through which another project hosts the web service — see
Host Hooks below.
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, the project's step variables and color trees, run-output queries, and
the real-time push layer.
Execution/ExecutionController.cs— the playback surface.Execution/ExecutionChartsController.csandExecution/ClStripController.cs— the chart data. Three separate classes share the case-insensitiveapi/executionprefix on purpose, one of them routed there rather than under Mission with a comment saying why.Execution/SessionSinkHub.cs— four mapped hubs declared in one file, one per message sink, so hub-per-file does not hold here. Each pairs with a broadcast service thatProgram.csresolves eagerly, so it subscribes to its sink before the first client connects.Execution/ClStripHub.cs,Execution/ExecutionStatusHub.cs— the strip and status pushes.Execution/StepVariableController.cs— the project's step variables: the list, an add, change or rename, a delete, the compile-only check and the preview.Execution/StepColorTreeController.cs— the project's color trees: the list, an add, change or rename, a delete, the check and the preview.Execution/ExecutionStatusService.cs— the status broadcast behind that hub, and also the service log's engine-message lines under the fourHi.Engine.*categories and its run-start and run-end lines.- The Execution canvas has no hub of its own: it rides
Disp/RenderingHub.cslike every other canvas.
Documented in Execution Page, Program Branch, Block Info Panel, Step Variables Branch, Step Colors Branch, Selected-Step Info Panel, Strip Charts, Cycle-Line Charts and — for the log lines — Log Viewer Page.
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, ambient 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 the scan that answers whether the loaded project actually plays CSV or CL —
the referenced flag the Preference menu captions its CSV and CL Controller checkboxes with; the two
tree nodes follow those device-local checkboxes, not the scan. No SignalR hub lives here.
Mech/Topo/— one thin controller per transformer kind, each editing an instance held in the keyed object store. Documented in Transformer Select Panel.Mech/Topology/— the equipment topology editor behind the Equipment page's Topology column, not to be confused withMech/Topo/:Mech/Topology/EquipmentTopologyController.csis the one REST surface (api/mech/equipment-topology),Mech/Topology/EquipmentRoles.csthe per-part role table with the webservice's own checks,Mech/Topology/TopologyEditService.csthe anchor / branch / transformer / solid editing that controller builds per request, andMech/Topology/TopologyGraphDto.cswithMech/Topology/TopologyGraphBuilder.csthe whole-equipment graph. Documented in Equipment Topology.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.csandMech/ClRunnerController.cs— the two resident non-brand runner suits, reached from two Equipment tree nodes that are absent until their checkboxes in the Preference menu's Optional Nodes & Charts submenu are ticked, or a link names them. Documented in Hidden Controller Branches.
Documented in Equipment 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.csis 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, service-wide 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, and read this instance's file through the
file log provider; the same controller writes one log line per completed project operation.
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 with the line index that pages a large text file and the CSV chart service behindapi/csv-strip, path guards, the per-instance daily file logger (theFileprovider the Log Viewer reads), and two pieces the whole application rests on.Common/IndexService.csis the keyed object store behind the index a backend object, then edit it by key pattern every geometry, transformer and widget controller uses — one process-wide store that every browser and script connected to the service shares.Common/CleanupHub.csis not a messaging hub; it is one of the two things that bound that store. Its key registry is a static dictionary bucketed by connection id (SignalR builds a fresh hub instance for every invocation, so an instance field could not carry a key to the disconnect), and 90 seconds after a connection drops the sweep evicts every key it registered withAddthat no live connection holds by then — a reconnected page registers its keys again, so a transient drop costs it nothing. The browser bounds the store from the other side:wwwroot-src/src/composables/useCleanupHub.tsposts the index-remove endpoint onCommon/IndexController.csfor every key it holds when its host unmounts, and again whenever a key it registered is replaced. Documented in Object Store (IndexService), 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 4×4 matrix, and the object-management surface that handles file operations, XML editing and copy-paste for indexed objects. The 3D vector has no controller of its own: its widget posts to the owner of the vector, a transformer controller underMech/Topo/or the box controller underGeom/. Documented in Object Management Menu Button, Mat4dControl Component and, for the vector, Vec3dControl Component.
Host Hooks
Program.cs carries the hooks through which another project hosts the web service: two static
properties whose null defaults are the web service running on its own, and two public methods.
ContentRootPath—null: the content root, where the settings files andwwwrootare read from, is the working directory, or--contentRooton the command line.ConfigureBuilder—null: nothing is added to the builder beforeBuildAppreads its first setting and registers its first service.AnnounceWhenStarted— once the server listens, prints the version and settings file it is given, the addresses and the working directory, and on Windows puts the address in the console window's title; under systemd (INVOCATION_IDset) it leaves out the addresses and the line saying that closing the window stops HiNC. It opens no browser.RunApp— runs whatBuildAppbuilt, then ends the native core and closes the log file.
The web service's own Main applies the Linux core-dump filter, then calls BuildApp,
AnnounceWhenStarted and RunApp. Execution/ExecutionStatusService.cs makes StatusRunning and
StatusPaused public constants for a host that checks for a run in progress, and the front end's
counterpart is the build-time product alias in wwwroot-src/quasar.config.ts, covered in
Web Service SPA Source Tree. Documented in
Hosting from another project.
Controller and Demo
Controller/ is the single-file surface over the legacy HardNcEnv model, MachiningProject.NcEnv.
No page in the app drives it, 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 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
- Anatomy by Source Directory — the other two source trees, and how this layer is meant to be entered
- Web Service SPA Source Tree — the front end this process serves and answers
- Object Store (IndexService) — the keyed store in
Common/that the geometry, transformer and widget controllers edit through