S19: consume versioned engineering resources and move landscape documentation
All checks were successful
Build, test and publish / verify (push) Successful in 8m54s
All checks were successful
Build, test and publish / verify (push) Successful in 8m54s
This commit is contained in:
86
docs/validation/S12-validation.md
Normal file
86
docs/validation/S12-validation.md
Normal file
@@ -0,0 +1,86 @@
|
||||
> Historical validation evidence from application commit `bd898e92d22f6c412e671908770f4d89c8ae12bc`. Commands retain their original paths; current tooling is documented in README.md.
|
||||
|
||||
# S12 implementation validation
|
||||
|
||||
## Delivered behavior
|
||||
|
||||
Scheduling starts through a short POST returning 202 and a run identifier.
|
||||
The backend reserves and snapshots inputs before submitting background work;
|
||||
completion applies a validated result or records a distinct unsuccessful outcome.
|
||||
Per-show exclusion remains in the shared school service, with different shows
|
||||
allowed to calculate concurrently. Status publication and subscription snapshots
|
||||
share a lock so connecting cannot miss a transition between snapshot and subscription.
|
||||
|
||||
The solver publishes optimization phases and first feasible-solution discovery
|
||||
through a callback. Intermediate assignments remain private. Final summaries
|
||||
calculate the same attendance, spread and adjacency penalties as the solver.
|
||||
|
||||
SSE provides a current snapshot on connection and status changes, with separate
|
||||
15-second heartbeats. The nginx proxy disables buffering. The frontend keeps one
|
||||
application-wide connection, explicitly retries connection errors (including
|
||||
permanent EventSource failures caused by proxy responses), and reconciles state
|
||||
without event replay. Run identifiers deduplicate completion notifications.
|
||||
|
||||
## Validation
|
||||
|
||||
- Maven verify: 60 backend tests passed, plus 19 standards-checker regression tests.
|
||||
- Backend line coverage: 1346/1384, or 97.25%, above the required 80%.
|
||||
- Frontend: 30 unit tests, production build and ESLint.
|
||||
- Playwright: three real REST/browser scenarios, including scheduling completion,
|
||||
result summaries, a completion snackbar, reloading to recover the latest result
|
||||
and suppression of old notifications after reload.
|
||||
- HTTP SSE integration verifies initial snapshot, pushed completion and a new
|
||||
connection recovering the completed run.
|
||||
- Background tests cover duplicate exclusion, parallel shows, stale-result
|
||||
rejection, preserved assignments, failure outcomes and retry after failure.
|
||||
- Frontend tests cover missed completion after disconnect, reconnection, heartbeat
|
||||
handling, deduplication, completion arriving before the POST response and a
|
||||
locally started run completing before the first successful SSE connection.
|
||||
- Real solver tests cover phase/discovery callbacks, distinct infeasible/no-solution
|
||||
outcomes and objective-summary definitions including coach exemptions.
|
||||
|
||||
## Manual standards assessment
|
||||
|
||||
Scheduling states and phases use backend enums and frontend string unions while
|
||||
preserving their JSON names. Initial SSE recovery notifies for locally tracked
|
||||
running tasks while suppressing historical completions.
|
||||
|
||||
No waivers or weakened checks were introduced. The architecture tests pass.
|
||||
New records contain immutable values; the SSE snapshot defensively copies its
|
||||
list. The ten-component SchedulingRun record groups run identity, timestamps,
|
||||
progress and outcome in one immutable snapshot, avoiding mutable task state in
|
||||
API responses. Solver observers use the existing application-owned port and
|
||||
framework-independent domain types; OR-Tools remains encapsulated in solver.
|
||||
|
||||
Retained review signals:
|
||||
|
||||
- SchedulingRuns fan-out (26): task orchestration uses JDK executor/collection
|
||||
types, the scheduling port and immutable input/progress/result/status models.
|
||||
Its injected dependencies remain two; splitting these short lifecycle methods
|
||||
would distribute the shared publication and run-slot ordering.
|
||||
- SchedulingEventsResource fan-out (16): SSE/Mutiny transport, JSON envelope and
|
||||
service subscription types are confined to the REST adapter.
|
||||
- OrToolsSchedulingEngine fan-out (21), solve cognitive complexity (11) and
|
||||
length (41 code lines): the ordered three-stage loop retains deadline and
|
||||
earlier-feasible-result fallback behavior while publishing phase/discovery.
|
||||
requireSolution cyclomatic complexity (8) retains explicit mappings for stable
|
||||
failure outcomes and their human-readable explanations.
|
||||
- Integration/background test fan-out and the background lifecycle test's
|
||||
34-line method reflect real HTTP/solver fixtures and lifecycle assertions.
|
||||
Existing REST-test length signals remain below blocking limits after adapting
|
||||
them to await background completion.
|
||||
|
||||
## Persistence follow-up in S16
|
||||
|
||||
The maintainer explicitly transferred durable scheduling status and
|
||||
backend-restart recovery to S16 and approved completion of S12 with that scope
|
||||
adjustment. S12 is IN_REVIEW in `in_review/S12_support-async-feedback-for-scheduling`;
|
||||
implementation is ready for review and final acceptance is pending.
|
||||
|
||||
The application currently stores schools, saved assignments and the latest
|
||||
scheduling status in memory. S16 now explicitly requires PostgreSQL storage of
|
||||
accepted runs and their latest status, atomic durable result/status commits,
|
||||
stable identifiers in recovered API/SSE snapshots and startup conversion of
|
||||
previously running calculations to Interrupted without automatic resumption.
|
||||
Restart/crash recovery tests belong to S16; the S12 validation above covers
|
||||
navigation, browser reload and connection recovery within one backend lifetime.
|
||||
Reference in New Issue
Block a user