Problem Statement
When I find a movie or show I think a friend would love, I have no way to tell them inside Seen. I have to leave the app and message them elsewhere, and the recommendation lives outside the product — my friend can't act on it in one tap.
Solution
From a media detail page I can recommend the title to people I follow, optionally with a short message. They receive a push notification and find the recommendation in a dedicated "Received" inbox, where they can read who sent it (and their note) and jump straight to the title.
User Stories
- As a viewer on a media detail page, I want a recommend button in the header, so that I can send the title to friends without cluttering the main action bar.
- As a sender, I want to pick from the people I follow, so that I can recommend to anyone I follow (no mutual-follow requirement).
- As a sender, I want to select multiple friends at once with a running count, so that I can recommend to several people in one action.
- As a sender, I want to attach an optional short message, so that I can say why I'm recommending it.
- As a sender, I want clear confirmation that the recommendation was sent, so that I trust it went through.
- As a recipient, I want a push notification when someone recommends a title to me, so that I find out promptly.
- As a recipient, I want tapping that notification to deep-link me to my "Received" inbox, so that I land in the right place.
- As a recipient, I want a dedicated "Received" inbox listing recommendations sent to me, so that I never lose one even if I miss the notification.
- As a recipient, I want each inbox entry to show who sent it, the title, and their message, so that I have full context.
- As a recipient, I want to tap an inbox entry and open the title's media detail page, so that I can decide whether to watch it.
- As a recipient, I want a bell/badge with an unread count in my profile header, so that I notice new recommendations.
- As a recipient, I want recommendations to be marked read once I view them, so that the unread badge stays accurate.
- As a user, I want recommendations to work for both movies and TV shows, so that the feature is consistent.
Implementation Decisions
- New
recommendations domain across DB, API, and mobile, modeled on the existing watch-sessions feature (its friend picker, invite mutation, push dispatch, and deep-link handling are the closest prior art and should be reused).
- Schema: new
media_recommendations table (its own schema folder following the per-domain convention) with: id, senderId, recipientId (→ user), tmdbId, mediaType, a display snapshot (title, poster path), optional message, readAt (nullable), createdAt. Generate + apply via the root db scripts.
- API contract (new module):
POST /recommendations — body { tmdbId, mediaType, recipientIds[], message? }; inserts one row per recipient and dispatches a push to each.
GET /recommendations/received — the recipient's inbox list.
POST /recommendations/:id/read — mark one as read.
GET /recommendations/recommendable-friends — candidate recipients = people the current user follows (reuse the existing get-following query; one-directional, not mutual).
- Push: reuse the existing Expo push library and the watch-sessions notify pattern; introduce a new push
type (e.g. recommendation.received). Extend the mobile deep-link decoder to route that type to the inbox route.
- Mobile:
- New
recommendations service (eden handlers: send, list-received, mark-read, list-recommendable-friends) and React Query hooks (send + friend list, received list) with a dedicated query-key factory.
- Send sheet (form-sheet presentation) reusing the watch-invite multi-select friend list UI, plus an optional message field. Opened from the media-detail header button.
- Inbox screen ("Received") modeled on the existing watch-invitations screen; opens its items to the corresponding media detail; marks entries read on view.
- Unread bell + badge in the profile header.
- New i18n keys (FR + EN) for button labels, inbox title, and push copy.
- Follow
naming (this is a "media recommendation", distinct from TMDB recommendations), expo-ui-swiftui, and haptics skills.
Testing Decisions
- The repo has no automated test framework wired up (per
AGENTS.md).
- Seams:
- Highest integration seams: the four new
recommendations API routes (HTTP contracts) — especially POST /recommendations (fan-out to N recipients + push) and GET /recommendations/received.
- Unit-level seam: the recommendable-friends query (returns people the user follows) and the inbox serializer (row → inbox DTO).
- Good tests assert external behavior: sending to N recipients creates N received rows and N push messages; the inbox returns sender + title + message; marking read flips unread state — not the push transport internals.
- Prior art: the watch-sessions module (invite-to-session mutation, list-invitable-friends query, notify dispatch) is the direct template.
- Until a harness exists, verify manually with two accounts: send a recommendation to several followed users with a message → 200 and rows created; on a recipient device confirm the push, tap → "Received" inbox, see sender/title/message, badge decrements on read, tapping the title opens its media detail.
Out of Scope
- The OS share sheet path (sharing via Messages/WhatsApp with a deep link) — explicitly deprioritized in favor of in-app recommendations.
- Recommending to users you do not follow / open user search as recipients.
- Threaded replies or chat on a recommendation.
- Recommendations surfaced inside the existing social activity feed (the dedicated inbox is the chosen surface).
- Recommending individual episodes (movie/TV only for now).
Further Notes
The heaviest feature (new DB table + API module + two screens + push wiring). Depends on the existing social graph and push infrastructure, both of which already exist. Part of the "richer media detail page" epic. Consider a whats-new announcement when shipped.
Problem Statement
When I find a movie or show I think a friend would love, I have no way to tell them inside Seen. I have to leave the app and message them elsewhere, and the recommendation lives outside the product — my friend can't act on it in one tap.
Solution
From a media detail page I can recommend the title to people I follow, optionally with a short message. They receive a push notification and find the recommendation in a dedicated "Received" inbox, where they can read who sent it (and their note) and jump straight to the title.
User Stories
Implementation Decisions
recommendationsdomain across DB, API, and mobile, modeled on the existing watch-sessions feature (its friend picker, invite mutation, push dispatch, and deep-link handling are the closest prior art and should be reused).media_recommendationstable (its own schema folder following the per-domain convention) with: id, senderId, recipientId (→ user), tmdbId, mediaType, a display snapshot (title, poster path), optional message, readAt (nullable), createdAt. Generate + apply via the root db scripts.POST /recommendations— body{ tmdbId, mediaType, recipientIds[], message? }; inserts one row per recipient and dispatches a push to each.GET /recommendations/received— the recipient's inbox list.POST /recommendations/:id/read— mark one as read.GET /recommendations/recommendable-friends— candidate recipients = people the current user follows (reuse the existing get-following query; one-directional, not mutual).type(e.g.recommendation.received). Extend the mobile deep-link decoder to route that type to the inbox route.recommendationsservice (eden handlers: send, list-received, mark-read, list-recommendable-friends) and React Query hooks (send + friend list, received list) with a dedicated query-key factory.naming(this is a "media recommendation", distinct from TMDB recommendations),expo-ui-swiftui, andhapticsskills.Testing Decisions
AGENTS.md).recommendationsAPI routes (HTTP contracts) — especiallyPOST /recommendations(fan-out to N recipients + push) andGET /recommendations/received.Out of Scope
Further Notes
The heaviest feature (new DB table + API module + two screens + push wiring). Depends on the existing social graph and push infrastructure, both of which already exist. Part of the "richer media detail page" epic. Consider a
whats-newannouncement when shipped.