P-01: Clamp delta poll since param to max 24h in the past (projects +
calendars) to prevent expensive full-table scans from malicious timestamps.
P-02: Validate individual user_id elements in ProjectMemberInvite and
TaskAssignmentCreate with Annotated[int, Field(ge=1, le=2147483647)].
P-04: Only enable delta polling for shared projects (member_count > 0).
Solo projects skip the 5s poll entirely.
P-05: Remove fragile 200ms onBlur timeout in ProjectShareSheet search.
The onMouseDown preventDefault on dropdown items already prevents blur
from firing before click registers.
P-06/S-04: Replace manual dict construction in model_validators with
__table__.columns iteration so new fields are auto-included.
S-01: Replace bare except in ProjectResponse.compute_member_count with
logger.debug to surface errors in development.
S-03: Consolidate cascade_projects_on_disconnect from 2 project ID
queries into 1 using IN clause with both user IDs.
S-05: Send version in toggleTaskMutation, updateTaskStatusMutation,
and toggleSubtaskMutation for full optimistic locking coverage. Handle
409 with refresh toast.
S-07: Replace window.location.href with React Router navigateRef in
task_assigned toast for client-side navigation.
S-08: Already fixed in previous commit (subtask comment selectinload).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add member_count to ProjectResponse via model_validator (computed from
eagerly loaded members relationship). Shows on ProjectCard for both
owners ("2 members") and shared users ("Shared with you").
- Fix share button badge positioning (add relative class).
- Add dedicated showTaskAssignedToast with blue ClipboardList icon,
"View Project" action button, and 15s duration.
- Wire task_assigned into both initial-load and new-notification toast
dispatch flows in NotificationToaster.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Enables multi-user project collaboration mirroring the shared calendar
pattern. Includes ProjectMember model with permission levels, task
assignment with auto-membership, optimistic locking, field allowlist
for assignees, disconnect cascade, delta polling for projects and
calendars, and full frontend integration with share sheet, assignment
picker, permission gating, and notification handling.
Migrations: 057 (indexes + version + comment user_id), 058
(project_members), 059 (project_task_assignments)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 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>
- Extract duplicate statusColors/statusLabels to projects/constants.ts
- Add staleTime + select to sidebar tracked projects query to reduce
refetches and narrow data to only id/name
- Gate TrackedProjectsWidget query on settings being loaded
- Remove unnecessary from_attributes on TrackedTaskResponse schema
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds is_tracked boolean to projects, expandable tracked projects
in sidebar navigation, pin toggle on project cards/detail, and a
dashboard widget showing upcoming tasks from tracked projects.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add blocked/review/on_hold to ProjectStatus (backend + frontend)
- ProjectForm: add new status options to dropdown
- ProjectDetail: add status colors/labels for new statuses
- KanbanBoard: reorder columns (review before completed)
- KanbanBoard: decouple subtask view from selectedTaskId via
kanbanParentTaskId — closing task panel stays in subtask view,
"Back to all tasks" button now works
- TaskDetailPanel: show status badge on subtask rows so kanban
drag-and-drop status changes are 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>