solverforge-deliveries WIREFRAME
This file is the architectural map for the deliveries example.
README.md explains how to run and use the app. This document explains how the
pieces fit together and where each responsibility lives.
Documentation Roles
README.mdQuick start, dependency shape, route list, and user-facing orientation.WIREFRAME.mdArchitecture, execution flow, and file-map walkthrough.AGENTS.mdRepo-specific contribution, validation, and documentation rules.MakefileLocal development, validation, and Space/Docker command surface.DockerfileHugging Face Docker Space image definition.docs/screenshot.pngCurrent browser screenshot embedded by the README.
What This Repo Is Teaching
This repo is a complete solverforge-deliveries 1.0.1 list-variable
SolverForge app for delivery routing.
It shows how to combine:
- a
Plansolution with a list planning variable - route-specific score rules
- SolverForge CVRP construction and local-search hooks
solverforge-mapsroad-network preparation and route geometry- retained jobs with snapshots, analysis, cancel, pause, resume, and SSE
- a browser plan viewer built on stock
solverforge-uiassets
SolverForge Concepts In Plain Language
DeliveryInput stop data. The solver assigns delivery IDs into vehicle routes.VehiclePlanning entity. Each vehicle owns one ordereddelivery_orderlist.PlanPlanning solution. It holds deliveries, vehicles, score, routing mode, view state, and prepared routing data.- hard score Missing assignments, capacity overage, late delivery seconds, and unreachable route legs.
- soft score Total travel seconds.
- retained job A solve that lives in memory so the UI can stream events, fetch snapshots, pause/resume, cancel, analyze, and delete terminal jobs.
Runtime Flow
- The browser loads
static/index.html. static/app/main.mjsloadsstatic/sf-config.json.- The app fetches
/demo-data/PHILADELPHIA. PlanDto::from_plan()serializes a refreshed transport plan with preview state.- The browser normalizes the plan, renders summary cards, tables, timelines, and a map.
- When the user clicks Solve, the browser sends the current plan to
POST /jobs. src/api/routes.rsdeserializes thePlanDto, rebuilds aPlan, and callsprepare_plan().prepare_plan()builds straight-line or road-network matrices and attachesPreparedVehicleRoutingto each vehicle.SolverServicestarts a retained solve throughSolverManager<Plan>.- Solver events are converted by
src/solver/service/runtime_payload.rsinto UI-facing JSON. - The browser consumes
/jobs/{id}/eventsand fetches snapshots, analysis, and route geometry for exact snapshot revisions. - Road-network route geometry follows the
solverforge-mapsgraph route, projects each leg endpoint onto the nearest road segment, and stitches the exact depot or delivery coordinate back in before encoding so each displayed leg reaches the visible markers.
File Map
.
βββ Cargo.toml
β Rust 1.95 crate metadata for app version 1.0.1 and registry dependency
β requests.
βββ solver.toml
β Embedded search policy for construction heuristics and local search.
βββ solverforge.app.toml
β App metadata, demo IDs, model facts/entities, registry dependency sources,
β and the `solverforge 0.13.1` runtime target.
βββ Makefile
β Hospital-style local build, validation, and Space/Docker commands.
βββ Dockerfile
β Multi-stage Rust 1.95 Docker image for Hugging Face Spaces.
βββ .dockerignore
β Keeps build artifacts, git metadata, route cache, and Playwright output out
β of the Docker context.
βββ README.md
β Run guide, dependency shape, API list, and learning path.
βββ AGENTS.md
β Repo-specific rules for future edits.
βββ WIREFRAME.md
β This architectural walkthrough.
βββ docs/screenshot.png
β Current browser screenshot used by the README.
βββ src/
β βββ domain/
β β `planning_model!` manifest, `Plan`, entities, facts, preview structs,
β β and route metrics.
β βββ constraints/
β β Assignment, capacity, time-window, and travel-time score rules.
β βββ data/
β β Deterministic city seed data and generator entrypoints.
β βββ solver/
β β Retained-job service and runtime event payload formatting.
β βββ api/
β Axum routes, DTOs, and SSE endpoint.
βββ static/
β βββ index.html
β βββ sf-config.json
β βββ generated/ui-model.json
β βββ app/
β Browser controller, plan models, and UI renderers.
βββ tests/
βββ api_contract.rs
β Single integration-test crate composed from `tests/api_contract/*.rs`.
βββ api_contract/
β Catalog, job, lifecycle, SSE, and live-road modules.
βββ support/
β Shared integration-test helpers used by that single crate.
βββ e2e/
β Playwright browser tests for the served app.
βββ frontend_models.test.mjs
Frontend model tests.
Domain And Route Metrics
src/domain/plan.rs stays small and macro-facing. It owns the Plan struct,
normalization, list shadow refresh, transport refresh, and the
VrpSolution implementation.
Route-specific behavior lives under src/domain/route_metrics/:
preparation.rsBuilds matrices and per-vehicle prepared routing data.cvrp_hooks.rsSupplies Clarke-Wright, k-opt, load, capacity, and route replacement hooks.metrics.rsComputes per-vehicle route metrics.scoring.rsBuilds preview DTOs and aggregate hard/soft score components.routes.rsBuilds straight-line or road-network route geometry snapshots, including edge-projected visual endpoints for road legs.insertions.rsRanks candidate insertion positions for one delivery.types.rsShared route metrics, snapshots, candidates, and routing trait types.
This split keeps the public domain API stable while avoiding oversized files.
Demo Data
src/data/data_seed/entrypoints.rs exposes three demo IDs:
PHILADELPHIAHARTFORDFIRENZE
Each city has a small module with separate depot and grouped visit files. The generator is deterministic. Every demo has ten vehicle depots, enough scaled deliveries for those vehicles, reachable road-network coordinates, and enough aggregate capacity before route ordering.
API And Retained Runtime
The REST API handles job control and snapshot reads:
/jobscreates a retained solver job./jobs/{id}and/jobs/{id}/statusexpose summary state./jobs/{id}/snapshotreturns an exact or latest snapshot./jobs/{id}/analysisruns constraint analysis for a snapshot./jobs/{id}/routesreturns route geometry for a snapshot./jobs/{id}/eventsstreams typed lifecycle events.
The insertion endpoint, /recommendations/delivery-insertions, is app-specific.
It prepares the submitted plan, removes the requested delivery from any
existing route, evaluates candidate insert positions, and returns preview plans.
Frontend Layout
static/app/main.mjs is the controller. It owns current plan state, retained
job state, route identity tracking, and event handlers.
Supporting modules are split by responsibility:
static/app/models/core.mjsClone and normalize incoming plans.static/app/models/preview.mjsDraft straight-line preview scoring.static/app/models/timeline.mjsVehicle and delivery rail models.static/app/models/formatters.mjsLabels, icons, tones, clocks, and durations.static/app/ui/layout.mjsPage shell and stock SolverForge UI component composition.static/app/ui/overview.mjsSummary, route list, vehicle-id keyed route highlighting, map, and timeline rendering. The tutorial uses ten distinct map colors for its ten fixed vehicles.static/app/ui/data-tables.mjsRead-only vehicle and delivery tables with delivery insertion recommendations.static/app/ui/modals.mjsAnalysis and insertion recommendation bodies.static/app/ui/api-guide.mjsVisible API guide content.static/app/ui/lifecycle.mjsDataset markers and route-identity helpers.
Validation Surfaces
Use the Makefile as the repo-local workflow:
make fmt-checkmake clippymake build-releasemake testmake test-e2emake space-buildmake test-live-roadmake ci-localmake pre-release
make ci-local includes the Docker image build used by the Hugging Face Space.
The Playwright command uses the publication bundle's root Node dev dependency;
runtime UI assets are served from the declared solverforge-ui Cargo crate.
The file-size rule is part of the architecture: keep files below 300 lines and split by responsibility before they become broad catch-all modules.