Drift (specs aligned to shipped code): - social-follows: locked-account access rule for /users/:u/followers and /users/:u/following (owner + accepted-follower see; non-followers of private get 404). Adds the follow→notification lifecycle requirement. Fills the placeholder Purpose. - public-profiles: counts degrade to plain text (not anchors) for viewers who can't see the lists. Cross-references social-follows. Fills the placeholder Purpose. - journal-auth slimmed to cookie session + Terms gate. Auth methods moved out (see authentication-methods). Splits: - account-settings (14-line stub) deleted, content split into: - profile-settings (display name, bio, profile_visibility) - account-management (email change with verification, account deletion) - connected-services (Wahoo + future external integrations) - authentication-methods split out of journal-auth: passkeys (register/login/add/delete), magic links, 6-digit codes (login + register), method toggle on register/login forms, dev-console fallback. New specs: - sse-broker: /api/events, in-process broker, useUnreadNotifications hook, Caddy passthrough, multi-process forward-compat contract. Archived: notifications change → openspec/changes/archive/2026-04-26-notifications. Promoted the four delta spec files into top-level specs: - specs/notifications/ (new capability) - specs/activity-feed/ (added: public activity fan-out) - specs/journal-landing/ (added: Notifications navbar entry) - specs/social-follows/ (added: follow→notification lifecycle) Added openspec/CAPABILITIES.md grouped index covering all 40 specs with a Conventions section explaining cross-references, naming, and the catch-up-vs-change rule. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
16 lines
1.1 KiB
Markdown
16 lines
1.1 KiB
Markdown
## ADDED Requirements
|
|
|
|
### Requirement: Public activity creation fans out notifications
|
|
Creating an activity with `visibility = 'public'` SHALL enqueue a fan-out job that inserts an `activity_published` notification for every accepted follower of the activity owner. The fan-out SHALL run asynchronously so the activity-creation request returns immediately.
|
|
|
|
#### Scenario: Public activity fans out
|
|
- **WHEN** a user with N accepted followers creates an activity with `visibility = 'public'`
|
|
- **THEN** a pg-boss job is enqueued, and on completion N notifications exist with `type = 'activity_published'`, `recipient_user_id` ∈ accepted-followers, `actor_user_id` = activity owner, `subject_id` = activity id
|
|
|
|
#### Scenario: Private or unlisted activity does not fan out
|
|
- **WHEN** a user creates an activity with `visibility = 'private'` or `'unlisted'`
|
|
- **THEN** no fan-out job is enqueued and no notifications are created
|
|
|
|
#### Scenario: No accepted followers means no notifications
|
|
- **WHEN** a user with zero accepted followers creates a public activity
|
|
- **THEN** the fan-out job runs and inserts zero rows
|