BE-CAL-API-004: Implement Calendar cancel API for real and virtual slots

- 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
This commit is contained in:
zhi
2026-03-31 12:47:38 +00:00
parent f7f9ba3aa7
commit b00c928148
2 changed files with 122 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ BE-CAL-004: MinimumWorkload read/write schemas.
BE-CAL-API-001: TimeSlot create / response schemas.
BE-CAL-API-002: Calendar day-view query schemas.
BE-CAL-API-003: TimeSlot edit schemas.
BE-CAL-API-004: TimeSlot cancel schemas.
"""
from __future__ import annotations
@@ -240,3 +241,13 @@ class CalendarDayResponse(BaseModel):
default_factory=list,
description="All slots for the day, sorted by scheduled_at ascending",
)
# ---------------------------------------------------------------------------
# TimeSlot cancel (BE-CAL-API-004)
# ---------------------------------------------------------------------------
class TimeSlotCancelResponse(BaseModel):
"""Response after cancelling a slot — includes the cancelled slot."""
slot: TimeSlotResponse
message: str = Field("Slot cancelled successfully", description="Human-readable result")