blackopsrepl's picture
chore(deps): update SolverForge runtime stack
8aa703c
metadata
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.md Quick start, concepts, API surface, and the shortest learning path.
  • WIREFRAME.md Architecture and request/data flow across backend, runtime, and frontend.
  • docs/api-and-solver-policy.md REST routes, payload shape, lifecycle semantics, and solver policy notes.
  • AGENTS.md Contribution rules, validation commands, and the documentation standard for future edits.
  • Makefile The 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:

  1. The planning-model manifest and model modules in src/domain/
  2. The score rules in src/constraints/
  3. The runtime and browser app in src/api/, src/solver/, and static/app/

What SolverForge Is Doing Here

SolverForge is the optimization engine. In this app:

  • Employee is a problem fact: input data the solver does not move
  • Shift is the planning entity: the thing the solver assigns
  • Shift.employee_idx is the planning variable: the actual choice the solver makes
  • the constraints decide whether an assignment is legal and whether it is good
  • solver.toml tells 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:

  1. src/domain/employee.rs Employee is the input fact model.
  2. src/domain/care_hub.rs CareHub explains how the app models service-line proximity.
  3. src/domain/mod.rs This is the planning_model! manifest that lists and exports the model modules.
  4. src/domain/plan.rs Shift, Plan, nearby search meters, and transport normalization live here.
  5. src/constraints/mod.rs This lists every scoring rule.
  6. src/constraints/*.rs Each file explains one real scheduling rule.
  7. src/data/data_seed/entrypoints.rs This shows the public demo-data surface.
  8. src/data/data_seed/large.rs This assembles the published benchmark instance.
  9. src/solver/service.rs This is the retained-job runtime facade.
  10. src/api/routes.rs and src/api/sse.rs These expose the HTTP and live-event contracts.
  11. static/app/main.mjs This is the browser boot sequence.
  12. static/app/shell/ and static/app/schedule/ These adapt stock solverforge-ui pieces 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 over SolverManager<Plan>.
  • src/api/ REST routes, DTOs, and SSE endpoint.
  • static/app/ Browser code built as plain ES modules on top of solverforge-ui.
  • tests/frontend/ Browserless UI tests using the fake DOM in tests/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.1
  • solverforge-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:

  1. Loads static/sf-config.json
  2. Loads static/generated/ui-model.json
  3. Fetches the LARGE demo dataset from /demo-data/LARGE
  4. Renders two schedule views: By location and By employee
  5. 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.