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:
361
docs/archive/ACADEMIC_PERIODS_CRUD_BUILD_PLAN.md
Normal file
361
docs/archive/ACADEMIC_PERIODS_CRUD_BUILD_PLAN.md
Normal file
@@ -0,0 +1,361 @@
|
||||
# Academic Periods CRUD Build Plan
|
||||
|
||||
## Goal
|
||||
|
||||
Add full academic period lifecycle management to the settings page and backend, including safe archive and hard-delete behavior, recurrence spillover blockers, and a UI restructuring where `Perioden` becomes the first sub-tab under `Akademischer Kalender`.
|
||||
|
||||
## Frontend Design Rules
|
||||
|
||||
All UI implementation for this build must follow the project-wide frontend design rules:
|
||||
|
||||
→ **[FRONTEND_DESIGN_RULES.md](FRONTEND_DESIGN_RULES.md)**
|
||||
|
||||
Key points relevant to this build:
|
||||
- Syncfusion Material3 components are the default for every UI element
|
||||
- Use `DialogComponent` for all confirmations — never `window.confirm()`
|
||||
- Follow the established card structure, button variants, badge colors, and tab patterns
|
||||
- German strings only in all user-facing text
|
||||
- No Tailwind classes
|
||||
|
||||
## Agreed Rules
|
||||
|
||||
### Permissions
|
||||
|
||||
- Create: admin or higher
|
||||
- Edit: admin or higher
|
||||
- Archive: admin or higher
|
||||
- Restore: admin or higher
|
||||
- Hard delete: admin or higher
|
||||
- Activate: admin or higher
|
||||
- Editors do not activate periods by default because activation changes global system state
|
||||
|
||||
### Lifecycle
|
||||
|
||||
- Active: exactly one period at a time
|
||||
- Inactive: saved period, not currently active
|
||||
- Archived: retired period, hidden from normal operational selection
|
||||
- Deleted: physically removed only when delete preconditions are satisfied
|
||||
|
||||
### Validation
|
||||
|
||||
- `name` is required, trimmed, and unique among non-archived periods
|
||||
- `startDate` must be less than or equal to `endDate`
|
||||
- `periodType` must be one of `schuljahr`, `semester`, `trimester`
|
||||
- Overlaps are disallowed within the same `periodType`
|
||||
- Overlaps across different `periodType` values are allowed
|
||||
- Exactly one period may be active at a time
|
||||
|
||||
### Archive Rules
|
||||
|
||||
- Active periods cannot be archived
|
||||
- A period cannot be archived if it still has operational dependencies
|
||||
- Operational dependencies include recurring master events assigned to that period that still generate current or future occurrences
|
||||
|
||||
### Restore Rules
|
||||
|
||||
- Archived periods can be restored by admin or higher
|
||||
- Restored periods return as inactive by default
|
||||
|
||||
### Hard Delete Rules
|
||||
|
||||
- Only archived and inactive periods can be hard-deleted
|
||||
- Hard delete is blocked if linked events exist
|
||||
- Hard delete is blocked if linked media exist
|
||||
- Hard delete is blocked if recurring master events assigned to the period still have current or future scheduling relevance
|
||||
|
||||
### Recurrence Spillover Rule
|
||||
|
||||
- If a recurring master event belongs to an older period but still creates occurrences in the current or future timeframe, that older period is not eligible for archive or hard delete
|
||||
- Admin must resolve the recurrence by ending, splitting, or reassigning the series before the period can be retired or deleted
|
||||
|
||||
## Build-Oriented Task Plan
|
||||
|
||||
### Phase 1: Lock The Contract
|
||||
|
||||
Files:
|
||||
|
||||
- `server/routes/academic_periods.py`
|
||||
- `models/models.py`
|
||||
- `dashboard/src/settings.tsx`
|
||||
|
||||
Work:
|
||||
|
||||
- Freeze lifecycle rules, validation rules, and blocker rules
|
||||
- Freeze the settings tab order so `Perioden` comes before `Import & Liste`
|
||||
- Confirm response shape for new endpoints
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Stable implementation contract for backend and frontend work
|
||||
|
||||
### Phase 2: Extend The Data Model
|
||||
|
||||
Files:
|
||||
|
||||
- `models/models.py`
|
||||
|
||||
Work:
|
||||
|
||||
- Add archive lifecycle fields to academic periods
|
||||
- Recommended fields: `is_archived`, `archived_at`, `archived_by`
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Academic periods can be retired safely and restored later
|
||||
|
||||
### Phase 3: Add The Database Migration
|
||||
|
||||
Files:
|
||||
|
||||
- `server/alembic.ini`
|
||||
- `server/alembic/`
|
||||
- `server/initialize_database.py`
|
||||
|
||||
Work:
|
||||
|
||||
- Add Alembic migration for archive-related fields and any supporting indexes
|
||||
- Ensure existing periods default to non-archived
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Schema upgrade path for current installations
|
||||
|
||||
### Phase 4: Expand The Backend API
|
||||
|
||||
Files:
|
||||
|
||||
- `server/routes/academic_periods.py`
|
||||
|
||||
Work:
|
||||
|
||||
- Implement full lifecycle endpoints:
|
||||
- `GET /api/academic_periods`
|
||||
- `GET /api/academic_periods/:id`
|
||||
- `POST /api/academic_periods`
|
||||
- `PUT /api/academic_periods/:id`
|
||||
- `POST /api/academic_periods/:id/activate`
|
||||
- `POST /api/academic_periods/:id/archive`
|
||||
- `POST /api/academic_periods/:id/restore`
|
||||
- `GET /api/academic_periods/:id/usage`
|
||||
- `DELETE /api/academic_periods/:id`
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Academic periods become a fully managed backend resource
|
||||
|
||||
### Phase 5: Add Backend Validation And Guardrails
|
||||
|
||||
Files:
|
||||
|
||||
- `server/routes/academic_periods.py`
|
||||
- `models/models.py`
|
||||
|
||||
Work:
|
||||
|
||||
- Enforce required fields, type checks, date checks, overlap checks, and one-active-period behavior
|
||||
- Block archive and delete when dependency rules fail
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Backend owns all business-critical safeguards
|
||||
|
||||
### Phase 6: Implement Recurrence Spillover Detection
|
||||
|
||||
Files:
|
||||
|
||||
- `server/routes/academic_periods.py`
|
||||
- `server/routes/events.py`
|
||||
- `models/models.py`
|
||||
|
||||
Work:
|
||||
|
||||
- Detect recurring master events assigned to a period that still generate present or future occurrences
|
||||
- Treat them as blockers for archive and hard delete
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Old periods cannot be retired while they still affect the active schedule
|
||||
|
||||
### Phase 7: Normalize API Serialization
|
||||
|
||||
Files:
|
||||
|
||||
- `server/routes/academic_periods.py`
|
||||
- `server/serializers.py`
|
||||
|
||||
Work:
|
||||
|
||||
- Return academic period responses in camelCase consistently with the rest of the API
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Frontend receives normalized API payloads without special-case mapping
|
||||
|
||||
### Phase 8: Expand The Frontend API Client
|
||||
|
||||
Files:
|
||||
|
||||
- `dashboard/src/apiAcademicPeriods.ts`
|
||||
|
||||
Work:
|
||||
|
||||
- Add frontend client methods for create, update, activate, archive, restore, usage lookup, and hard delete
|
||||
|
||||
Deliverable:
|
||||
|
||||
- The settings page can manage academic periods through one dedicated API module
|
||||
|
||||
### Phase 9: Reorder The Akademischer Kalender Sub-Tabs
|
||||
|
||||
Files:
|
||||
|
||||
- `dashboard/src/settings.tsx`
|
||||
|
||||
Work:
|
||||
|
||||
- Move `Perioden` to the first sub-tab
|
||||
- Move `Import & Liste` to the second sub-tab
|
||||
- Preserve controlled tab state behavior
|
||||
|
||||
Deliverable:
|
||||
|
||||
- The settings flow reflects setup before import work
|
||||
|
||||
### Phase 10: Replace The Current Period Selector With A Management UI
|
||||
|
||||
Files:
|
||||
|
||||
- `dashboard/src/settings.tsx`
|
||||
|
||||
Work:
|
||||
|
||||
- Replace the selector-only period card with a proper management surface
|
||||
- Show period metadata, active state, archived state, and available actions
|
||||
|
||||
Deliverable:
|
||||
|
||||
- The periods tab becomes a real administration UI
|
||||
|
||||
### Phase 11: Add Create And Edit Flows
|
||||
|
||||
Files:
|
||||
|
||||
- `dashboard/src/settings.tsx`
|
||||
|
||||
Work:
|
||||
|
||||
- Add create and edit dialogs or form panels
|
||||
- Validate input before save and surface backend errors clearly
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Admins can maintain periods directly in settings
|
||||
|
||||
### Phase 12: Add Archive, Restore, And Hard Delete UX
|
||||
|
||||
Files:
|
||||
|
||||
- `dashboard/src/settings.tsx`
|
||||
|
||||
Work:
|
||||
|
||||
- Fetch usage or preflight data before destructive actions
|
||||
- Show exact blockers for linked events, linked media, and recurrence spillover
|
||||
- Use explicit confirmation dialogs for archive and hard delete
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Destructive actions are safe and understandable
|
||||
|
||||
### Phase 13: Add Archived Visibility Controls
|
||||
|
||||
Files:
|
||||
|
||||
- `dashboard/src/settings.tsx`
|
||||
|
||||
Work:
|
||||
|
||||
- Hide archived periods by default or group them behind a toggle
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Normal operational periods stay easy to manage while retired periods remain accessible
|
||||
|
||||
### Phase 14: Add Backend Tests
|
||||
|
||||
Files:
|
||||
|
||||
- Backend academic period test targets to be identified during implementation
|
||||
|
||||
Work:
|
||||
|
||||
- Cover create, edit, activate, archive, restore, hard delete, overlap rejection, dependency blockers, and recurrence spillover blockers
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Lifecycle rules are regression-safe
|
||||
|
||||
### Phase 15: Add Frontend Verification
|
||||
|
||||
Files:
|
||||
|
||||
- `dashboard/src/settings.tsx`
|
||||
- Frontend test targets to be identified during implementation
|
||||
|
||||
Work:
|
||||
|
||||
- Verify sub-tab order, CRUD refresh behavior, blocked action messaging, and activation behavior
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Settings UX remains stable after the management upgrade
|
||||
|
||||
### Phase 16: Update Documentation
|
||||
|
||||
Files:
|
||||
|
||||
- `.github/copilot-instructions.md`
|
||||
- `README.md`
|
||||
- `TECH-CHANGELOG.md`
|
||||
|
||||
Work:
|
||||
|
||||
- Document academic period lifecycle behavior, blocker rules, and updated settings tab order as appropriate
|
||||
|
||||
Deliverable:
|
||||
|
||||
- Repo guidance stays aligned with implemented behavior
|
||||
|
||||
## Suggested Build Sequence
|
||||
|
||||
1. Freeze rules and response shape
|
||||
2. Change the model
|
||||
3. Add the migration
|
||||
4. Build backend endpoints
|
||||
5. Add blocker logic and recurrence checks
|
||||
6. Expand the frontend API client
|
||||
7. Reorder sub-tabs
|
||||
8. Build period management UI
|
||||
9. Add destructive-action preflight UX
|
||||
10. Add tests
|
||||
11. Update documentation
|
||||
|
||||
## Recommended Delivery Split
|
||||
|
||||
1. Backend foundation
|
||||
- Model
|
||||
- Migration
|
||||
- Routes
|
||||
- Validation
|
||||
- Blocker logic
|
||||
|
||||
2. Frontend management
|
||||
- API client
|
||||
- Tab reorder
|
||||
- Management UI
|
||||
- Dialogs
|
||||
- Usage messaging
|
||||
|
||||
3. Verification and docs
|
||||
- Tests
|
||||
- Documentation
|
||||
Reference in New Issue
Block a user