Closes the social loop opened by social-feed: a Pending follower has no way to know their request was approved, and a follower has no signal at all that someone they follow just posted. Adds a notifications surface for three v1 event types — follow_request_approved, follow_received, activity_published — plus a /notifications page, navbar unread count, and mark-as-read controls. Capabilities: - New: notifications (table, page, badge, generation hooks) - Modified: social-follows (approve + auto-accept emit) - Modified: activity-feed (public create fans out) - Modified: journal-landing (nav entry alongside follow-requests) Design picks: - Fan-out-on-write for activity_published (1:N) so /notifications is a flat single-table query and "mark read" composes trivially. 1:1 events insert directly. Cost ceiling documented at 10k followers × 50 activities/day = 500k/day, still trivial; revisit only if hot. - Single notifications table with loose subject_id (no per-type FK); renderer dereferences by type. Mastodon-style. - Two distinct nav entries (Follow requests + Notifications). Pending is "act on this", notifications is "this happened" — different semantics, kept separate. - Loader-driven unread count (no real-time channel). Real-time is deferred. - 90-day retention for read rows; unread kept indefinitely. Out of scope: per-type mute preferences, email/push, real-time, notifications about routes/replies/mentions, federated notifications. Each tracked as follow-up. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24 lines
1.2 KiB
Markdown
24 lines
1.2 KiB
Markdown
## ADDED Requirements
|
|
|
|
### Requirement: Follow lifecycle emits notifications
|
|
The follow lifecycle SHALL produce notifications for the recipient of the social event (see `notifications` spec):
|
|
|
|
- Auto-accepted public follow → `follow_received` to the followed user.
|
|
- Approved Pending request → `follow_request_approved` to the follower (now accepted).
|
|
- Reject and unfollow do NOT produce notifications.
|
|
|
|
#### Scenario: Public auto-accept notifies the target
|
|
- **WHEN** a user follows another user whose `profile_visibility = 'public'` (auto-accept path)
|
|
- **THEN** a `follow_received` notification is created for the followed user
|
|
|
|
#### Scenario: Approval notifies the requester
|
|
- **WHEN** a private user approves a Pending follow request
|
|
- **THEN** a `follow_request_approved` notification is created for the follower
|
|
|
|
#### Scenario: Reject does not notify
|
|
- **WHEN** a private user rejects a Pending follow request
|
|
- **THEN** no notification is created (silent rejection — the follower can re-request later if they want)
|
|
|
|
#### Scenario: Unfollow does not notify
|
|
- **WHEN** a follower unfollows or cancels a Pending request
|
|
- **THEN** no notification is created on the followed side
|