* HarborForge.Backend 5ea2cdf → 54feb96
fix(cli): import all model modules so SA relationship resolution works
(hf-cli admin list crashed with KeyError: Agent on prod cutover, fixed
by mirroring main.py's startup() bulk-import in cli/__main__.py).
prod is on v0.4.1 with this fix in place.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match the language of the submodule READMEs; content unchanged
(structure, tables, links, ports, security notes preserved).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sync umbrella refs after merging the README refresh (all submodules),
backend security hardening, and frontend Foundry Deck redesign into
their respective mains.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrite top-level README (full 7-submodule map, corrected architecture/
ports/model, security notes). No conflicts: remote commits touched only
submodule pointers, this branch only README.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
List all 7 submodules with stack/role, correct architecture and ports,
replace stale Issues model with tasks/milestones/proposals, add Security
notes (mandatory strong SECRET_KEY) and cross-links to component READMEs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- FE-PR-003: Essential create/edit modal with type selector and partial refresh already implemented in ProposalDetailPage
- FE-PR-004: Accept modal with milestone selector and generated tasks display already implemented
- FE-PR-005: Remove 'story' from TASK_TYPES in CreateTaskPage and CreateTaskModal - all story/* must come from Proposal Accept workflow
- PATCH /calendar/plans/{plan_id}: edit a recurring schedule plan
- Validates period-parameter hierarchy after merge
- Rejects edits to inactive (cancelled) plans
- Detaches future materialized slots so they keep old data
- Past materialized slots remain untouched
- POST /calendar/plans/{plan_id}/cancel: cancel (soft-delete) a plan
- Sets is_active=False
- Detaches future materialized slots (plan_id -> NULL)
- Preserves past materialized slots, returns their IDs
- Added SchedulePlanEdit and SchedulePlanCancelResponse schemas
- Imported guard_plan_edit/cancel_no_past_retroaction from slot_immutability
- Add POST /calendar/slots/{slot_id}/cancel for real slot cancellation
- Add POST /calendar/slots/virtual/{virtual_id}/cancel for virtual slot cancellation
- Virtual cancel materializes the slot first, then marks as Skipped
- Both endpoints enforce past-slot immutability guard
- Both endpoints detach from plan (set plan_id=NULL)
- Status set to SlotStatus.SKIPPED on cancel
- Add TimeSlotCancelResponse schema
- Import guard_cancel_real_slot and guard_cancel_virtual_slot
- Add GET /calendar/day endpoint with optional ?date= query param
- Returns unified CalendarDayResponse merging real slots + virtual plan slots
- New CalendarSlotItem schema supports both real (id) and virtual (virtual_id) slots
- Excludes inactive slots (skipped/aborted) from results
- All slots sorted by scheduled_at ascending