6 Commits

Author SHA1 Message Date
61e48c3f14 Add project notification types to CHECK constraint (migration 060)
The notifications table CHECK constraint did not include project_invite,
project_invite_accepted, project_invite_rejected, or task_assigned.
This caused 500 errors on invite_members and assign_users_to_task
because create_notification violated ck_notifications_type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 03:54:54 +08:00
05f5b49e26 Fix 500 on POST /api/projects/:id/members — add project_invite types to notification CHECK constraint
The invite_members handler called create_notification with type="project_invite", which
is not in the ck_notifications_type CHECK constraint. The db.flush() inside the handler
flushed both the ProjectMember and Notification INSERTs atomically, causing a
CheckViolationError → 500. Added "project_invite", "project_invite_accepted",
"project_invite_rejected" to the model tuple and migration 060 drops/recreates the
constraint to include them.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 03:53:42 +08:00
8652c9f2ce Implement event invitation feature (invite, RSVP, per-occurrence override, leave)
Full-stack implementation of event invitations allowing users to invite connected
contacts to calendar events. Invitees can respond Going/Tentative/Declined, with
per-occurrence overrides for recurring series. Invited events appear on the invitee's
calendar with a Users icon indicator. LeaveEventDialog replaces delete for invited events.

Backend: Migration 054 (2 tables + notification types), EventInvitation model with
lazy="raise", service layer, dual-router (events + event-invitations), cascade on
disconnect, events/dashboard queries extended with OR for invited events.

Frontend: Types, useEventInvitations hook, InviteeSection (view list + RSVP buttons +
invite search), LeaveEventDialog, event invite toast with 3 response buttons, calendar
eventContent render with Users icon for invited events.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 02:47:27 +08:00
e4b45763b4 Phase 1: Schema and models for shared calendars
Migrations 047-051:
- 047: Add is_shared to calendars
- 048: Create calendar_members table (permissions, status, constraints)
- 049: Create event_locks table (5min TTL, permanent owner locks)
- 050: Expand notification CHECK (calendar_invite types)
- 051: Add updated_by to calendar_events + updated_at index

New models: CalendarMember, EventLock
Updated models: Calendar (is_shared, members), CalendarEvent (updated_by),
  Notification (3 new types)
New schemas: shared_calendar.py (invite, respond, member, lock, sync)
Updated schemas: calendar.py (is_shared, sharing response fields)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 03:22:44 +08:00
820ff46efa Fix QA W-01/W-05/W-06/W-08: cancel requests, detach umbral, notifications
W-08: Add CHECK constraint on notifications.type (migration 044) with
defensive pre-check and matching __table_args__ on model.

W-05: Auto-detach umbral contact before Person delete — nulls out
connection's person_id so the connection survives deletion.

W-01: Add PUT /requests/{id}/cancel endpoint with atomic UPDATE,
silent notification cleanup, and audit logging. Frontend: direction-aware
ConnectionRequestCard, cancel mutation, pending requests section on
PeoplePage with incoming/outgoing subsections.

W-06: Convert useNotifications to context provider pattern — single
subscription shared via NotificationProvider in AppLayout. Adds
refreshNotifications convenience function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 07:17:31 +08:00
3d22568b9c Add user connections, notification centre, and people integration
Implements the full User Connections & Notification Centre feature:

Phase 1 - Database: migrations 039-043 adding umbral_name to users,
profile/social fields to settings, notifications table, connection
request/user_connection tables, and linked_user_id to people.

Phase 2 - Notifications: backend CRUD router + service + 90-day purge,
frontend NotificationsPage with All/Unread filter, bell icon in sidebar
with unread badge polling every 60s.

Phase 3 - Settings: profile fields (phone, mobile, address, company,
job_title), social card with accept_connections toggle and per-field
sharing defaults, umbral name display with CopyableField.

Phase 4 - Connections: timing-safe user search, send/accept/reject flow
with atomic status updates, bidirectional UserConnection + Person records,
in-app + ntfy notifications, per-receiver pending cap, nginx rate limiting.

Phase 5 - People integration: batch-loaded shared profiles (N+1 prevention),
Ghost icon for umbral contacts, Umbral filter pill, split Add Person button,
shared field indicators (synced labels + Lock icons), disabled form inputs
for synced fields on umbral contacts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 02:10:16 +08:00