File size: 2,632 Bytes
7596726
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# API And Solver Policy

This page holds the longer reference material that must stay aligned with
`src/api/routes.rs`, `src/api/dto.rs`, `src/solver/service.rs`, `solver.toml`,
and the visible API guide in `static/app/shell/api-guide.mjs`.

## REST API

- `GET /health`
- `GET /info`
- `GET /demo-data`
- `GET /demo-data/{id}`
- `POST /jobs`
- `GET /jobs/{id}`
- `GET /jobs/{id}/status`
- `GET /jobs/{id}/snapshot`
- `GET /jobs/{id}/analysis`
- `POST /jobs/{id}/pause`
- `POST /jobs/{id}/resume`
- `POST /jobs/{id}/cancel`
- `DELETE /jobs/{id}`
- `GET /jobs/{id}/events`

## Lifecycle Semantics

- `pause` requests an exact runtime-managed pause and checkpoint
- `resume` continues from the retained checkpoint
- the user-facing Stop control calls `cancel` to stop a live or paused job
- `delete` removes a terminal retained job before the next fresh solve
- `GET /jobs/{id}` and `GET /jobs/{id}/status` return the same summary payload
- `snapshot_revision={n}` is optional on both snapshot and analysis requests
- reconnects bootstrap from current runtime status plus retained snapshot
  revision, not from cached SSE text

## Payload Shape

The transport payload mirrors the domain model directly. The important field is
`employeeIdx`, which is the scalar planning assignment chosen for each shift.

```json
{
  "employees": [
    {
      "id": "employee-0",
      "name": "Alex Smith",
      "homeHub": "critical_care",
      "skills": ["Critical care doctor"],
      "unavailableDates": [],
      "undesiredDates": [],
      "desiredDates": []
    }
  ],
  "shifts": [
    {
      "id": "shift-1",
      "start": "2024-01-01T08:00:00",
      "end": "2024-01-01T16:00:00",
      "location": "Critical care",
      "careHub": "critical_care",
      "requiredSkill": "Critical care doctor",
      "employeeIdx": 0
    }
  ],
  "score": "0hard/0soft"
}
```

Telemetry is intentionally a UI-facing projection, not the raw runtime type.
Fields like `elapsedMs`, `movesPerSecond`, and `acceptanceRate` are derived for
display.

## Solver Policy

The runtime source of truth is [../solver.toml](../solver.toml).

The currently shipped policy is deliberately narrow:

- `construction_heuristic = cheapest_insertion`
- one local-search phase
- nearby scalar change/swap selectors
- `late_acceptance`
- `accepted_count`

That is not an accident. A candidate sweep against broader scalar phase-2/3
variants showed that the current nearby baseline remained the best balanced
policy for this dataset and 30-second budget.

The canonical description of current behavior is `solver.toml`, the code,
`README.md`, this file, and `WIREFRAME.md`.