Owner review 52 — the sweep, the streamline, and the road to code
Status: Reference · Date: 2026-10-31
The owner finished the review of every page (86 marks: 78 ok, 8 fix) and asked for one more sweep, then: "examine all the pages and streamline them so that 1) we don't have duplicates, 2) we know how exactly each page is mapped out to one another from a navigational standpoint, and 3) we know how these pages will be translated into actual codes for our app. If there is any other pass or audit we need to perform to really turn these pages into concretely implemented pages, please let me know."
1. The notes, read as patterns
| Note | Pages | Pattern | Decision |
|---|---|---|---|
| "remove anything related to practice entirely ... add a journal/journey section ... subscribers ... summarize their tennis journey through the use of AI" | L1-05, L3-08 | A feature leaves; a new subject enters | Practice is gone from the boards, the app code and the database (00702; the hosted table held 0 rows). The match note and 테니스 여정 take its place (library § 1.23). |
| "view a more detailed version of a person's statistics ... reusable pages that can be redirected from the 전적 page? Or should we recreate?" | L2-06 | Depth behind a public profile | Reuse: 공개 프로필 gains 전적 (door to 기간 기록 read as that person's), 플레이, 최근 경기; one page per subject (review 50). Grounded in Playtomic and UTR (§ 3). |
| "apply consistent spacing" | L3-47 | Row rhythm inside a group | The seams measured equal to 경기 규칙's (head 40, row 48, option row 68, group gap 12); the drift was inside the rows (the disclosure row's weight, the Tag's slot, nested rows). Fixed row by row; see the reply. |
| "stepper + number only input field ... make our input fields as specific and tailored as possible" | L4-01 and every form | One control per kind of answer | § 1.22 rule 1: a count with a fixed unit is the typed Stepper; presets of a unit's values and lone Number fields for counts are gone; money and years stay typed. Swept across every form, sheet and settings page. |
| "where and how do we enter these screens" (L3-08, ok) | L3-08 | An entry question | 테니스 여정 opens from 프로필's closing Cell; a note is written from the match's result (노트 남기기 ›) and read on 여정. |
The four older fix marks (L2-05, L3-02, L3-26, L3-40) were answered and folded in rounds 48 and 49 (their codes are retired into L2-04, L3-01, L3-25, L3-38/39) and wait on the owner's re-mark.
2. The decisions, with the evidence
2.1 Public profile: reuse 기록's pages or recreate?
| Option | Correctness | Coupling | Complexity | Reversibility |
|---|---|---|---|---|
Reuse 기간 기록 (L3-04) with a userId, read-only, filtered by visibility | one truth per record; the viewer's own page and another's are the same projection | the page reads get_public_profile_view's visibility (00212) for a foreign user | one param and one filter | easy |
| Recreate a public 전적 page | a second layout drifts from 기록's | none | a new page, its states and its tests | easy |
| Show everything on 공개 프로필 | the page grows past its family (an object page: hero, modules, a feed) | — | low | — |
Reuse wins (review 50: one page per subject; the grammar check holds both). What a public profile tells, from the two references: Playtomic's profile is the level with its reliability, matches won and lost and the win rate (the section guide); UTR's is a singles rating and a doubles rating with the results behind each, filterable by period (advanced player metrics). So 공개 프로필 shows the Block, 전적 (총 경기 · 승률 · ELO, door 전체 보기 ›), 플레이 (단식 ELO · 복식 ELO; 주 종목 · 선호 시간), 최근 경기 (five results), 나와의 전적 (club-mate or friend), 업적; a stranger sees the Block, 전적 and 업적. The identity, ELO and 신뢰 are always visible; the rest follows profile_visibility (00212, 00691).
2.2 Practice → the match note and 테니스 여정
Match journals in the market pair one note with a mood after the match, keep it private and share it on purpose (Tennispreneur, GameSetMatch, matchmind), and the one AI feature in this space is a subscriber-only summary over the record (Strava's Athlete Intelligence, out of beta 2025). So: a note per match from its result (text, a three-way mood), private; 테니스 여정 as the person's notes by day with the month's Strip; AI 요약 › for the player plan and above (subscription.entity.ts: free · player · basic · pro); a club's 여정 for basic and pro, owed. Nothing of the practice log stays: the hosted table held 0 rows, so the drop (00702) loses nothing.
2.3 One control per kind of answer
| Answer | Control | Why |
|---|---|---|
| a count with a fixed unit (분, 명, 면, 세트, 게임, 일) | the typed Stepper in a Cell, the unit in the label | near values are two taps, far ones are typed; no presets to guess the right values |
| money (원) | the amount Field on the number pad | its magnitude is free; a step on it is arbitrary |
| a year | the Number field with 년 | not stepped |
| a time, a date | the time selector, the Calendar | unchanged |
| a choice without a unit | a Choice set or a Picker Cell | unchanged |
3. Duplicates: none on the boards; nine screens in the app
On the boards. By skeleton (chrome and zone sequence of every canonical frame), the only twin pair is 시작 (L0-01) and 이메일 가입 (L0-03), which share the lockup-and-band shape on purpose. By subject, every overlap found since review 46 is already folded and its code retired: L3-12 내 회비 → 클럽 홈's 회비 pane; L2-05 디렉터리 장소 → L2-04; L3-02 멤버 기록 → L3-01; L3-26 가입 신청 → L3-25; L3-40 토너먼트 → L3-38/L3-39. One page per subject holds (82 pages). Three routes carry two pages each, a pane or a sheet drawn as its own page on one screen's route: /(tabs)/(sessions) (L1-03, L1-03c), /clubs/[clubId]/dues (L3-11, L4-14), /messages (L3-14, L3-15); the page → code map lists them ("Routes two pages share"). An earlier line here claimed 0 shared routes and a build that fails on one; the navigation parity audit (2026-11-01) corrected it.
In the app (page-code-map, "App routes no page claims"): 9 screens and 10 pure redirects no page claims. Each screen is a duplicate of a page by subject, and the migration retires it into that page:
| Screen today | Absorbed by | How |
|---|---|---|
/clubs/[clubId]/admin ClubAdminScreen | L4-20 클럽 설정 + the 관리 sheet on L2-01 | the admin tab's rows are 클럽 설정's groups and the gear's sheet (review 48) |
/clubs/[clubId]/preview PublicClubProfileScreen | L2-01 클럽 홈 (visitor frames) | one home for members and visitors (review 50) |
/directory-venues/[id] DirectoryVenueDetailScreen | L2-04 장소 상세 | one page for one place (review 48) |
/records/history RecordsHistoryScreen | L1-04 기록 + L3-04 기간 기록 | the history is 기록's own list and 기간 기록's rows |
/sessions/[sessionId]/payments SessionPaymentsScreen | L3-16 참가비 내역 and L3-35 참석자 관리 | the viewer's own fees, and the host's confirmations |
/tournament-board TournamentBoardScreen | L3-38 스코어카드 + L3-39 운영 | a tournament is stages of the session's matches (review 48) |
/m/[matchId], /p/[userId], /lb/[clubId] share cards | L0-07 웹 공유 페이지 | one web share page per object; the registry gives L0-07 these routes in the next registry pass |
10 redirects (/home, /clubs, /ranking, /leaderboard, /activity*, …) | — | kept as redirects for old links, or dropped with the route tree |
4. Navigation: every page's doors, measured
docs/workflows/page-links.json lists every way a page opens another (329 links across 82 pages; kinds: tab, header, menu, row, door, band, fab, switcher, push, link). The board build fails on an unknown page, a page nobody opens, a page that opens nothing unless it is a named leaf (9 leaves), and a mutual pair missing a direction (7 pairs). The navigation map draws it; page-code-map.md lists per page what opens it and what it opens. Five doors lead to pages no board holds yet (정기 일정, 조, 앨범 관리, 행사; the owed list), which the boards owe before the build reaches them.
5. From a page to code: the map
docs/architecture/page-code-map.md is generated from the three registries and held by yarn docs:check: per page the board frame that is its design, its route, what serves the route today (the screen file and its blueprint's state, or new), and its doors. Counts on 2026-11-01: 82 pages; 68 served by a screen today, 8 new (신뢰 기록, 참가비 내역, 행사 만들기, 테니스 여정, 입금 계좌, 연결된 계정, 장부, 대진 짜기), 6 outside the app; 84 app routes, 19 claimed by no page (§ 3), 3 carrying two pages each.
The build order the map implies: the kit's components first (@twomore/ui primitives map 1:1 to the kit's Fvk* pieces; W2a moved Tag and Choice, W2b moves the rest with their pages), then one screen per page row from its board frame, reusing the surviving layers (domain, adapters, view models; the UI migration readiness note), then the retirements in § 3, then the owed pages.
6. The audits still needed before a page is "implemented"
Each is a gate the build should hold, in the order the migration needs them:
- Kit → component parity. Every
Fvk*piece on the boards has one@twomore/uicomponent with the same props (W2b). Audit: a table from the kit's index (flat-v2-kit-content.jsxlines 20–140) topackages/ui/src, with the gaps; the existingwireframe-kit-parity.test.mjsgrows to hold it. - Data contract per page. For each page row: the hooks and RPCs it reads and writes, against the boards' spec rows (Stack, Taps) and the app's
@/registryports; the gaps are new RPCs or columns (the match note needs a table; 테니스 여정's AI 요약 needs an edge function and the plan gate). - States per page. Each page's loading, empty, error, offline and role variants exist on its board (the frames) and in the screen; the verifier's checks cover the boards, a screen test per state covers the code.
- Copy. Every string on a board frame exists as an i18n key (the language pass of 10-28 aligned the words; the keys are not yet checked against the boards). Audit: a copy dump of the boards (
copy-dump.mjs) diffed against the ko registry. - Navigation parity.
page-links.jsonagainst the app'sroutesregistry and each screen's navigation calls: every link drawn has a route and a handler; nothing navigates where no link is drawn. - Permissions and roles. Each page's role layer (host, official, member, visitor, stranger) against RLS and the
can*helpers; the boards name the roles per frame. - Deep links and shares. The web share pages (L0-07) and the universal links (
/s,/p,/m,/lb) against the registry. - Accessibility. The boards carry spoken labels (the Spoken rows); the screens need the same
aria/accessibilityLabel; the a11y gate (layout-audit,check-color-contrast) extends to the new components. - Analytics and signals. The events each page emits (opened, acted) and the push signals that open it, against
signals.entity.ts. - Performance. Lists with Protocol A bulk siblings, image budgets for the Feed and the album, the 200% text frames as the layout floor.
Of these, 1, 2 and 5 decide the build order and should run first; 3, 4 and 8 run per page as it is built; 6, 7, 9 and 10 run as release gates. Audits 1, 2 and 5 ran on 2026-11-01: owner-review-52-audits-2026-11-01.md.