Owner review 46 — lane F: best-partner scores and navigation between pages (2026-10-19)
Status: Reference · Date: 2026-10-19
Read-only research for owner review 46, marks M24 ("make sure we can properly show how each point is calculated") and M28 (which pages reach which, for club pages and pickup pages). Code at HEAD ff88ca1e1; the route table is the IA doc's §1.3, re-verified; the boards are wireframes/flat-v2-{hub,list-a,detail}.jsx. The 10-09 IA doc is partly stale: payer and join-request pushes are fixed (signal-routes.ts:25-62, 110-124) and appRouter.back falls back to the tab root (app-router.ts:79-112). [n] is the number of taps from the 클럽 or 경기 tab root. "Board" marks a board reading; everything else is code.
Two score defects, confirmed
Lane F found them by reading; the lead confirmed both in code, and lane D found the second independently.
- 함께 친 기록 (30 points) reads the opponent ledger.
usePartnerCandidatesfeedsuseMyMatchupsinto the score (use-partner-candidates.ts:29-36), which readsplayer_matchups(player-matchup.supabase.ts:20).private.apply_match_ratingswrites that ledger once per team1 × team2 pair (00692:235-239), yet the suggester labels it "함께 N승 M패". Teammates are inplayer_partner_records(00692:250-259), read byusePartnerRecords(use-player-format-records.ts:38), which has no caller. Beating someone raises your chemistry with them. - 출석 (15 points) is always 0.
profiles.global_attendance_rateis a 0–1 fraction (private.refresh_attendance_state, 00640:320-339; the trust rules compare it with 0.90 and multiply by 100 to display it, trust-tier.rules.ts:21, 82; profile-screen.tsx:353 multiplies by 100), butcomputeAttendanceScoredivides it by 100 (partner-matching.rules.ts:134-137). The tests feed 50 and 100 (partner-matching.rules.test.ts:228-253). The real maximum is 85.
1. Navigation now
Club
- A 클럽 row opens 클럽 홈 [1]; a non-member's row opens /preview (retiring, review 41).
- 클럽 홈 has six panes in code (홈, 일정, 채팅, 순위, 멤버, 회비) and five on the board (일정 folded into the Feed, 다음 일정 removed, review 41). Out of it: the 앨범 banner [2] (club-place-header.tsx:82); avatars to the member list (:91); a Feed row to 게시글 or 일정 상세 [2; 4 through the board's 일정 filter]; the FAB to 글쓰기 or 만들기; 관리 [2] (a text action in code, a gear on the board).
- The 멤버 pane holds the only entry to 복식 파트너 추천 [3] (members-pane.tsx:232). A 순위 row opens a stats peek whose chips do nothing (
onPress={null}, member-stats-modal.tsx:312, 332). The 회비 pane has no out-link in code; the board ends 멤버 and 회비 with 관리 Cells (hub 2431, 2504). - 관리 lists 멤버 관리, 출석 현황, 회비 관리, 일정 관리, 테니스장 관리, 클럽 대항전, 성장 분석 and 클럽 설정 [3] (admin-tab.tsx:80-165). The board's sheet (hub 2850-2863) adds 신고 관리 and calls 대항전 "도전 과제". 멤버 관리 opens 가입 심사 [4] (members-list-header.tsx:170); 일정 관리 opens 일정 상세 and 만들기; 테니스장 관리 opens /venues/[id]; 클럽 설정 opens 테니스장 관리 and 대진표.
- Reachable only inside 관리: 출석 현황, 테니스장 관리, 대항전, 성장 분석, 클럽 설정. 관리 plus a pending-work row: 일정 관리, 신고 관리 (admin-snapshot-cells.ts:84). Two entries: 멤버 관리, 회비 관리. Dead ends (no
routes.*call in the screen file; the board's rows are inert): 출석 현황, 대항전, 성장 분석, 앨범, the 회비 rows, the 순위 peek.
Session, venue, person
- 일정 상세: the map band opens /venues/[id] and nothing else (session-hero-section.tsx:92); the club eyebrow is plain text (:88); the roster door opens 참석자; 관리/⋯ opens 참석자 관리, 경기 규칙, 호스트 관리 and 출석 확인 (host-menu-actions.ts:49-122), with no 참가비 row (the board adds one); the 정산 CTA appears only once the session is completed (primary-action.tsx:395).
- Missing pairs: session → club; venue → its sessions (venue-detail-screen.tsx reads none); /venues/[id] ↔ /directory-venues/[id]; club → home court (text only, public-club-profile-screen.tsx:453); profile → 나와의 전적; 회비 ↔ 내 결제 (
useMySessionPaymentshas no caller); 순위 peek → 프로필.
Pickup
- 경기 tab → 번개 찾기 → card → 미리보기 [2] (activity-screen.tsx:353) → apply → replaced by 일정 상세. The preview: host → 프로필 → DM; map → /venues. 번개 만들기 [2] (:535). The 테니스장 pane → a directory venue [2] → 여기서 열기 → /create-session (use-directory-venue-detail.ts:437). The home nearby card → 미리보기. A host: 일정 상세 → 관리 → 호스트 관리 [3].
- "Pickup" is any public-invite session (session.supabase.ts:73-100), so public club sessions fill 번개 찾기, yet the preview passes
clubName={null}(public-pickup-preview-screen.tsx:523): no club link, no host's other 번개, and no open 번개 on a venue page.
2. References (2025–26 unless noted)
- Band, announced 2025-11-04: four tabs per band (홈 gathers notices, 게시글, 일정, 사진첩); the global home merges "my bands" with the new-post feed, the often-used bands more prominent. https://navercorp.com/media/pressReleasesDetail?seq=33511
- Meetup, one group page fetched 2026-10-19: five tabs (About, Events, Members, Photos, Discussions) over a long About page that repeats Organizers and Members. https://www.meetup.com/the-lambertville-new-hope-activities-meetup-group/
- Strava clubs, updated 2026-09-16: a carousel (Activities, Stats, Posts) plus an Overview member list; admin is a top-right settings icon. https://support.strava.com/hc/en-us/articles/221622188-Clubs-on-the-Mobile-App
- Spond, updated 2026-08/09: a cross-group Home bar (Events, Posts, Payments, Polls) and one create button; admin settings behind the three dots on the group image. https://help.spond.com/app/en/articles/765343-home-screen-spond-app and https://help.spond.com/app/en/articles/133292-group-settings-for-group-admins
- Playtomic: club profile tabs Book and Open Matches (search text; the page returned 403). https://playerhelp.playtomic.com/hc/en-gb/articles/19831715222929-How-to-book-a-court-or-a-spot-in-a-match-in-your-favourite-Club
- 당근 모임: only 2023 sources (홈, 게시판, 일정, 앨범, 채팅). https://weeklyuxuichallenge.oopy.io/619500d9-80d3-4ade-a1ed-b4bff79ccab6
- NN/g (2015–2021, nothing newer found): a hub makes users return to it to switch sections (https://www.nngroup.com/articles/mobile-navigation-patterns/); 6–15 children suit a section menu (good within a section, poor between sections), landing pages force a return per branch, nested-doll is not recommended (https://www.nngroup.com/articles/mobile-subnavigation/); local navigation is siblings plus children for browsing or comparing, otherwise related-content links (https://www.nngroup.com/articles/local-navigation/); hidden navigation cuts discoverability by over 20%, so show up to four top links (https://www.nngroup.com/articles/hamburger-menus/).
Read-across: groups use four or five content tabs, hide admin behind one icon and give money a cross-group surface (Spond's Payments). Our 관리 sheet's nine children fit NN/g's section-menu band, but each child is a full push, so a sibling costs a trip back through the hub (back, 관리, row: three taps).
3. Navigation proposal
Rules: five visible pane items, no sixth; weekly work is never sheet-only; monthly work = the sheet + a pane-end Cell + a count tag; rare work = 설정 only; every object chip is a visible text row, not an image tap; pages used in sequence share a switcher.
- Club members: panes 홈, 채팅, 기록 (was 순위), 멤버, 회비; inside a pane: 일정 rows, 앨범, 글쓰기, 베스트 파트너 and 추천 (inside 기록), 계좌 복사; header: 공유, ⋯.
- Officials add: the 만들기 FAB, pane-end Cells, 홈 할 일 (weekly). 관리 > 운영: 멤버 관리, 일정 관리 (with the count of 입금 확인), 회비 관리, 출석 현황, 신고 관리. 관리 > 설정: 테니스장 관리, 클럽 대항전, 성장 분석, 클럽 설정. Deep: 가입 심사, 장소 상세.
- Moves: 테니스장 관리 and 대항전 from 운영 to 설정; 복식 파트너 추천 out of 멤버 (M10); /preview retires; /courts is deleted; the board label 도전 과제 becomes 클럽 대항전.
- Owner decision: review 41 removed 다음 일정. Your own next session stays one tap away on 홈 and 경기; another club session costs 2–4. Reinstate one next-session row above the Feed, or accept.
- Mutual links: 일정 상세 → its club (the eyebrow becomes a row), its 장소 (a Cell, the map too), its host; 장소 상세 → next sessions and open 번개, 번개 만들기, the clubs with it as home court (or cross-link the two venue pages); 클럽 홈 → a 홈 코트 row; 순위 peek and 멤버 row → 프로필 and 나와의 전적 (선수별 전적, filtered); 내 회비 → 참가비 내역; 참석자 관리 (people, fees and applicants as sections, M25) ↔ 참석 확인 (M26) by a two-item switcher; 멤버 관리 ↔ 출석 현황 by "출석 주의 N명".
- Pickup: 경기's four panes stay; card → 미리보기 [2]; the preview and the detail carry 장소, 호스트, the club (for club sessions) and 같은 장소 번개 as Cells; for the host, a pending-applicants Notice → 호스트 관리; 참가비 관리 in the 관리 sheet (board).
- Prevention: generate the edge list from the
routes.*call sites; fail on a route with zero inbound links (/courts today) and on a must-be-mutual manifest of the pairs above.
4. Best partners now
Formula (partner-matching.rules.ts): score = E + C + T + A (0–100) for every roster member but the viewer, sorted descending, top 20 (:178-201; partner-suggester-screen.tsx:78).
- E, 40: round((1 − min(|diff|, 400)/400) × 40); diff = the viewer's doublesElo ?? eloRating ?? 1000 against the candidate's doublesElo ?? eloRating (:91-95, 147; screen :70).
- C, 30: 15 with no record, else round(15 + (30 × wins/played − 15) × min(played/10, 1)) (:105-116).
- T, 15: tier index/3 × 15: sprout 0, active 5, trusted 10, veteran 15 (:122-128).
- A, 15: round(min(rate, 100)/100 × 15), null → 0 (:134-137). No minimum sample anywhere.
Defects: the two above, and a third: draws are non-wins in C, absent from the label, and excluded from 기록's rates. Five "best partner" rules coexist: this score; 기록's top 3 by win rate with no minimum (records-screen.tsx:178; player-stats.ts:187); the 순위 peek, no minimum (member-stats-modal.tsx:150); an unrendered personal best at 5+ (use-player-stats-detail.ts:222); review 41 and the boards, 5+ matches together.
Surfaces. App: the 멤버 pane row "복식 파트너 추천 / 나와 잘 맞는 파트너 찾기" (members-pane.tsx:225-236); /clubs/[id]/partners with the caption "클럽 멤버 중 나와 잘 맞을 만한 파트너를 추천해요" (screen :144-150), rows of face, name, "NTRP · ELO n", one adjective reason, and a figure over "궁합" (:214-223); a tap expands four value/max bars (:227-266). 기록: TopPartnersCard medals, "W승/N경기", % (records-screen.tsx:388). Boards: list-a 3519-3620 keeps the 궁합 caption row (3541), the figure column, the reason line and open Cells "ELO 유사도 36/40" (3547-3551); hub 1291-1308 has the trio "이서연 64% 9승 5패" under "최고의 파트너 | 복식"; detail 7917 (5+ together).
5. Best partners proposal
Fix the inputs first, since a wrong number cannot be explained: C from usePartnerRecords(viewer, { clubId }) summed over doubles and mixed; A × 100 (or normalised in the mapper); draws out of every rate.
- Breakdown: a row tap opens a detail sheet, not an inline expand (four two-line Cells per candidate would bury the ranked list). The sheet: the person row, "83점 / 100점", four Cells (label, points, fact): 실력 차이 36/40 "나 ELO 1,482 · 이서연 1,523 (41점 차)"; 함께 친 기록 23/30 "같은 편 12경기 9승 3패 (75%)"; 신뢰 10/15 "신뢰 멤버"; 출석 14/15 "출석률 93%"; and the sum "36 + 23 + 10 + 14 = 83". A "?" InfoHintButton (terminology-guide.md, First Encounter rule 1) opens a PartnerScoreInfoSheet with the four rules: 40점 at equal rating down to 0 at 400 apart; 같은 편 승률 × 30점, pulled toward 15 below 10 matches; 새싹 0, 활동 5, 신뢰 10, 베테랑 15; 출석률 × 15; 친목 경기와 부전승 제외.
- Replaces the metadata: no caption row and no 궁합; the figure carries its unit ("83점") and a Section head "추천 순서" holds the "?"; line 2 states the strongest factor's fact ("같은 편 12경기 9승 3패"), not an adjective. The same sheet serves 기록's 베스트 파트너 rows (M10) and the 대진 flow.
- Minimum samples: no shared match "함께 친 적이 없어요 · 기본 15점"; 1–9 matches "N경기뿐이라 N0%만 반영"; "최고의 파트너" callouts need 5 (ratified); attendance unknown or under 5 sessions "기록이 아직 없어요 · 기본 8점" (the same neutral idea as C, not 0).
- Precedent: ESPN lists stat × rate and the sum ("5 + 3 + 6 = 14"), updated 2026-08-18, https://support.espn.com/hc/en-us/articles/360003914032-Scoring-Formats ; UTR names its four weights and window (30 matches, 12 months) but no match-count threshold on that page, https://support.universaltennis.com/en/support/solutions/articles/9000151894 ; Playtomic pairs a level with a reliability % (low = bigger swings; search text, page 403), https://playerhelp.playtomic.com/hc/en-gb/articles/43310980754193-How-the-Playtomic-level-system-works . The pattern: fact to points, the total's unit, confidence beside it, one rules page.
Not verified
The tap counts are static readings (no device, no seeded data); the two defects are confirmed by reading, not by running. No route-frequency telemetry was read; the tiers rest on the 총무's weekly loop (IA doc, Flow 9). Not found: Meetup's organizer tools, Band's chat, members and settings, Playtomic's tab bar, 당근's 2025–26 structure; the NN/g sources are 2015–2021.