6 Commits

Author SHA1 Message Date
17f331477f Fix QA review issues: error handlers, validation, accessibility, cleanup
- C1: Add onError handlers to dismiss/snooze mutations in useAlerts
- C2: Clear snoozed_until when dismissing via update endpoint
- W1: Handle future dates in getRelativeTime
- W2+S3: Add Escape key, aria-expanded, role=menu to SnoozeDropdown
- W4: Remove redundant field_validator (Literal suffices)
- W7: Validate recurrence_rule with Literal['daily','weekly','monthly']
- S2: Clean up delete confirmation setTimeout on unmount
- S6: Cap AlertBanner height with scroll for many alerts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 03:52:28 +08:00
daf2a4d5f1 Fix snooze/due using container UTC instead of client local time
Docker container datetime.now() returns UTC, but all stored datetimes
are naive local time from the browser. Both /due and /snooze now
accept client_now from the frontend, ensuring snooze computes from
the user's actual current time, not the container's clock.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 03:12:31 +08:00
5b1b9cc5b7 Fix QA issues: single AlertsProvider, null safety, snooze cleanup
- C1: Replaced duplicate useAlerts() calls with AlertsProvider context
  wrapping AppLayout — single hook instance, no double polling/toasts
- C2: Added null guard on remind_at in Active Reminders card format()
- W2: Clear snoozed_until when dismissing a reminder
- W5: Extracted getRelativeTime to shared lib/date-utils.ts
- S3: Replaced inline SVG with Lucide Bell component in toasts
- S4: Clear snoozed_until when remind_at is updated via PUT

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:56:56 +08:00
250cbd0239 Address remaining QA items: indexes, validation, UX improvements
Backend:
- [W1] Add server_default=func.now() on created_at/updated_at
- [W2] Add index on reset_at column (migration 016)
- [W7] Document weekly reset edge case in code comment

Frontend:
- [W4] Extract shared isTodoOverdue() utility in lib/utils.ts,
  used consistently across TodosPage, TodoItem, TodoList
- [W5] Delete requires double-click confirmation (button turns red
  for 2s, second click confirms) with optimistic removal
- [W6] Stat cards now reflect filtered counts, not global
- [S3] Optimistic delete with rollback on error
- [S4] Add "None" to priority segmented filter
- [S7] Sort todos within groups by due date ascending

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:24:59 +08:00
27c65ce40d Fix Round 2 code review findings: type safety, security, and correctness
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>
2026-02-16 15:18:49 +08:00
1f6519635f Initial commit 2026-02-15 16:13:41 +08:00