# S12 — Asynchronous feedback for scheduling Status: IMPLEMENTED 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 and rejection because inputs changed. Explain why no result was applied and that existing assignments were preserved. Backend-restart interruption recovery belongs to S16. ## 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 The maintainer explicitly transferred durable scheduling status and recovery following backend restarts to [S16](../in_review/S16_store-state-in-persistent-storage) when completing S12. The latest status and outcome in S12 survive navigation, page reloads and SSE reconnection while the same backend process remains active. Schools, assignments and scheduling status currently remain in memory. S16 owns PostgreSQL storage of the latest run, atomic persistence of saved assignments and completed status, and startup recovery of previously running calculations as Interrupted without automatic resumption. Previously saved results must survive restart under S16. These are not completion criteria for S12. 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 - [x] Starting Schedule Groups returns without waiting for solver completion; leaving or reloading the page does not interrupt the calculation. - [x] 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. - [x] Running status shows elapsed time, phase and discovery of a valid solution during a phase, without a fabricated completion percentage or ETA. - [x] 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. - [x] 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. - [x] 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. - [x] An application-wide snackbar reports completion or failure with the show name and View show action, including after navigation to another page. - [x] Connection recovery notifies once for a missed completion; phase changes, repeated reconnection and reopening do not replay old snackbars. - [x] The latest status and outcome survive navigation, page reload and SSE reconnection within the lifetime of the running backend. Durable storage and recovery after backend restart are explicitly transferred to S16. ## Review handoff Background execution, solver progress callbacks, SSE, frontend status recovery, result summaries, proxy streaming configuration and application-wide completion notifications are implemented and verified. S12 replaces S9's synchronous request behavior while retaining scheduling and result-application protections. See [S12 validation](../S12-validation.md) for verification and retained standards signals. Durable storage and backend-restart recovery are tracked in S16 and do not block review of this specification under the agreed scope adjustment. Implementation is ready for review; final acceptance is pending.