title: SolverForge Hospital
emoji: 🏥
colorFrom: red
colorTo: pink
sdk: docker
app_port: 7860
pinned: false
license: apache-2.0
short_description: SolverForge hospital scheduling example
SolverForge Hospital
solverforge-hospital is a beginner-friendly example of a real SolverForge app.
It answers one concrete question:
"Given a hospital workforce and a month of shifts, which employee should cover each shift?"
Documentation Map
Each top-level document has a different job:
README.mdQuick start, concepts, API surface, and the shortest learning path.WIREFRAME.mdArchitecture and request/data flow across backend, runtime, and frontend.docs/api-and-solver-policy.mdREST routes, payload shape, lifecycle semantics, and solver policy notes.AGENTS.mdContribution rules, validation commands, and the documentation standard for future edits.MakefileThe beginner-friendly command surface for local development, validation, and Docker-based Hugging Face Space preparation.
If you are new to SolverForge, read this repo as three layers:
- The planning-model manifest and model modules in
src/domain/ - The score rules in
src/constraints/ - The runtime and browser app in
src/api/,src/solver/, andstatic/app/
What SolverForge Is Doing Here
SolverForge is the optimization engine. In this app:
Employeeis a problem fact: input data the solver does not moveShiftis the planning entity: the thing the solver assignsShift.employee_idxis the planning variable: the actual choice the solver makes- the constraints decide whether an assignment is legal and whether it is good
solver.tomltells the runtime how to search for a better assignment
The app ships one serious demo instance rather than many toy presets:
- fixed random seed
- fixed 28-day schedule horizon
- 50 employees
- 688 shifts
- 8-hour shifts
- deterministic generator
- retained-job runtime with pause, resume, cancel, snapshot, and analysis
Read The Code In This Order
If you want to learn the codebase, this order is the shortest path:
- src/domain/employee.rs
Employeeis the input fact model. - src/domain/care_hub.rs
CareHubexplains how the app models service-line proximity. - src/domain/mod.rs
This is the
planning_model!manifest that lists and exports the model modules. - src/domain/plan.rs
Shift,Plan, nearby search meters, and transport normalization live here. - src/constraints/mod.rs This lists every scoring rule.
- src/constraints/*.rs Each file explains one real scheduling rule.
- src/data/data_seed/entrypoints.rs This shows the public demo-data surface.
- src/data/data_seed/large.rs This assembles the published benchmark instance.
- src/solver/service.rs This is the retained-job runtime facade.
- src/api/routes.rs and src/api/sse.rs These expose the HTTP and live-event contracts.
- static/app/main.mjs This is the browser boot sequence.
- static/app/shell/ and static/app/schedule/
These adapt stock
solverforge-uipieces to the hospital example.
Project Shape
src/domain/planning_model!manifest, planning model, derived fields, nearby meters.src/constraints/Hard and soft scoring rules.src/data/Deterministic demo-data generator.src/solver/Retained-job orchestration overSolverManager<Plan>.src/api/REST routes, DTOs, and SSE endpoint.static/app/Browser code built as plain ES modules on top ofsolverforge-ui.tests/frontend/Browserless UI tests using the fake DOM intests/support/.tests/e2e/Playwright smoke tests against the served browser app.
Quick Start
This repo depends on the published SolverForge runtime and UI crates:
solverforge = 0.11.1solverforge-ui = 0.6.5
Run the app:
make run-release
Then open http://localhost:7860.
If you want to inspect the command surface first:
make help
What You Will See
The browser UI does five things:
- Loads
static/sf-config.json - Loads
static/generated/ui-model.json - Fetches the
LARGEdemo dataset from/demo-data/LARGE - Renders two schedule views:
By locationandBy employee - Starts a retained solving job when you click Solve
The frontend is intentionally thin. It mostly uses stock solverforge-ui pieces:
SF.createBackend({ type: "axum" })SF.createHeader()SF.createStatusBar()SF.createSolver()SF.rail.createTimeline()
The app also exposes a visible "REST API" guide inside the browser shell. See
docs/api-and-solver-policy.md for the route
list, lifecycle semantics, payload shape, and solver policy notes that this
guide is expected to match.
Run Validation
Standard local validation:
make test
Space-style local CI simulation:
make ci-local
Slow acceptance solve:
make test-slow
make test includes Rust tests, browserless frontend tests, and Playwright
browser tests. make ci-local is the main pre-push validation path for this
repo. It also checks formatting, runs clippy, builds the release binary, and
builds the Docker image that the Space-style deploy path expects.
Demo Dataset Intent
The generator is not random filler data. It is designed to publish a problem that is:
- hard-feasible
- deterministic
- narrow enough that candidate choice matters
- rich enough that soft-score improvements still exist after construction
The hidden witness roster in src/data/data_seed/witness.rs is especially
important: it gives the generator an internal feasible assignment that is used
to shape unavailability and preferences, but it is never shown to the solver.
The LARGE dataset is built once and cached in memory because it is immutable
and deterministic. Each request still receives an owned Plan, but the server
does not regenerate the same public benchmark from scratch every time.
API And Solver Policy
Detailed REST route, payload, lifecycle, telemetry, and solver-policy reference
material lives in docs/api-and-solver-policy.md.
The runtime source of truth remains solver.toml.
Constraints
Hard constraints:
- Assigned shift
- Required skill
- Overlapping shift
- At least 10 hours between 2 shifts
- One shift per day
- Unavailable employee
Soft constraints:
- Undesired day for employee
- Desired day for employee
- Balance employee assignments
Docker
Build from this repository root:
make space-build
make space-run
The Docker build uses the same published crates as local development.