P1. The pane is a projection, not a feed row: it renders beside the FeedList on windows of 1200 and up, reading the same queries the week pane already holds, so opening 홈 on desktop adds no request the phone does not make. It follows the browsed week (its title reads 이번 주 only for the current week).
| Cell | Definition | Supplied by | New RPC? |
|---|---|---|---|
| 참석 | Count of `rsvpdSessions` in the week range | `useHomePeriodRecap(userId, weekRange)` (`useRsvpdUpcomingSessions`) | No |
| 입금 대기 | Sessions where `sessionPaymentGateState(fee, status, submittedAt)` is `reserved` | `useMySessionPayments(userId, weekSessionIds)` plus the fee on `sessionCardModels` | No (bulk reader exists) |
| 치른 경기 | Match-history entries in the week (`derivePeriodRecap` total) | `useMatchHistory` already read by the week pane | No |
| 다음 일정 | First of `rsvpdSessions`, host-first sorted, from today on | `useHomePeriodRecap` + `sessionCardModels` (capacity ring from the model) | No |
| 예정 (cut) | Would count sessions the viewer could still join, not RSVP’d | Needs a viewer-scoped open-sessions count across clubs | Yes: a new RPC |
| 예비 (cut) | Waitlisted RSVPs; `useRsvpdUpcomingSessions` returns confirmed only | Would add a second RSVP-status read | Yes: new read |
P2. friends_attending_count(session_ids uuid[]) returns (session_id uuid, friend_count int): SECURITY DEFINER with search_path = '', REVOKE FROM PUBLIC, GRANT to authenticated. It counts confirmed rsvps whose user is an accepted friend of auth.uid(), only for open, visible pickup sessions, at most 50 ids per call, rows with a zero count omitted. It returns no identities: the viewer learns that N of their friends are going, never which. The client gap-fills who.friendsGoing with the larger of the roster count and the RPC count through one bulk sibling hook (Protocol A), so the strip rule in session-strip.ts and the card stay unchanged. Needs a pgTAP file: a stranger gets 0, a friend of an attendee gets the count, a blocked friend is excluded.
P3. At the phone column (358 usable width on a 390 screen) a 4:3 photo is 268 tall and a 16:9 band is 201: the band saves 67px per photo post, about one extra text-only post per screen. 4:3 is the phone camera’s own ratio, so 16:9 crops a third of a typical photo off the top and bottom; the tile arrangement for two and three photos is unchanged either way. Band and Facebook show the full-width photo; 당근 keeps a small thumbnail beside the text, which is the density the owner already rejected as too small.
Proposal (2026-10-06): three product questions, each drawn as the recommended final state. P1 the 홈 desktop summary pane from existing loads; P2 a count-only 친구 참석 RPC for the pickup finder; P3 the single-photo frame in the club feed.
packages/features/home/src/home-feed-screen.tsx · packages/app/src/presentation/components/sessions/session-card-v2.tsx · packages/features/clubs/src/shared/post-row.tsx
grounded in 13 source file(s)
packages/features/home/src/home-feed-screen.tsxpackages/features/home/src/page/home-body.tsxpackages/features/home/src/lead/use-home-lead.tspackages/features/home/src/news/news-feed-list.tsxpackages/features/home/src/lead/lead-block.tsxpackages/app/src/domain/session-info-model.tspackages/app/src/domain/session-info-model/payment-gate.tspackages/app/src/domain/session-strip.tspackages/app/src/presentation/components/sessions/session-card-v2.tsxpackages/app/src/presentation/hooks/use-session-card-models.tssupabase/migrations/00080_db_optimization.sqlpackages/features/clubs/src/shared/post-row.tsxpackages/features/clubs/src/shared/club-photo-seam.tsx