- New overlap.py service with check_overlap(), check_overlap_for_create(),
and check_overlap_for_edit() functions
- Detects same-day time conflicts for a user's calendar
- Checks both real (materialized) TimeSlots and virtual (plan-generated) slots
- Excludes skipped/aborted slots from conflict checks
- Edit scenario excludes the slot being edited from conflict candidates
- Returns structured SlotConflict objects with human-readable messages
- 24 passing tests covering no-conflict, conflict detection, inactive
exclusion, edit self-exclusion, virtual slot overlap, and message content
- New service: app/services/plan_slot.py
- Virtual slot ID: plan-{plan_id}-{YYYY-MM-DD} format with parse/make helpers
- Plan-date matching: on_month/on_week/on_day hierarchy with week_of_month calc
- Materialization: convert virtual slot to real TimeSlot row from plan template
- Detach: clear plan_id after edit/cancel to break plan association
- Bulk materialization: materialize_all_for_date for daily pre-compute
- New tests: tests/test_plan_slot.py (23 tests, all passing)
- Patched conftest.py to monkey-patch app.core.config engine/SessionLocal
with SQLite in-memory DB BEFORE importing the FastAPI app, preventing
startup event from trying to connect to production MySQL
- All 29 tests pass: Essential CRUD (11), Proposal Accept (8),
Story restricted (6), Legacy compat (4)
New test infrastructure:
- tests/conftest.py: SQLite in-memory fixtures, TestClient wired to test DB,
factory fixtures for User/Project/Milestone/Task/Roles/Permissions
- tests/test_milestone_actions.py: 17 tests covering:
- freeze success/no-release-task/multiple-release-tasks/wrong-status
- start success+started_at/deps-not-met/wrong-status
- close from open/freeze/undergoing, rejected from completed/closed
- auto-complete on release task finish, no auto-complete for non-release/wrong-status
- preflight allowed/not-allowed