Enforce a single birthday calendar per account (server-side)
- POST /local/calendars with is_birthday returns the existing birthday calendar if one exists (idempotent, no second created) - PUT /local/calendars rejects (422) marking a second calendar as is_birthday Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -211,6 +211,21 @@ def create_calendar(
|
|||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
current_user: models.User = Depends(get_current_user),
|
current_user: models.User = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
|
# Only ONE birthday calendar per account — hard server guarantee. If the
|
||||||
|
# user already has one, "create birthday calendar" is idempotent: return the
|
||||||
|
# existing one instead of creating a second.
|
||||||
|
if data.is_birthday:
|
||||||
|
existing = (
|
||||||
|
db.query(models.LocalCalendar)
|
||||||
|
.filter(
|
||||||
|
models.LocalCalendar.user_id == current_user.id,
|
||||||
|
models.LocalCalendar.is_birthday == True,
|
||||||
|
)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
if existing is not None:
|
||||||
|
return _cal_dict(existing)
|
||||||
|
|
||||||
cal = models.LocalCalendar(
|
cal = models.LocalCalendar(
|
||||||
user_id=current_user.id,
|
user_id=current_user.id,
|
||||||
name=data.name,
|
name=data.name,
|
||||||
@@ -251,6 +266,19 @@ def update_calendar(
|
|||||||
if data.reminders_enabled is not None:
|
if data.reminders_enabled is not None:
|
||||||
cal.reminders_enabled = data.reminders_enabled
|
cal.reminders_enabled = data.reminders_enabled
|
||||||
if data.is_birthday is not None:
|
if data.is_birthday is not None:
|
||||||
|
# Never let a second calendar be marked as the birthday calendar.
|
||||||
|
if data.is_birthday and not cal.is_birthday:
|
||||||
|
other = (
|
||||||
|
db.query(models.LocalCalendar)
|
||||||
|
.filter(
|
||||||
|
models.LocalCalendar.user_id == current_user.id,
|
||||||
|
models.LocalCalendar.is_birthday == True,
|
||||||
|
models.LocalCalendar.id != cal.id,
|
||||||
|
)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
if other is not None:
|
||||||
|
raise HTTPException(422, "A birthday calendar already exists")
|
||||||
cal.is_birthday = data.is_birthday
|
cal.is_birthday = data.is_birthday
|
||||||
if data.birthday_notify_days_before is not None:
|
if data.birthday_notify_days_before is not None:
|
||||||
# -1 is the client's sentinel for "clear the reminder" (JSON has no way to
|
# -1 is the client's sentinel for "clear the reminder" (JSON has no way to
|
||||||
|
|||||||
Reference in New Issue
Block a user