feat: period-scoped holiday management, archive lifecycle, and docs/release sync
- add period-scoped holiday architecture end-to-end - model: scope `SchoolHoliday` to `academic_period_id` - migrations: add holiday-period scoping, academic-period archive lifecycle, and merge migration head - API: extend holidays with manual CRUD, period validation, duplicate prevention, and overlap merge/conflict handling - recurrence: regenerate holiday exceptions using period-scoped holiday sets - improve frontend settings and holiday workflows - bind holiday import/list/manual CRUD to selected academic period - show detailed import outcomes (inserted/updated/merged/skipped/conflicts) - fix file-picker UX (visible selected filename) - align settings controls/dialogs with defined frontend design rules - scope appointments/dashboard holiday loading to active period - add shared date formatting utility - strengthen academic period lifecycle handling - add archive/restore/delete flow and backend validations/blocker checks - extend API client support for lifecycle operations - release/docs updates and cleanup - bump user-facing version to `2026.1.0-alpha.15` with new changelog entry - add tech changelog entry for alpha.15 backend changes - refactor README to concise index and archive historical implementation docs - fix Copilot instruction link diagnostics via local `.github` design-rules reference
This commit is contained in:
@@ -487,7 +487,16 @@ def create_event():
|
||||
if not (ev.skip_holidays and ev.recurrence_rule):
|
||||
return
|
||||
# Get holidays
|
||||
holidays = session.query(SchoolHoliday).all()
|
||||
holidays_query = session.query(SchoolHoliday)
|
||||
if ev.academic_period_id is not None:
|
||||
holidays_query = holidays_query.filter(
|
||||
SchoolHoliday.academic_period_id == ev.academic_period_id
|
||||
)
|
||||
else:
|
||||
holidays_query = holidays_query.filter(
|
||||
SchoolHoliday.academic_period_id.is_(None)
|
||||
)
|
||||
holidays = holidays_query.all()
|
||||
dtstart = ev.start.astimezone(UTC)
|
||||
r = rrulestr(ev.recurrence_rule, dtstart=dtstart)
|
||||
window_start = dtstart
|
||||
@@ -588,7 +597,16 @@ def update_event(event_id):
|
||||
if not (ev.skip_holidays and ev.recurrence_rule):
|
||||
return
|
||||
# Get holidays
|
||||
holidays = session.query(SchoolHoliday).all()
|
||||
holidays_query = session.query(SchoolHoliday)
|
||||
if ev.academic_period_id is not None:
|
||||
holidays_query = holidays_query.filter(
|
||||
SchoolHoliday.academic_period_id == ev.academic_period_id
|
||||
)
|
||||
else:
|
||||
holidays_query = holidays_query.filter(
|
||||
SchoolHoliday.academic_period_id.is_(None)
|
||||
)
|
||||
holidays = holidays_query.all()
|
||||
dtstart = ev.start.astimezone(UTC)
|
||||
r = rrulestr(ev.recurrence_rule, dtstart=dtstart)
|
||||
window_start = dtstart
|
||||
|
||||
Reference in New Issue
Block a user