diff --git a/specs/S12_support-async-feedback-for-scheduling b/specs/S12_support-async-feedback-for-scheduling deleted file mode 100644 index e69de29..0000000 diff --git a/specs/refined/S12_support-async-feedback-for-scheduling b/specs/refined/S12_support-async-feedback-for-scheduling new file mode 100644 index 0000000..f3ff145 --- /dev/null +++ b/specs/refined/S12_support-async-feedback-for-scheduling @@ -0,0 +1,139 @@ +# S12 — Asynchronous feedback for scheduling + +Status: REFINED + +Agreed after the grill-me interview; shared understanding confirmed. + +## User story + +As a dance-school maintainer, I want feedback after starting Schedule Groups, +so that I can see whether the backend is still calculating, when it finishes +and what the outcome is, including when I leave and return to the show page. + +## Background execution and concurrency + +- Start scheduling in the backend without keeping the initiating HTTP request + open until the calculation finishes. Navigation, page reloads and disconnected + clients must not stop the calculation. +- The backend owns the current scheduling status for each show. All open + screens see the same status, including screens that did not start the run. +- Allow at most one active calculation per show. Disable Schedule Groups while + it is running and reject duplicate starts in the backend as well. +- Different shows may calculate concurrently. A global capacity limit and a + waiting queue are outside S12. +- Retain the existing 30-minute solver limit and scheduling rules. + +## Progress and outcomes + +- While running, show elapsed time, the current optimization phase (attendance, + spread or variety), and whether a valid solution has been found. +- Report a valid solution as soon as the solver discovers one, including during + a phase. Extend solver progress reporting rather than waiting for the phase + to finish. Do not apply intermediate solutions. +- Do not present a completion percentage or estimated finish time: the phases + do not represent proportional parts of the calculation time. +- Keep the latest status and outcome per show until a new calculation starts. + Show the finish time and distinguish an optimal solution from a valid solution + whose optimality was not proven within the time limit. +- For a successful result, show a concise summary with concrete results for + attendance, spread and variety, using understandable labels. +- Clearly distinguish invalid input, infeasibility, solver failure, time limit + without a valid solution, rejection because inputs changed, and interruption + by a backend restart. Explain why no result was applied and that existing + assignments were preserved. + +## Applying results + +- Retain the confirmation before starting that explains replacement of existing + assignments. A successful completed calculation automatically replaces them; + no preview/apply step is introduced. +- A valid solution may be applied when the time limit expires even if optimality + has not been proven. +- Preserve the existing scheduling input revision check. A result based on + outdated inputs must not replace the current assignments. +- Failed, infeasible, interrupted, stale and no-solution calculations preserve + existing assignments. +- Report success only after the resulting assignments have been saved. Keep + status and saved results consistent. + +## Server-sent events and connection recovery + +- Use server-sent events (SSE) for backend-to-frontend status updates. +- On initial connection and reconnection, provide the current backend status. + Correctness must not depend on receiving every previous event. +- Maintain updates across navigation within the application so completion + notifications can appear outside the show page. +- If the connection is lost, indicate that displayed status may be outdated + while the backend calculation continues. Reconnect and reconcile with the + current status when connectivity returns. +- Configure the application's proxy for streaming so updates reach the client + promptly rather than being buffered until completion. + +## Completion notifications + +- Show an application-wide snackbar when a calculation completes or fails, + including when the user has navigated to another application page. +- Include the show name, a short outcome and a View show action. +- Phase changes update progress without generating snackbars. +- After temporary connection loss, show a missed completion notification once + when the connection recovers. Reconnection must not repeatedly notify for + the same completion. +- Do not replay old snackbars on page reload or reopening the application; + show the retained status on the show page instead. +- Email, browser notifications and notifications outside the application are + outside S12. + +## Persistence and backend restarts + +- Retain the latest scheduling status and outcome across backend restarts, + aligned with the PostgreSQL persistence specified in + `S16_store-state-in-persistent-storage`. +- Calculations interrupted by a backend restart become recognizably Interrupted + rather than remaining Running indefinitely. Do not resume them automatically; + allow the user to start again. +- Previously saved results survive restart. Volatile in-memory status alone + does not satisfy S12; its implementation must integrate with S16 storage. +- Target the single active backend instance defined by S16. Distributed + execution and scheduling on another PC remain in S13. + +## Out of scope + +- Cancelling a calculation or applying an intermediate solution. +- History of earlier calculations beyond the latest status and outcome. +- Global capacity limits, queues and remote workers. +- Changes to scheduling objectives or constraints. +- This specification grants no coding-standards waiver. + +## Acceptance criteria + +- [ ] Starting Schedule Groups returns without waiting for solver completion; + leaving or reloading the page does not interrupt the calculation. +- [ ] Opening a show in another screen recovers its current backend status; + duplicate runs for the same show are prevented in frontend and backend, + while different shows can run concurrently. +- [ ] Running status shows elapsed time, phase and discovery of a valid solution + during a phase, without a fabricated completion percentage or ETA. +- [ ] SSE delivers status changes promptly through the deployed proxy. Initial + connection and reconnection reconcile the current state, and loss of + connectivity visibly marks status as potentially outdated. +- [ ] Successful runs automatically apply their result after the existing start + confirmation, retain stale-input protection and distinguish proven optimal + results from valid results at the time limit. +- [ ] The final display includes finish time and concrete attendance, spread and + variety results when successful; unsuccessful outcomes are distinguishable + and explain that previous assignments were preserved. +- [ ] An application-wide snackbar reports completion or failure with the show + name and View show action, including after navigation to another page. +- [ ] Connection recovery notifies once for a missed completion; phase changes, + repeated reconnection and reopening do not replay old snackbars. +- [ ] The latest status and outcome survive navigation, reload and backend + restart through persistent storage integrated with S16. +- [ ] After backend restart, interrupted calculations are marked Interrupted, + do not resume automatically and can be started again; saved results remain. + +## Implementation handoff + +This specification records the agreed design and behavior. Backend and frontend +changes, persistence integration, proxy configuration and validation are +subsequent implementation work. S12 replaces S9's synchronous request behavior +while retaining the existing scheduling and result-application protections.