solverforge-fsr / README.md
github-actions[bot]
chore: sync uc-fsr Space
4f50b67
|
Raw
History Blame Contribute Delete
6.71 kB
---
title: SolverForge Field Service Routing
emoji: 🧰
colorFrom: indigo
colorTo: blue
sdk: docker
app_port: 7860
pinned: false
license: apache-2.0
short_description: SolverForge field-service routing example
---
# SolverForge FSR
![SolverForge FSR screenshot](docs/screenshot.png)
`solverforge-fsr` is a SolverForge field-service routing app with retained
jobs, technician schedules, road-network geometry, and a browser map workspace.
It answers one concrete question:
"Given technicians, service visits, skills, parts, shifts, territories, and
road-network travel, which technician should serve each visit and in what
order?"
## Quick Start
```sh
make run-release
```
Then open `http://localhost:7860`.
To inspect the supported command surface:
```sh
make help
```
## Documentation Map
- `README.md`
Quick start, model concepts, validation, REST API, and solver policy.
- `WIREFRAME.md`
As-built architecture and runtime/data flow across backend, routing, and UI.
- `AGENTS.md`
Codex-facing maintenance, validation, and documentation rules.
- `Makefile`
Supported local commands for development, validation, Docker, and Space work.
- `Dockerfile`
Docker Space image build using Rust 1.95 and the declared crates.io line.
## Current Dependency Shape
- Package: `solverforge-fsr`; version is declared in `Cargo.toml`
- Release binary: `solverforge_fsr`
- Rust: `1.95`
- SolverForge runtime: `solverforge` `0.19.3`
- SolverForge core helpers: `solverforge-core` `0.19.3`
- Browser UI assets: `solverforge-ui` `0.6.5`
- Routing engine: `solverforge-maps` `2.1.4`
- Scaffold metadata: `solverforge-cli` `2.2.2` in `solverforge.app.toml`
The app serves registry-backed Rust dependencies, local static browser modules,
and Axum API routes from one process.
## Model Concepts
- `Location` is a problem fact: a depot or customer coordinate.
- `ServiceVisit` is a problem fact: a customer job the solver must place in a
route.
- `TravelLeg` is a problem fact: precomputed duration, distance, and
reachability between two locations.
- `TechnicianRoute` is the planning entity: one route owned by one technician.
- `TechnicianRoute.visits` is the list planning variable: the ordered visit
sequence SolverForge changes.
- `FieldServicePlan` is the planning solution with the current `HardSoftScore`.
The app ships one deterministic `STANDARD` Bergamo dataset with two depots, six
technicians, 24 customer locations, and 48 service visits.
## Constraints
Hard constraints:
- Every service visit is assigned exactly once, and route visit indexes are valid.
- Every route leg is reachable.
- The assigned technician has the required skills.
- The assigned technician carries the required parts.
- Visits fit their time windows.
- Routes fit technician shift capacity.
Soft constraints:
- Total travel time is minimized.
- Workload is balanced across technicians.
- Territory affinity is preferred.
- Deadline slack is rewarded more strongly for higher-priority visits.
## REST API
- `GET /health`
- `GET /info`
- `GET /demo-data`
- `GET /demo-data/{id}`
- `POST /jobs`
- `GET /jobs/{id}`
- `DELETE /jobs/{id}`
- `GET /jobs/{id}/status`
- `GET /jobs/{id}/snapshot`
- `GET /jobs/{id}/analysis`
- `GET /jobs/{id}/routes`
- `POST /jobs/{id}/pause`
- `POST /jobs/{id}/resume`
- `POST /jobs/{id}/cancel`
- `GET /jobs/{id}/events`
`snapshot_revision={n}` is optional for snapshots, analysis, and route
geometry. Route geometry reports unreachable, snap-failed, and no-path legs as
segment statuses so one failed road leg does not hide the rest of the route.
## Solver Policy
`solver.toml` is embedded by `FieldServicePlan` and is the runtime source of
truth.
- `list_round_robin` creates the first visit distribution.
- Local search combines list change, list swap, sublist change, sublist swap,
and reverse moves over `TechnicianRoute.visits`.
- `hill_climbing` with `first_best_score_improving` keeps this tutorial easy to
reason about.
- Solving stops after 60 seconds.
Road-network routing is prepared from the deterministic Bergamo coordinates and
stored as `TravelLeg` facts before solving.
## Validation
Standard validation:
```sh
make test
```
Full local validation:
```sh
make ci-local
```
`make test` runs Rust tests, JavaScript syntax checks, and Playwright browser
tests. `make ci-local` adds formatting, clippy, release build, and Docker image
build.
## Hugging Face Space Deployment
This repo is Docker-Space ready. The Space reads the README front matter,
builds `Dockerfile`, and expects the app to bind `PORT=7860`.
Local Space-equivalent commands:
```sh
make space-build
make space-run
```
## Read The Code In This Order
1. `src/domain/mod.rs`
The `planning_model!` manifest and public domain exports.
2. `src/domain/field_service_plan.rs`
The solution type, fact collections, route entities, transient index
normalization, route shadow refresh, and score.
3. `src/domain/location.rs`, `src/domain/service_visit.rs`, and
`src/domain/travel_leg.rs`
The problem facts the solver reads.
4. `src/domain/technician_route.rs` and `src/domain/route_metrics.rs`
The planning entity, list variable SolverForge mutates, and route shadow
measurements used by stock constraints.
5. `src/data/data_seed.rs` and `src/data/bergamo_*.rs`
Demo ID, Bergamo data assembly, static fact catalogs, routing preparation,
and cache policy.
6. `src/constraints/mod.rs`
The score model assembled from SolverForge constraints.
7. `src/constraints/*.rs`
One business scoring rule per file. Most rules use stock `ConstraintFactory`
streams; duplicate visit assignment uses a custom incremental counter so
retained score analysis counts only real duplicate groups.
8. `src/solver/service.rs`
Retained-job orchestration over `SolverManager<FieldServicePlan>`.
9. `src/api/routes.rs`, `src/api/dto.rs`, `src/api/route_geometry.rs`, and
`src/api/sse.rs`
HTTP routes, transport DTOs, route geometry, and live-event streaming.
10. `static/app.js` and `static/app-*.js`
Browser lifecycle, dataset loading, route rendering, maps, tables, and API
guide.
## Project Shape
- `src/domain/`
Planning model, domain types, route entities, and route shadow measurements.
- `src/constraints/`
SolverForge scoring rules, one business rule per file; most use stock streams.
- `src/data/`
Deterministic Bergamo demo data and road-network preparation.
- `src/solver/`
Retained-job facade and runtime event payload formatting.
- `src/api/`
Axum routes, DTOs, route geometry, and SSE endpoint.
- `static/`
Browser workspace built on stock `solverforge-ui` assets.
- `tests/e2e/`
Playwright browser tests for the served app.