ocs_doc_api: convert architecture flow diagram to readable text format

Replace the mermaid flowchart (hard to read raw) with a clean ASCII/text diagram
tracing the same flow from the single source of truth (spec/entities.toml +
layouts.json) through codegen, facade, wire, transport, executor, and the host
backend/Scene, plus a layer-by-layer legend.
This commit is contained in:
Sebastian committed 2026-09-06 16:34:39 +02:00
1 parent 0965e188c9
commit d1b8fc93f5
1 file changed
+58 -80
+58 -80
View File
@@ -43,95 +43,73 @@ every entity family, its construction ops, geometric actions, and queries, and
their kernel/acadrust mapping. Everything downstream derives from it. The full their kernel/acadrust mapping. Everything downstream derives from it. The full
flow from spec to a committed document change: flow from spec to a committed document change:
```mermaid ```
flowchart TD SINGLE SOURCE OF TRUTH
subgraph SRC["Single source of truth"] spec/entities.toml families · constructors · methods · kernel map
SPEC["spec/entities.toml<br/>families · constructors · methods · kernel map"] src/gen/layouts.json Operation/Query wire layouts
LAYOUTS["src/gen/layouts.json<br/>Operation/Query wire layouts"] │
end ▼ (build.rs codegen — cargo build, CI drift-checked)
CODEGEN OUTPUT
subgraph GEN["build.rs codegen (cargo build, CI drift-checked)"] src/gen/ops_gen.rs Operation enum (append-only)
OPS["src/gen/ops_gen.rs<br/>Operation enum (append-only)"] src/gen/query_gen.rs Query enum (append-only)
QRY["src/gen/query_gen.rs<br/>Query enum (append-only)"] src/gen/api_reference.md
APIREF["src/gen/api_reference.md"] src/gen/binding_schema.json (object model + layouts inlined)
SCHEMA["src/gen/binding_schema.json<br/>(object model + layouts inlined)"] │
end ▼
FACADE (facade.rs — what a plugin writes)
subgraph FACADE["Facade (facade.rs) — plugin-facing, object-centric"] DocApi ──► Document ──► collections (solids()/curves()/entities())
API["DocApi (root)"] │
DOC["Document (per tab)"] ▼
COLL["collections: solids() / curves() / entities()"] typed handles (Solid · Line · ArcCurve · Text · …)
HND["typed handles: Solid · Line · ArcCurve · Text · ...<br/>methods build ops (intersect, transform, create_*)"] method call → builds an Operation or Query
end │
▼
subgraph WIRE["Wire (envelope/ops/query)"] WIRE (envelope/ops/query)
ENV["DocApiEnvelope<br/>Op(Operation) | Queries(Vec)"] DocApiEnvelope = Op(Operation) | Queries(Vec<Query>) ──► request
REC["Receipt: outcome + query_results + new_revision"] Receipt = outcome + query_results + new_revision ◄── response
end │
▼
subgraph TRANS["Transport (the only plugin↔host boundary)"] TRANSPORT (the ONLY plugin↔host boundary)
INP["InProcess (host / tests)"] InProcess (host / built-in plugins / tests)
IPC["OcsPluginApiIpc (plugin)<br/>PluginRequest::DocApiRequest{tab_id, bytes}"] OcsPluginApiIpc (plugin) PluginRequest::DocApiRequest{tab_id, bytes}
end │ │
└────────────┬───────────────────────┘
subgraph EXEC["Executor (executor.rs) — crate-owned, one impl"] ▼
AO["apply_op: validate+compute → push_undo → mutate → finalize_op"] EXECUTOR (executor.rs — crate-owned, ONE implementation)
AQ["apply_queries: read-only batch (capped)"] apply_op validate+compute → push_undo → mutate → finalize_op
end apply_queries read-only batch (capped)
│
subgraph HOST["Host backend (src/app/doc_api.rs — HostSession)"] ▼
BE["DocApiBackend impl<br/>resolve_body · store_solid · transform · add_* · bounds · volume · centroid"] HOST BACKEND (src/app/doc_api.rs — HostSession)
TAB["tab auth: reject tab_id ≠ bound tab"] tab authorization reject tab_id ≠ bound tab
SCN["Scene (per tab)<br/>solid_models · meshes · erase_entities<br/>geometry_epoch · doc_api_mass_cache · doc_api_cold_tess_used"] DocApiBackend impl resolve_body · store_solid · transform · add_*
CAD["CadDocument (acadrust)<br/>entities · block_records · handles"] bounds · volume · centroid · can_remove
end │
├──► Scene (per tab) solid_models · meshes · erase_entities
SPEC -->|spec → enum names + mapping| OPS │ geometry_epoch · doc_api_mass_cache
SPEC -->|spec → enum names + mapping| QRY │ doc_api_cold_tess_used
SPEC -->|spec → reference| APIREF └──► CadDocument (acadrust) entities · block_records · handles
SPEC -->|spec → schema| SCHEMA │
LAYOUTS -->|layouts inlined| SCHEMA ▼ produce
Receipt ──► facade turns it into a typed result (Solid, Aabb, f64, …)
API --> DOC --> COLL --> HND
HND -->|method → Operation / Query| ENV
ENV --> INP
ENV --> IPC
INP --> AO
IPC -->|bincode → host routes DocApiRequest| AO
AO --> TAB
AQ --> TAB
TAB --> BE
BE --> SCN
BE --> CAD
SCN --> REC
CAD --> REC
REC -->|deserialized| HND
classDef truth fill:#1f6feb,stroke:#0b3d91,color:#fff
classDef gen fill:#2da44e,stroke:#14532d,color:#fff
classDef hot fill:#bf8700,stroke:#7a5200,color:#fff
class SPEC,LAYOUTS truth
class OPS,QRY,APIREF,SCHEMA gen
class AO,AQ,TAB,SCN hot
``` ```
**How to read it:** **How to read it (top to bottom = the path of a request):**
- **Blue (source of truth)** — `spec/entities.toml` + `layouts.json`. Change - **SINGLE SOURCE OF TRUTH** — `spec/entities.toml` + `layouts.json`. Change
*these* to change the API surface; everything else regenerates or maps onto them. *these* to change the API surface; everything else regenerates or maps onto them.
- **Green (codegen)** — `build.rs` derives the wire enums, the human reference, - **CODEGEN OUTPUT** — `build.rs` derives the wire enums, the human reference,
and the binding handover schema. The `Operation`/`Query` enums are the canonical and the binding handover schema. The `Operation`/`Query` enums are the canonical
append-only wire vocabulary; the spec's `op`/`query` names must map to them append-only wire vocabulary; the spec's `op`/`query` names must map to them
(enforced by `spec_wire_consistency` tests). (enforced by `spec_wire_consistency` tests).
- **Facade → wire → transport** — a plugin's `solid.intersect(&other)` becomes an - **FACADE → WIRE → TRANSPORT** — a plugin's `solid.intersect(&other)` becomes an
`Operation`, wrapped in a `DocApiEnvelope`, and shipped via the one `Transport` `Operation`, wrapped in a `DocApiEnvelope`, and shipped via the one `Transport`
(in-process or IPC). Identical request either way. (in-process or IPC). Identical request either way.
- **Amber (hot paths)** — the executor's per-op invariant and the host's tab - **EXECUTOR + HOST BACKEND** — the hot paths: the executor's per-op invariant,
authorization + per-tab `Scene` state (solid cache, geometry epoch, the tab authorization, and the per-tab `Scene` state (solid cache, geometry epoch,
persistent cold-tessellation budget). This is where atomicity and the DoS the persistent cold-tessellation budget). Atomicity and the DoS boundaries live here.
boundaries live. - **Receipt (response)** — the host produces a `Receipt` (outcome + query results
- **Response** — the host produces a `Receipt` (outcome + query results + new + new geometry revision) that the facade turns back into a typed result (`Solid`,
geometry revision) that the facade turns back into a typed result (`Solid`,
`Aabb`, `f64`, …). `Aabb`, `f64`, …).
## Per-op execution model (the load-bearing invariant) ## Per-op execution model (the load-bearing invariant)