blackopsrepl commited on
Commit
8f89a80
Β·
1 Parent(s): 7be2122

docs: document deliveries tutorial and Space workflow

Browse files

Document the current deliveries tutorial surface end to end. The README now includes Hugging Face Space front matter, the dependency and Rust-version line, the SolverForge domain concepts, the validation commands, Space build/run commands, the code reading order, REST routes, routing modes, solver policy, and the current ten-vehicle demo dataset sizes.

Add AGENTS.md as the repo-local editing contract. It records the canonical Plan naming, file-size rule, no-suppression policy, Makefile workflow, documentation alignment requirements, road-network test gating, published dependency policy, and retained-job runtime notes.

Add WIREFRAME.md as the architecture map for future work. It explains the runtime flow from browser boot through demo data, preparation, retained solving, SSE, snapshots, route geometry, and frontend rendering; it also maps the files by responsibility and describes the domain, route-metrics, API, frontend, and validation surfaces.

This is a documentation-only boundary. Reverting it leaves the app, tests, and Space tooling intact while removing the tutorial prose and contributor guidance.

Files changed (3) hide show
  1. AGENTS.md +92 -0
  2. README.md +250 -0
  3. WIREFRAME.md +229 -0
AGENTS.md ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Repository Guidelines
2
+
3
+ ## Project Structure And Naming
4
+
5
+ This repo follows the current `solverforge-cli` app shape. The app package
6
+ version is `1.0.0`, and the release binary is `solverforge_deliveries`.
7
+
8
+ - `src/domain/mod.rs` owns the `solverforge::planning_model!` manifest.
9
+ - `src/domain/plan.rs` owns the `Plan` planning solution.
10
+ - `src/domain/delivery.rs` owns the `Delivery` problem fact.
11
+ - `src/domain/vehicle.rs` owns the `Vehicle` planning entity and its
12
+ `delivery_order` list variable.
13
+ - `src/domain/preview.rs` owns transport/view preview structs.
14
+ - `src/domain/route_metrics/` owns route preparation, CVRP hooks, scoring
15
+ preview, route geometry, and insertion ranking.
16
+ - `src/constraints/` owns one score rule per file plus `mod.rs` assembly.
17
+ - `src/data/data_seed/` owns deterministic city demo-data modules with grouped
18
+ visit files for scaled delivery counts.
19
+ - `src/api/` owns REST, DTO, and SSE surfaces.
20
+ - `src/solver/` owns retained-job runtime orchestration.
21
+ - `static/app/models/` owns frontend plan modeling.
22
+ - `static/app/ui/` owns browser layout and rendering helpers.
23
+
24
+ Keep the canonical solution name `Plan`. Do not reintroduce `DeliveryPlan` or
25
+ `delivery_plan.rs`.
26
+
27
+ ## File Size Rule
28
+
29
+ No source, test, frontend, config, or repo documentation file should reach 300
30
+ lines. Split by responsibility before that point. Large generated/cache output
31
+ under `target/` and `.osm_cache/` is outside this rule.
32
+
33
+ ## Build And Validation Commands
34
+
35
+ - `make help` shows the supported command surface.
36
+ - `make run-release` runs the app locally on `:7860`.
37
+ - `make test` runs Rust, frontend, and Playwright browser tests.
38
+ - `make test-e2e` runs the real browser Playwright smoke.
39
+ - `make space-build` builds the Docker image used by Hugging Face Spaces.
40
+ - `make space-run` builds and runs that image locally.
41
+ - `make ci-local` runs formatting, clippy, release build, standard tests, and
42
+ the Space Docker image build.
43
+ - `make test-live-road` runs the env-enabled road-network smoke test.
44
+ - `make pre-release` runs `ci-local` and the live road-network smoke.
45
+ - `cargo test` runs Rust unit and integration tests.
46
+ - `node --test tests/frontend_models.test.mjs` runs frontend model tests.
47
+
48
+ Use the Makefile as the authoritative local workflow, matching the
49
+ `solverforge-hospital` Space/Docker validation standard.
50
+
51
+ ## No Suppression Policy
52
+
53
+ Do not add warning suppressions, fallback compatibility branches, or unused
54
+ helper modules. If a split creates unused code, restructure the modules so each
55
+ compiled item is used by its crate.
56
+
57
+ ## Documentation Policy
58
+
59
+ Keep `Cargo.toml`, `Cargo.lock`, `Makefile`, `Dockerfile`, `README.md`,
60
+ `WIREFRAME.md`, `AGENTS.md`, `solverforge.app.toml`, `solver.toml`,
61
+ `static/sf-config.json`, and the visible API guide in
62
+ `static/app/ui/api-guide.mjs` aligned.
63
+
64
+ When changing routes, solver policy, demo IDs, dependency sources, file layout,
65
+ or browser behavior, update the docs in the same patch. Prefer current-state
66
+ documentation over planning language.
67
+
68
+ ## Testing Guidance
69
+
70
+ Add Rust unit tests next to the behavior they protect. Add API integration
71
+ coverage under `tests/api_contract/` and shared integration helpers under
72
+ `tests/support/` only when every helper is used by the single
73
+ `tests/api_contract.rs` crate. Add frontend model tests in
74
+ `tests/frontend_models.test.mjs`, and browser-flow tests in `tests/e2e/`.
75
+
76
+ Road-network tests should stay env-gated unless the test uses only cached or
77
+ straight-line behavior. Use `SOLVERFORGE_RUN_LIVE_TESTS=1` through
78
+ `make test-live-road` when validating live map/routing paths.
79
+
80
+ ## Runtime Notes
81
+
82
+ `solver.toml` is embedded by `Plan` through the planning-solution macro. Treat
83
+ it as the solver policy source of truth.
84
+
85
+ `Cargo.toml` currently uses Rust `1.95` and published crates.io dependencies
86
+ only. Keep every direct dependency declaration at the latest published version,
87
+ and keep `solverforge.app.toml`, `Cargo.lock`, and docs truthful if those
88
+ dependency sources or versions change.
89
+
90
+ The app serves stock `solverforge-ui` assets, local static app modules, and
91
+ Axum API routes from one process. Retained solver jobs are controlled through
92
+ REST and observed through SSE.
README.md ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: SolverForge Deliveries
3
+ emoji: 🚚
4
+ colorFrom: green
5
+ colorTo: blue
6
+ sdk: docker
7
+ app_port: 7860
8
+ pinned: false
9
+ license: apache-2.0
10
+ short_description: SolverForge delivery-route optimization example
11
+ ---
12
+
13
+ # SolverForge Deliveries
14
+
15
+ `solverforge-deliveries` is a SolverForge vehicle-routing example with retained
16
+ jobs, route geometry, insertion recommendations, and a browser plan viewer.
17
+
18
+ It answers one concrete question:
19
+
20
+ "Given depots, vehicles, delivery stops, capacities, and time windows, which
21
+ vehicle should visit each delivery and in what order?"
22
+
23
+ ## Documentation Map
24
+
25
+ - `README.md`
26
+ Quick start, concepts, API surface, and the shortest learning path.
27
+ - `WIREFRAME.md`
28
+ Architecture and request/data flow across backend, runtime, maps, and UI.
29
+ - `AGENTS.md`
30
+ Repo-specific contribution, validation, and documentation rules.
31
+ - `Makefile`
32
+ The supported local command surface for development, validation, and
33
+ Docker-based Hugging Face Space preparation.
34
+ - `Dockerfile`
35
+ The Docker Space image build, using Rust 1.95 and published crates.io
36
+ dependencies.
37
+
38
+ ## Current Dependency Shape
39
+
40
+ The app package version is `1.0.0`; the release binary is
41
+ `solverforge_deliveries`.
42
+
43
+ This repo requires Rust `1.95` and is configured against published crates.io
44
+ dependencies. Direct dependency declarations use the latest published versions
45
+ checked for this repo:
46
+
47
+ - `solverforge` `0.9.1`
48
+ - `solverforge-ui` `0.6.3`
49
+ - `solverforge-maps` `2.1.3`
50
+ - `axum` `0.8.9`
51
+ - `tokio` `1.52.1`
52
+ - `tokio-stream` `0.1.18`
53
+ - `tower-http` `0.6.8`
54
+ - `tower` `0.5.3`
55
+ - `serde` `1.0.228`
56
+ - `serde_json` `1.0.149`
57
+ - `rand` `0.10.1`
58
+ - `uuid` `1.23.1`
59
+ - `parking_lot` `0.12.5`
60
+ - `http-body-util` `0.1.3`
61
+
62
+ The app metadata in `solverforge.app.toml` mirrors that published dependency
63
+ shape and records `solverforge-cli` `2.0.0` as the current scaffold metadata
64
+ line.
65
+
66
+ ## What SolverForge Is Doing Here
67
+
68
+ - `Delivery` is a problem fact: a stop the solver must place in a route.
69
+ - `Vehicle` is a planning entity: each vehicle owns one mutable route.
70
+ - `Vehicle.delivery_order` is the list planning variable.
71
+ - `Plan` is the planning solution, matching the current `solverforge-cli`
72
+ default solution name and `src/domain/plan.rs` file shape.
73
+ - Constraints score assignment coverage, capacity, time-window violations, and
74
+ total travel time.
75
+ - `solver.toml` selects list construction heuristics and local-search moves.
76
+
77
+ The app ships three city datasets:
78
+
79
+ - `PHILADELPHIA` (default)
80
+ - `HARTFORD`
81
+ - `FIRENZE`
82
+
83
+ Each dataset has ten vehicles: 82 Philadelphia deliveries, 50 Hartford
84
+ deliveries, and 80 Firenze deliveries. Philadelphia is the default road-network
85
+ baseline, and all current seed data has enough aggregate vehicle capacity and
86
+ reachable street-front coordinates for the configured delivery stops.
87
+
88
+ ## Quick Start
89
+
90
+ ```sh
91
+ make run-release
92
+ ```
93
+
94
+ Then open `http://localhost:7860`.
95
+
96
+ To inspect the command surface:
97
+
98
+ ```sh
99
+ make help
100
+ ```
101
+
102
+ ## Validation
103
+
104
+ Standard validation:
105
+
106
+ ```sh
107
+ make test
108
+ ```
109
+
110
+ Full local validation:
111
+
112
+ ```sh
113
+ make ci-local
114
+ ```
115
+
116
+ Space image validation:
117
+
118
+ ```sh
119
+ make space-build
120
+ ```
121
+
122
+ Live road-network smoke:
123
+
124
+ ```sh
125
+ make test-live-road
126
+ ```
127
+
128
+ `make test` includes Rust tests, browserless frontend tests, and Playwright
129
+ browser tests. `make ci-local` adds the Docker image build used by the Hugging
130
+ Face Space. `make pre-release` runs `make ci-local` and then the live
131
+ road-network smoke test. The live road test may touch the local `.osm_cache/`
132
+ through `solverforge-maps`; that cache is ignored by git and by Docker builds.
133
+
134
+ ## Hugging Face Space Deployment
135
+
136
+ This repo is Docker-Space ready. The Space reads the README front matter,
137
+ builds `Dockerfile`, and expects the app to bind `PORT=7860`.
138
+
139
+ Local Space-equivalent commands:
140
+
141
+ ```sh
142
+ make space-build
143
+ make space-run
144
+ ```
145
+
146
+ ## Read The Code In This Order
147
+
148
+ 1. `src/domain/mod.rs`
149
+ The `planning_model!` manifest and public domain exports.
150
+ 2. `src/domain/plan.rs`
151
+ The `Plan` solution and list-variable shadow-refresh wiring.
152
+ 3. `src/domain/delivery.rs` and `src/domain/vehicle.rs`
153
+ The fact and planning-entity models.
154
+ 4. `src/domain/route_metrics/`
155
+ Route preparation, CVRP hooks, scoring preview, route geometry, and insertion
156
+ ranking.
157
+ 5. `src/constraints/mod.rs`
158
+ The constraint-set assembly point.
159
+ 6. `src/constraints/*.rs`
160
+ One scoring rule per file.
161
+ 7. `src/data/data_seed/entrypoints.rs`
162
+ Public demo-data IDs and generator dispatch.
163
+ 8. `src/data/data_seed/{philadelphia,hartford,firenze}/`
164
+ City depots and delivery coordinates.
165
+ 9. `src/solver/service.rs`
166
+ Retained-job orchestration over `SolverManager<Plan>`.
167
+ 10. `src/api/routes.rs`, `src/api/dto.rs`, and `src/api/sse.rs`
168
+ REST, DTO, and event-stream contracts.
169
+ 11. `static/app/main.mjs`
170
+ Browser controller.
171
+ 12. `static/app/models/` and `static/app/ui/`
172
+ Frontend plan normalization, preview modeling, layout, maps, tables, and
173
+ modals.
174
+
175
+ ## Project Shape
176
+
177
+ - `src/domain/`
178
+ Planning model, domain types, route metrics, and test-only model checks.
179
+ - `src/constraints/`
180
+ Incremental SolverForge scoring rules.
181
+ - `src/data/`
182
+ Deterministic city demo-data generator.
183
+ - `src/solver/`
184
+ Retained-job facade and runtime event payload formatting.
185
+ - `src/api/`
186
+ Axum routes, DTOs, and SSE endpoint.
187
+ - `static/app/`
188
+ Browser modules built on stock `solverforge-ui` assets.
189
+ - `Dockerfile`
190
+ Multi-stage Rust 1.95 Alpine build for the Hugging Face Docker Space.
191
+ - `tests/api_contract/`
192
+ Integration tests for catalog, jobs, lifecycle, SSE, and road-network smoke.
193
+ - `tests/frontend_models.test.mjs`
194
+ Browserless frontend model tests.
195
+ - `tests/e2e/`
196
+ Playwright tests for the served browser app, including asset loading, dataset
197
+ switching, route highlighting, and retained solve start/stop.
198
+
199
+ ## REST API
200
+
201
+ - `GET /health`
202
+ - `GET /info`
203
+ - `GET /demo-data`
204
+ - `GET /demo-data/{id}`
205
+ - `POST /jobs`
206
+ - `GET /jobs/{id}`
207
+ - `GET /jobs/{id}/status`
208
+ - `GET /jobs/{id}/snapshot`
209
+ - `GET /jobs/{id}/analysis`
210
+ - `GET /jobs/{id}/routes`
211
+ - `POST /jobs/{id}/pause`
212
+ - `POST /jobs/{id}/resume`
213
+ - `POST /jobs/{id}/cancel`
214
+ - `DELETE /jobs/{id}`
215
+ - `GET /jobs/{id}/events`
216
+ - `POST /recommendations/delivery-insertions`
217
+
218
+ Lifecycle semantics:
219
+
220
+ - `pause` requests a runtime-managed pause and checkpoint.
221
+ - `resume` continues from the retained checkpoint.
222
+ - `cancel` stops a live or paused job.
223
+ - `delete` removes a terminal retained job before the next fresh solve.
224
+ - `snapshot_revision={n}` is optional for snapshots, analysis, and routes.
225
+ - SSE reconnects bootstrap from the retained runtime status/event state.
226
+
227
+ ## Routing Modes
228
+
229
+ `road_network` is the default and uses `solverforge-maps` to fetch or load a
230
+ road graph for the current plan bounds. `straight_line` is available as a fast
231
+ draft/testing mode. Route geometry is returned by `/jobs/{id}/routes` and drawn
232
+ in the browser map only when it matches the active snapshot and routing mode.
233
+ The route list can highlight one vehicle route while dimming the rest of the
234
+ map geometry without changing the user's current map viewport.
235
+
236
+ ## Solver Policy
237
+
238
+ `solver.toml` is embedded by `Plan` and is the runtime source of truth:
239
+
240
+ - `list_clarke_wright` builds delivery routes.
241
+ - `list_k_opt` improves construction output before local search.
242
+ - local search combines nearby list change/swap, reverse, k-opt, ruin, and
243
+ limited sublist moves.
244
+ - `late_acceptance` and `accepted_count` control acceptance and retained
245
+ candidates.
246
+
247
+ The city seeds have coherent capacity and reachable road-network coordinates so
248
+ local search can reach feasible `0hard` road-network solutions. Current seed
249
+ sizes are 82 Philadelphia deliveries, 50 Hartford deliveries, and 80 Firenze
250
+ deliveries, each with ten vehicles.
WIREFRAME.md ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # solverforge-deliveries WIREFRAME
2
+
3
+ This file is the architectural map for the deliveries example.
4
+
5
+ `README.md` explains how to run and use the app. This document explains how the
6
+ pieces fit together and where each responsibility lives.
7
+
8
+ ## Documentation Roles
9
+
10
+ - `README.md`
11
+ Quick start, dependency shape, route list, and user-facing orientation.
12
+ - `WIREFRAME.md`
13
+ Architecture, execution flow, and file-map walkthrough.
14
+ - `AGENTS.md`
15
+ Repo-specific contribution, validation, and documentation rules.
16
+ - `Makefile`
17
+ Local development, validation, and Space/Docker command surface.
18
+ - `Dockerfile`
19
+ Hugging Face Docker Space image definition.
20
+
21
+ ## What This Repo Is Teaching
22
+
23
+ This repo is a complete `solverforge-deliveries` `1.0.0` list-variable
24
+ SolverForge app for delivery routing.
25
+
26
+ It shows how to combine:
27
+
28
+ - a `Plan` solution with a list planning variable
29
+ - route-specific score rules
30
+ - SolverForge CVRP construction and local-search hooks
31
+ - `solverforge-maps` road-network preparation and route geometry
32
+ - retained jobs with snapshots, analysis, cancel, pause, resume, and SSE
33
+ - a browser plan viewer built on stock `solverforge-ui` assets
34
+
35
+ ## SolverForge Concepts In Plain Language
36
+
37
+ - `Delivery`
38
+ Input stop data. The solver assigns delivery IDs into vehicle routes.
39
+ - `Vehicle`
40
+ Planning entity. Each vehicle owns one ordered `delivery_order` list.
41
+ - `Plan`
42
+ Planning solution. It holds deliveries, vehicles, score, routing mode, view
43
+ state, and prepared routing data.
44
+ - hard score
45
+ Missing assignments, capacity overage, late delivery seconds, and unreachable
46
+ route legs.
47
+ - soft score
48
+ Total travel seconds.
49
+ - retained job
50
+ A solve that lives in memory so the UI can stream events, fetch snapshots,
51
+ pause/resume, cancel, analyze, and delete terminal jobs.
52
+
53
+ ## Runtime Flow
54
+
55
+ 1. The browser loads `static/index.html`.
56
+ 2. `static/app/main.mjs` loads `static/sf-config.json`.
57
+ 3. The app fetches `/demo-data/PHILADELPHIA`.
58
+ 4. `PlanDto::from_plan()` serializes a refreshed transport plan with preview
59
+ state.
60
+ 5. The browser normalizes the plan, renders summary cards, tables, timelines,
61
+ and a map.
62
+ 6. When the user clicks Solve, the browser sends the current plan to
63
+ `POST /jobs`.
64
+ 7. `src/api/routes.rs` deserializes the `PlanDto`, rebuilds a `Plan`, and calls
65
+ `prepare_plan()`.
66
+ 8. `prepare_plan()` builds straight-line or road-network matrices and attaches
67
+ `PreparedVehicleRouting` to each vehicle.
68
+ 9. `SolverService` starts a retained solve through `SolverManager<Plan>`.
69
+ 10. Solver events are converted by `src/solver/service/runtime_payload.rs` into
70
+ UI-facing JSON.
71
+ 11. The browser consumes `/jobs/{id}/events` and fetches snapshots, analysis,
72
+ and route geometry for exact snapshot revisions.
73
+
74
+ ## File Map
75
+
76
+ ```text
77
+ .
78
+ β”œβ”€β”€ Cargo.toml
79
+ β”‚ Rust 1.95 crate metadata for app version 1.0.0 and latest published
80
+ β”‚ crates.io dependencies.
81
+ β”œβ”€β”€ solver.toml
82
+ β”‚ Embedded search policy for construction heuristics and local search.
83
+ β”œβ”€β”€ solverforge.app.toml
84
+ β”‚ App metadata, demo IDs, model facts/entities, crates.io dependency sources,
85
+ β”‚ and the `solverforge 0.9.1` runtime target.
86
+ β”œβ”€β”€ Makefile
87
+ β”‚ Hospital-style local build, validation, and Space/Docker commands.
88
+ β”œβ”€β”€ Dockerfile
89
+ β”‚ Multi-stage Rust 1.95 Docker image for Hugging Face Spaces.
90
+ β”œβ”€β”€ .dockerignore
91
+ β”‚ Keeps build artifacts, git metadata, route cache, and Playwright output out
92
+ β”‚ of the Docker context.
93
+ β”œβ”€β”€ README.md
94
+ β”‚ Run guide, dependency shape, API list, and learning path.
95
+ β”œβ”€β”€ AGENTS.md
96
+ β”‚ Repo-specific rules for future edits.
97
+ β”œβ”€β”€ WIREFRAME.md
98
+ β”‚ This architectural walkthrough.
99
+ β”œβ”€β”€ src/
100
+ β”‚ β”œβ”€β”€ domain/
101
+ β”‚ β”‚ `planning_model!` manifest, `Plan`, entities, facts, preview structs,
102
+ β”‚ β”‚ and route metrics.
103
+ β”‚ β”œβ”€β”€ constraints/
104
+ β”‚ β”‚ Assignment, capacity, time-window, and travel-time score rules.
105
+ β”‚ β”œβ”€β”€ data/
106
+ β”‚ β”‚ Deterministic city seed data and generator entrypoints.
107
+ β”‚ β”œβ”€β”€ solver/
108
+ β”‚ β”‚ Retained-job service and runtime event payload formatting.
109
+ β”‚ └── api/
110
+ β”‚ Axum routes, DTOs, and SSE endpoint.
111
+ β”œβ”€β”€ static/
112
+ β”‚ β”œβ”€β”€ index.html
113
+ β”‚ β”œβ”€β”€ sf-config.json
114
+ β”‚ β”œβ”€β”€ generated/ui-model.json
115
+ β”‚ └── app/
116
+ β”‚ Browser controller, plan models, and UI renderers.
117
+ └── tests/
118
+ β”œβ”€β”€ api_contract.rs
119
+ β”‚ Single integration-test crate composed from `tests/api_contract/*.rs`.
120
+ β”œβ”€β”€ api_contract/
121
+ β”‚ Catalog, job, lifecycle, SSE, and live-road modules.
122
+ β”œβ”€β”€ support/
123
+ β”‚ Shared integration-test helpers used by that single crate.
124
+ β”œβ”€β”€ e2e/
125
+ β”‚ Playwright browser tests for the served app.
126
+ └── frontend_models.test.mjs
127
+ Frontend model tests.
128
+ ```
129
+
130
+ ## Domain And Route Metrics
131
+
132
+ `src/domain/plan.rs` stays small and macro-facing. It owns the `Plan` struct,
133
+ normalization, list shadow refresh, transport refresh, and the
134
+ `VrpSolution` implementation.
135
+
136
+ Route-specific behavior lives under `src/domain/route_metrics/`:
137
+
138
+ - `preparation.rs`
139
+ Builds matrices and per-vehicle prepared routing data.
140
+ - `cvrp_hooks.rs`
141
+ Supplies Clarke-Wright, k-opt, load, capacity, and route replacement hooks.
142
+ - `metrics.rs`
143
+ Computes per-vehicle route metrics.
144
+ - `scoring.rs`
145
+ Builds preview DTOs and aggregate hard/soft score components.
146
+ - `routes.rs`
147
+ Builds straight-line or encoded road-network route geometry snapshots.
148
+ - `insertions.rs`
149
+ Ranks candidate insertion positions for one delivery.
150
+ - `types.rs`
151
+ Shared route metrics, snapshots, candidates, and routing trait types.
152
+
153
+ This split keeps the public domain API stable while avoiding oversized files.
154
+
155
+ ## Demo Data
156
+
157
+ `src/data/data_seed/entrypoints.rs` exposes three demo IDs:
158
+
159
+ - `PHILADELPHIA`
160
+ - `HARTFORD`
161
+ - `FIRENZE`
162
+
163
+ Each city has a small module with separate depot and grouped visit files. The
164
+ generator is deterministic. Every demo has ten vehicle depots, enough scaled
165
+ deliveries for those vehicles, reachable road-network coordinates, and enough
166
+ aggregate capacity before route ordering.
167
+
168
+ ## API And Retained Runtime
169
+
170
+ The REST API handles job control and snapshot reads:
171
+
172
+ - `/jobs` creates a retained solver job.
173
+ - `/jobs/{id}` and `/jobs/{id}/status` expose summary state.
174
+ - `/jobs/{id}/snapshot` returns an exact or latest snapshot.
175
+ - `/jobs/{id}/analysis` runs constraint analysis for a snapshot.
176
+ - `/jobs/{id}/routes` returns route geometry for a snapshot.
177
+ - `/jobs/{id}/events` streams typed lifecycle events.
178
+
179
+ The insertion endpoint, `/recommendations/delivery-insertions`, is app-specific.
180
+ It prepares the submitted plan, removes the requested delivery from any
181
+ existing route, evaluates candidate insert positions, and returns preview plans.
182
+
183
+ ## Frontend Layout
184
+
185
+ `static/app/main.mjs` is the controller. It owns current plan state, retained
186
+ job state, route identity tracking, and event handlers.
187
+
188
+ Supporting modules are split by responsibility:
189
+
190
+ - `static/app/models/core.mjs`
191
+ Clone and normalize incoming plans.
192
+ - `static/app/models/preview.mjs`
193
+ Draft straight-line preview scoring.
194
+ - `static/app/models/timeline.mjs`
195
+ Vehicle and delivery rail models.
196
+ - `static/app/models/formatters.mjs`
197
+ Labels, icons, tones, clocks, and durations.
198
+ - `static/app/ui/layout.mjs`
199
+ Page shell and stock SolverForge UI component composition.
200
+ - `static/app/ui/overview.mjs`
201
+ Summary, route list, non-panning route highlighting, map, and timeline
202
+ rendering.
203
+ - `static/app/ui/data-tables.mjs`
204
+ Read-only vehicle and delivery tables with delivery insertion recommendations.
205
+ - `static/app/ui/modals.mjs`
206
+ Analysis and insertion recommendation bodies.
207
+ - `static/app/ui/api-guide.mjs`
208
+ Visible API guide content.
209
+ - `static/app/ui/lifecycle.mjs`
210
+ Dataset markers and route-identity helpers.
211
+
212
+ ## Validation Surfaces
213
+
214
+ Use the Makefile as the repo-local workflow:
215
+
216
+ - `make fmt-check`
217
+ - `make clippy`
218
+ - `make build-release`
219
+ - `make test`
220
+ - `make test-e2e`
221
+ - `make space-build`
222
+ - `make test-live-road`
223
+ - `make ci-local`
224
+ - `make pre-release`
225
+
226
+ `make ci-local` includes the Docker image build used by the Hugging Face Space.
227
+
228
+ The file-size rule is part of the architecture: keep files below 300 lines and
229
+ split by responsibility before they become broad catch-all modules.