feat: persist weekly availability defaults (Closes #1256)
CI / lint (pull_request) Successful in 3m37s
CI / build-release (pull_request) Successful in 8s
CI / browser-journey (pull_request) Successful in 5m47s
CI / release-candidate (pull_request) Has been skipped

This commit is contained in:
timmy committed 2026-08-22 08:10:24 +00:00
1 parent ea3204c78c
commit 1ae8533702
8 files changed
+255 -17

No files matched your search

+4
View File
@@ -738,6 +738,9 @@ class WeekPlanUpdate(BaseModel):
base_revision: int = Field(ge=0)
days: list[WeekPlanDay] = Field(max_length=7)
timezone: str = Field(min_length=1, max_length=100)
availability_defaults: list[int] | None = Field(
default=None, min_length=7, max_length=7,
)
class WeekPromotion(BaseModel):
@@ -2828,6 +2831,7 @@ async def replace_week_plan(payload: WeekPlanUpdate):
base_revision=payload.base_revision,
days=[day.model_dump() for day in payload.days],
timezone=payload.timezone,
availability_defaults=payload.availability_defaults,
)
except WeekPlanConflict as error:
raise HTTPException(
+30 -5
View File
@@ -519,7 +519,10 @@ class TodayStore:
)
return {"revision": 1, **payload}
def _normalize_week(self, *, days: list[dict], timezone: str) -> dict:
def _normalize_week(
self, *, days: list[dict], timezone: str,
availability_defaults: list[int] | None = None,
) -> dict:
if not isinstance(days, list) or len(days) > 7:
raise ValueError("Week Ahead is limited to seven dates")
if not isinstance(timezone, str) or not timezone.strip() or len(timezone) > 100:
@@ -555,13 +558,32 @@ class TodayStore:
plan.pop("timezone")
normalized.append(plan)
normalized.sort(key=lambda item: item["plan_date"])
return {"timezone": timezone, "days": normalized}
result = {"timezone": timezone, "days": normalized}
if availability_defaults is not None:
if (
not isinstance(availability_defaults, list)
or len(availability_defaults) != 7
or any(
not isinstance(value, int) or isinstance(value, bool)
or value < 0 or value > 1440
for value in availability_defaults
)
):
raise ValueError("availability defaults must contain seven weekday capacities")
result["availability_defaults"] = list(availability_defaults)
return result
def replace_week(self, login: str, *, base_revision: int, days: list[dict], timezone: str) -> dict:
def replace_week(
self, login: str, *, base_revision: int, days: list[dict], timezone: str,
availability_defaults: list[int] | None = None,
) -> dict:
login = self._normalize_login(login)
if not isinstance(base_revision, int) or isinstance(base_revision, bool) or base_revision < 0:
raise ValueError("base_revision must be a non-negative integer")
normalized = self._normalize_week(days=days, timezone=timezone)
normalized = self._normalize_week(
days=days, timezone=timezone,
availability_defaults=availability_defaults,
)
with self._connect() as connection:
connection.execute("BEGIN IMMEDIATE")
row = connection.execute(
@@ -649,7 +671,10 @@ class TodayStore:
and not allow_over_capacity
):
raise ValueError("explicit overload confirmation is required")
normalized_week = self._normalize_week(days=days, timezone=week["timezone"])
normalized_week = self._normalize_week(
days=days, timezone=week["timezone"],
availability_defaults=week.get("availability_defaults"),
)
today_ids = [item_id for item_id in today["ids"] if item_id != identity]
today_estimates = {