Compare commits
2 Commits
aa29283a94
...
f64aa9123d
| Author | SHA1 | Date | |
|---|---|---|---|
| f64aa9123d | |||
| 9171a2d932 |
0
specs/S10_allow-group-exclusion-for-show
Normal file
0
specs/S10_allow-group-exclusion-for-show
Normal file
0
specs/S11_add-season-context-go-groups-and-shows
Normal file
0
specs/S11_add-season-context-go-groups-and-shows
Normal file
0
specs/S12_support-async-feedback-for-scheduling
Normal file
0
specs/S12_support-async-feedback-for-scheduling
Normal file
@@ -1,6 +1,6 @@
|
||||
# S2 — ESLint for the frontend
|
||||
|
||||
Status: IN_REVIEW
|
||||
Status: IMPLEMENTED
|
||||
|
||||
Agreed after the grill-me review; shared understanding confirmed.
|
||||
|
||||
153
specs/refined/S9_spread-dancegroups-via-ortools-setup
Normal file
153
specs/refined/S9_spread-dancegroups-via-ortools-setup
Normal file
@@ -0,0 +1,153 @@
|
||||
# S9 — Schedule dance groups across show dayparts with OR-Tools
|
||||
|
||||
Status: REFINED
|
||||
|
||||
Agreed after the grill-me review; shared understanding confirmed.
|
||||
|
||||
## User story
|
||||
|
||||
As a dance-school maintainer, I want to assign my school's dance groups to a
|
||||
show's dated dayparts, using configurable appearance counts per group type,
|
||||
so that appearances are spread evenly across the show.
|
||||
|
||||
## Show configuration
|
||||
|
||||
- A show can have one to six dayparts across multiple dates. Each daypart has a
|
||||
date and a type: MORNING, AFTERNOON or EVENING. A date/type combination must be
|
||||
unique within a show. For example, Friday afternoon, Saturday afternoon and
|
||||
Saturday evening are three distinct dayparts.
|
||||
- An unscheduled show may have no dayparts while being configured.
|
||||
- Daypart dates are the source of truth. Remove the separate editable show date.
|
||||
Display the range from the earliest to the latest daypart date, or
|
||||
"No dates configured" when there are none.
|
||||
- Each show stores an editable appearance count for every dance-group type,
|
||||
including types with no current groups. Remove the backend
|
||||
`DanceGroupType.dayPartsRequired` property.
|
||||
- Initialize counts when creating the show using the following defaults, where
|
||||
N is the configured number of dayparts:
|
||||
|
||||
| Type | Default appearances |
|
||||
| --- | --- |
|
||||
| PRE_SCHOOLER | 1 |
|
||||
| SHOW_CASE | N |
|
||||
| PRE_EDUCATION | N |
|
||||
| All remaining types | min(2, N) |
|
||||
|
||||
- PRE_SCHOOLER's count is editable; one is a default, not a fixed exception.
|
||||
- Both frontend and backend enforce integer counts greater than zero and no
|
||||
greater than N for a configured show. With one daypart, all fields display one
|
||||
and are disabled in the frontend.
|
||||
- A show without dayparts remains unscheduled; usable counts must be initialized
|
||||
when its initial daypart configuration becomes available.
|
||||
- Subsequent daypart edits preserve the saved counts rather than reapplying
|
||||
defaults. Block saving if a count exceeds the new number of dayparts until
|
||||
the user corrects it. Adding a daypart does not automatically increase counts.
|
||||
|
||||
## Scheduling rules and objective
|
||||
|
||||
- Use Google OR-Tools in the backend.
|
||||
- Include every current dance group belonging to the show's school.
|
||||
- Each group must appear in exactly the number of distinct dayparts configured
|
||||
for its type. A group cannot appear twice within one daypart.
|
||||
- Among assignments satisfying those requirements, minimize the difference
|
||||
between the largest and smallest number of group appearances per daypart.
|
||||
Count every configured daypart, including an empty one.
|
||||
- Assign groups to dayparts only. Do not calculate performance order or timing.
|
||||
- Require at least one school group and one configured daypart. Disable the
|
||||
scheduling action with an explanation when either is missing, and enforce
|
||||
the same requirements in the backend.
|
||||
|
||||
## Scheduling action and result handling
|
||||
|
||||
- Provide an explicit "Schedule groups" action clearly indicating that it
|
||||
replaces the current assignments. A separate preview/accept workflow is
|
||||
outside this specification.
|
||||
- Run scheduling synchronously, with a solver time limit of 30 minutes.
|
||||
For S9, the frontend may remain blocked until the request returns; configure
|
||||
the request path to accommodate the agreed duration.
|
||||
- If a valid result is found, save it as a complete replacement of the existing
|
||||
assignments. This includes a valid result whose optimality has not been proven
|
||||
when the time limit is reached.
|
||||
- Distinguish "optimal balance" from "valid result; optimal balance not proven"
|
||||
in the result presented to the user.
|
||||
- If validation fails, the problem is infeasible, the solver fails, or the limit
|
||||
is reached without a valid result, explain the outcome and preserve existing
|
||||
assignments. Never silently reduce required appearances.
|
||||
- Disable the scheduling action while a run is pending. The backend must reject
|
||||
another concurrent run for the same show.
|
||||
- Before saving, verify that scheduling inputs have not changed during the run.
|
||||
If they changed, reject the stale result, preserve existing assignments and
|
||||
explain that the user must run scheduling again.
|
||||
|
||||
## Changes affecting existing schedules
|
||||
|
||||
- Before accepting a potentially invalidating edit, warn that an existing show
|
||||
schedule may become invalid, name the affected shows and allow cancellation.
|
||||
- Cover adding/deleting school groups, changing a group's type, changing show
|
||||
dayparts and changing appearance counts when affected shows have assignments.
|
||||
Name-only edits do not require this warning.
|
||||
- After accepting the edit, do not automatically reschedule. Identify schedules
|
||||
whose assignments no longer meet the appearance requirements and offer the
|
||||
explicit scheduling action again.
|
||||
- Newly added groups use their type's saved count on the next scheduling run.
|
||||
|
||||
## JSON import/export
|
||||
|
||||
- Preserve dated dayparts, group assignments and every per-type appearance
|
||||
setting through JSON export/import.
|
||||
- Update the format version and validation for the new structure, including
|
||||
allowing the same daypart type on different dates.
|
||||
- No legacy export compatibility or migration is required: the application is
|
||||
still greenfield and no exports have been made.
|
||||
|
||||
## Optional repeatability
|
||||
|
||||
Identical inputs producing identical assignments is a nice-to-have for
|
||||
testability, not a mandatory scheduling requirement. Spend at most three
|
||||
minutes investigating how to achieve it. Implement it only if it requires at
|
||||
most ten additional code statements; otherwise omit it. Changed inputs may
|
||||
produce different assignments regardless.
|
||||
|
||||
## Out of scope and follow-up specifications
|
||||
|
||||
- Group exclusions: S10_allow-group-exclusion-for-show.
|
||||
- Season context: S11_add-season-context-go-groups-and-shows.
|
||||
- Asynchronous scheduling feedback: S12_support-async-feedback-for-scheduling.
|
||||
- Scheduling on another PC: S13_create-runner-to-allow-scheduling-on-different-pc.
|
||||
- Availability restrictions, pinned assignments, capacity limits, shared-dancer
|
||||
constraints, duration/audience balancing and performance ordering.
|
||||
|
||||
S10–S13 are intentionally empty placeholders and are to be refined separately.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] Configure up to six dated dayparts, reject duplicate date/type combinations
|
||||
and derive the displayed show date range from them.
|
||||
- [ ] Persist editable per-type counts with the agreed defaults, remove the
|
||||
backend type-level property and validate counts in frontend and backend.
|
||||
- [ ] With one daypart, every count is one and frontend fields are disabled.
|
||||
- [ ] Daypart edits preserve configured counts and require correction of counts
|
||||
that exceed the new number of dayparts.
|
||||
- [ ] OR-Tools assigns every school group to exactly its type's required number
|
||||
of distinct dayparts and minimizes the busiest/quietest appearance gap.
|
||||
- [ ] Scheduling requires groups and dayparts and replaces assignments only after
|
||||
a successful, current result.
|
||||
- [ ] The synchronous request supports a 30-minute solver limit, accepts valid
|
||||
unproven results and communicates whether optimality was proven.
|
||||
- [ ] Failed, infeasible, stale and no-result runs preserve existing assignments
|
||||
and explain why no replacement was saved.
|
||||
- [ ] Duplicate concurrent runs for a show are prevented in frontend and backend.
|
||||
- [ ] Potentially invalidating edits warn beforehand, identify affected shows,
|
||||
permit cancellation and expose invalid schedules afterward without
|
||||
automatically rescheduling.
|
||||
- [ ] New-format JSON round-trips dates, assignments and all type settings;
|
||||
legacy import support is not required.
|
||||
- [ ] Any repeatability work respects both the three-minute investigation limit
|
||||
and the ten-additional-statement implementation limit.
|
||||
|
||||
## Implementation handoff
|
||||
|
||||
This specification records agreed behavior; it does not implement scheduling.
|
||||
The current application uses in-memory storage with JSON import/export for
|
||||
transfer. S9 adds the scheduling model, frontend controls, backend operation and
|
||||
JSON changes within that existing persistence approach.
|
||||
Reference in New Issue
Block a user