- Add max_length constraints to all string fields in request schemas,
matching DB column limits (title:255, description:5000, etc.)
- Add min_length=1 to required name/title fields
- Add ConfigDict(extra="forbid") to all request schemas to reject
unknown fields (prevents silent field injection)
- Add Path(ge=1, le=2147483647) to all integer path parameters across
all routers to prevent integer overflow → 500 errors
- Add max_length to TOTP inline schemas (code:6, mfa_token:256, etc.)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove unused imports (UserCheck, Loader2, ShieldOff) and replace
non-existent SmartphoneOff icon with Smartphone in admin components.
Includes backend query fixes, performance indexes migration, and
admin page shared utilities extraction.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Widen priority badge from w-10 to w-14 to fit "medium" text, add "none" case
- Guard against null end_datetime in event update validation
- Exclude current event from this_and_future DELETE to prevent 404
- Use Python-side datetime.now for comment timestamps (avoids UTC offset)
- Hide "Add subtask" button when viewing a subtask (prevents nested nesting)
- Add X close button to TaskDetailPanel header on desktop
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
model_dump() includes None values for optional RecurrenceRule fields.
When serialized to JSON, these become explicit nulls (e.g. "weekday": null).
The recurrence service then does int(None) which raises TypeError.
Fix: strip None values when serializing rule to JSON, and add defensive
None handling in recurrence service for all rule.get() calls.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- C1: Nominatim search already uses run_in_executor (non-blocking)
- C2: Ensure target event is deleted in "this_and_future" scope
- W3: Add Field constraints (ge/le) on RecurrenceRule fields
- W4: Add safety cleanup for body overflow on Sheet unmount
- W5: Block drag-drop/resize on recurring events (must use scope dialog)
- W6: Discard stale LocationPicker responses via request ID
- S8: Add role="dialog" and aria-modal to Sheet component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Weekly recurrence no longer requires manual weekday selection;
auto-derives from event start date
- EventForm now receives and forwards editScope prop to API
(edit_scope in PUT body, scope query param in DELETE)
- CalendarPage passes scope through proper prop instead of _editScope hack
- Backend this_and_future: inherits parent's recurrence_rule when child
has none, properly regenerates children after edit
- Backend: parent-level edits now delete+regenerate all children
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New Calendar model and calendars table with system/default flags
- Alembic migration 006: creates calendars, seeds Personal+Birthdays, migrates existing events
- CalendarEvent model gains calendar_id FK and calendar_name/calendar_color properties
- Updated CalendarEventCreate/Response schemas to include calendar fields
- New /api/calendars CRUD router (blocks system calendar deletion/rename)
- Events router: selectinload on all queries, default-calendar assignment on POST, virtual birthday event generation from People with birthdays when Birthdays calendar is visible
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend:
- Add Literal types for status/priority fields (project_task, todo, project schemas)
- Add AccentColor Literal validation to prevent CSS injection (settings schema)
- Add PIN max-length (72 char bcrypt limit) validation
- Fix event date filtering to use correct range overlap logic
- Add revocation check to auth_status endpoint for consistency
- Config: env-aware SECRET_KEY fail-fast, configurable COOKIE_SECURE
Frontend:
- Add withCredentials to axios for cross-origin cookie support
- Replace .toISOString() with local date formatter in DashboardPage
- Replace `as any` casts with proper indexed type access in forms
- Nginx: add CSP, Referrer-Policy headers; remove deprecated X-XSS-Protection
- Nginx: duplicate security headers in static asset location block
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>