Skip to content

TwoMore App Functionality Map

Status: Active Last reviewed: 2026-06-28

This document describes what the current app delivers from the user's point of view and from the backend capability point of view. It is not a backlog, not a wireframe, and not a promise that every surface is production-launched.

Use it to answer:

  • What does each tab do?
  • Which support screens and backend systems make those tabs work?
  • Which capabilities are built, scaffolded, or externally gated?
  • Where should roadmap and market decisions attach to the real product?

Evidence Floor

EvidenceWhat it proves
Current Project StateCurrent versions, migration count, web page count, launch posture, auth/payment gating, and enforcement coverage.
Product Spec SheetProduct definition, personas, success metrics, and launch/non-launch scope.
apps/mobile/app/(tabs)Mobile has five user tabs: 홈, 클럽, 경기, 기록, 프로필. The mobile folder for 경기 is (sessions) but it mounts the activity feature.
apps/web/app/(tabs)Web mirrors the five-tab model and uses /activity for the 경기 tab route.
packages/features/*/src/index.tsRouter-agnostic screen packages exported for home, clubs, activity, sessions, records, profile, messaging, and onboarding.
packages/app/src/presentation/hooks/queries and packages/app/src/presentation/hooks/mutationsData access and mutation surfaces for clubs, sessions, payments, records, DM, trust, venues, weather, notifications, and profile/account flows.
packages/app/src/adapters/supabase and packages/app/src/portsSupabase adapters sit behind repository/service ports rather than being called directly from feature UI.
supabase/functionsProduction-facing edge functions for weather, venue search, push, PortOne verification/webhooks, export, and scenario/dev support.

Product Shape

TwoMore currently behaves as a Korean amateur-tennis club operating system with a mobile-first app, a web shell, and shareable public routes.

The primary loop is:

  1. User signs in or uses a dev-login path in non-production contexts.
  2. User completes onboarding and lands in an intent-aware first action: Home by default, Clubs discovery/create, join club, pickup hosting, a public share receiver, or a safe internal next route when present.
  3. User joins, creates, discovers, or receives a shared club/session/pickup.
  4. User RSVPs, applies, pays or confirms payment state, attends, plays, records results, and returns for records/profile/trust.
  5. Organizers manage sessions, members, dues, attendance, guest applications, exceptions, and communication from club/session surfaces.

The current freshness model does not depend on persistent ambient Supabase Realtime channels. It uses freshness contracts, focus/foreground refetch, bounded polling on volatile surfaces, push-triggered invalidation, and mutation invalidation.

Platform Shells

SurfaceCurrent delivery
MobileExpo Router app for iOS/Android with five primary tabs, deep-link routes, EAS update support, and native scaffolding for Kakao/notifications/payments.
WebNext App Router shell mounting shared feature screens through router-agnostic packages, plus public share/open-graph routes.
Shared app layer@twomore/app exports domain types, ports, hooks, routes, i18n, registry access, cache helpers, and shared app components.
Feature packagespackages/features/* own screens and import only from @twomore/app and @twomore/ui, not from platform routers.
UI layerpackages/ui owns Tamagui primitives and reusable layout patterns.
BackendSupabase Postgres/RLS/migrations/storage/edge functions behind adapters and ports.

Primary Tabs

Home / Clubs / Activity Responsibility Split

The club-admin strategy does not mean every admin surface should become a top-level Home destination. The product split is:

SurfaceResponsibilityClub-admin implication
High-frequency attention router: today, this week, this month, live play, disputed scores, payment/session obligations, and recommendations.Surface only actionable admin exceptions for admins: payment confirmation, RSVP deadline risk, attendance closeout, join/guest decisions, reports. Do not turn Home into the full admin console.
클럽Club identity, membership, discovery, club health, and administration.This is where the club operating cockpit belongs. The club tab should make club value visible to members and admins, not only to users already inside a club detail admin tab.
경기Session and pickup execution: find play, RSVP, manage upcoming play, live session detail, and host/session-specific actions.Session-level host workflows stay here, but club-level operations should roll up to Clubs and admin exceptions can point back from Home.

This keeps the current Home design intact: it remains the most frequently visited, action-packed surface with consolidated club/pickup sessions, live match visibility, and weekly/monthly progress. The adjustment is to give club-based activity more prominence in the Clubs tab and use Home as a role-gated alerting layer when a club official has work to do.

User job: understand what matters now without becoming a schedule list.

Home is the present-tense feed. It surfaces today's, this week's, and this month's relevant signals, notifications, disputed-match prompts, recommendations, club/session highlights, and unresolved user attention items. It intentionally does not act as the full scheduled-session list because that belongs to 경기.

LayerCurrent implementation
Main screenHomeFeedScreen from packages/features/home.
Mobile routeapps/mobile/app/(tabs)/(home) and related home routes.
Web routeapps/web/app/(tabs)/home.
Key dataHome data, disputed matches, unread signals, recommendations, notifications, foreground refresh.
Backend supporthome-signals, signal, match/session/profile adapters, notification service, push-triggered invalidation.
Product roleRe-entry surface, exception surfacing, and attention routing.

Planned admin attention rule: when the viewer has club-admin permissions, Home may show small exception cards for urgent club work. Those cards deep-link to the club admin cockpit or existing admin screens. Home should not list all admin tools.

클럽

User job: find, join, administer, and grow clubs.

The club area separates "my clubs" from discovery. Joined clubs are sorted around what matters next, while discovery supports search, filters, media, stats, and join/apply paths. Club detail surfaces branch into board posts, members, settings, dues, attendance, analytics, venues, sessions, partner suggestions, challenges, and public profile/share flows.

LayerCurrent implementation
Main screensClubsMyScreen, ClubsDiscoverScreen, ClubDetailScreen, PublicClubProfileScreen.
Mobile routesapps/mobile/app/(tabs)/(clubs), club/[id], clubs/[clubId]/*, join-club, create-club.
Web routes/clubs, /clubs/[clubId]/*, /create-club, public club/share routes.
Key dataClub membership, roles, invites, join requests, discovery summaries, media, dues, analytics, attendance, venues, posts, challenges.
Backend supportClub, club media, analytics, event, dues, invite, post, venue, member report, inter-club challenge, and guest-application adapters.
Product roleClub supply, admin cockpit foundation, and social graph anchor.

Planned club emphasis rule: the club tab should become the primary destination for club identity and operations. Joined-club cards should expose next sessions, role, club health/activity, and admin-action badges where permissions allow. Non-members should still see discovery/preview flows; private member/admin content remains role gated.

경기

User job: find play, manage upcoming play, and act on session obligations.

The user-facing 경기 tab is implemented by the activity feature. On mobile the folder is named (sessions) for legacy route grouping, but the mounted tab surface is the activity screen. On web the route is /activity.

The activity surface includes active user sessions, pickup discovery, filters, saved sessions, RSVP/payment state, and navigation into session detail. Session detail then becomes the main operational screen for players and hosts: status, logistics, venue/weather, participants, matchups, payments, attendance, host actions, share, GPS check-in, guest applications, and post-session steps.

LayerCurrent implementation
Main screensActivityScreen, ActivityUpcomingSessionsScreen, ActivityPickupsScreen, SessionDetailScreen, PickupHostDashboardScreen.
Mobile routesapps/mobile/app/(tabs)/(sessions), session/[id], sessions/[sessionId]/*, create-session, courts, venues.
Web routes/activity, /sessions/[sessionId]/*, /create-session, /courts, /venues, public /s/[sessionId].
Key dataRSVP, waitlist, saved sessions, payments, guest applications, live session data, weather/TMI, venue/court context, match board, scorecard.
Backend supportSession, RSVP, saved-session, session-payment, guest-application, attendance-record, venue, court-review, weather, match, player-matchup, session-feedback adapters and edge functions.
Product roleCore play loop, pickup supply, host workflow, and payment/trust gateway.

기록

User job: see competitive identity, progress, history, and leaderboards.

Records is the analytics and competitive-history area. It owns ELO/tier display, format stats, partner stats, trend charts, personal records, match history, head-to-head views, leaderboard scopes, and shareable leaderboard/stat surfaces. This is intentionally not a profile-settings surface.

LayerCurrent implementation
Main screensRecordsScreen, RecordsLeaderboardScreen, RecordsHistoryScreen, RecordsDayScreen, HeadToHeadScreen.
Mobile routesapps/mobile/app/(tabs)/(records) and records/*.
Web routes/records, /records/*, public /m/[matchId], /lb/[clubId].
Key dataRatings, tiers, match history, score calls, achievements, progression, practice logs, milestones, leaderboards, matchup records.
Backend supportMatch, match-set, match-score-call, club-elo-rating, progression, achievement, practice-log, participation-milestone, player-matchup, season-record adapters.
Product roleRetention, identity, competitive trust, and shareable proof of play.

프로필

User job: manage identity, social graph, privacy, safety, account, and settings.

Profile is the identity and account-management hub. It shows avatar/name/tier, lightweight stats, friends summary, achievements, attendance and manner tags, direct-message entry, share cards, settings, legal/account paths, consent history, privacy controls, blocked users, and account export/delete paths.

LayerCurrent implementation
Main screensProfileScreen, SettingsScreen, PublicProfileScreen, friends/settings/legal/account screens.
Mobile routesapps/mobile/app/(tabs)/(profile), profile/*, settings, legal/account routes, public /p/[userId].
Web routes/profile, /settings, /p/[userId], profile/settings subroutes.
Key dataProfile, preferences, auth state, consents, friendships, achievements, attendance/manner signals, reports/blocks, export/delete.
Backend supportProfile, preferences, auth, consent, friendship, safety, member-report, achievement, attendance-record, manner-tag, edge export function.
Product roleAccount trust, social graph, privacy compliance, and user identity.

Supporting Surfaces

SurfaceWhat it deliversNotes
OnboardingFirst-run setup for account/profile, consent, play style, and intent-aware app entry.Mobile root gate owns destination choice; production social auth remains externally gated.
MessagingDM inbox, threads, group creation, add-members, requests, unread state, image support, accept/decline flow.Keep lightweight; do not rebuild Kakao group chat.
Public share routesPublic club/session/match/profile/leaderboard landing and preview routes.Needed for Kakao/share growth loop and web open graph.
Legal/accountTerms, privacy, consent history, contact, delete account, password/profile edit.Legal text and CPO/contact values remain launch gates.
Dev/opsDev panel, scenario seeding, simulation, debug login, production guardrails.Must stay inaccessible to normal production users.

Backend Capability Map

Capability groupCurrent backend support
Identity and accessSupabase auth adapter, profile repository, preferences, consent repository, RLS migrations, export-user-data function, account safety paths.
Club operationsClub repository, roles/membership, invites, join requests, discovery summaries, media, posts, dues, analytics, alerts, attendance, reports, venues, challenges.
Session operationsSession, RSVP, waitlist, saved sessions, templates, payment states, guest applications, attendance, scorecards, match board, feedback, host authority.
PaymentsManual fee state, mock checkout, session payment repository, PortOne verify and webhook edge functions, payment service port.
Records and ratingsMatch/match-set/score-call repositories, club ELO ratings, progression, achievements, milestones, leaderboards, practice logs, head-to-head data.
Trust and safetyReports, blocks, manner tags, attendance/no-show records, consent history, privacy settings, safety repository.
Messaging and signalsDM repository, home signals, signal repository, unread counts, notification service, push send and receipt-check functions.
Venue and weatherVenue repository, court review, venue search edge function, static map function, weather fetch/warnings/forecast functions, TMI/playability support.
Operations and observabilityClient error repository, Sentry wrapper, performance events, scenario seed/simulate functions, generated docs and enforcement gates.

Built, Scaffolded, Gated

AreaStatusPractical meaning
Core club/session/records loopBuiltProduct direction should harden, test, and sequence existing surfaces before adding speculative feature families.
Manual payment stateBuiltSupports transfer/manual-fee reality and admin visibility.
PortOne production railScaffolded and externally gatedRequires owner/vendor setup, native runtime adapter proof, server verification, webhook smoke, refund/support policy, and audit clarity before charging real users.
Kakao auth/shareAuth scaffolded; share paths builtProduction IdP credentials and Kakao-native share integration remain launch/growth work.
Direct venue bookingNot built as marketplaceCurrent system supports venue/court context and handoff. Booking marketplace should wait for venue supply validation.
SubscriptionsSpec/entity shellsPilot only after retained clubs and payment trust exist.
Coaching/brand marketplacePlannedShould follow retained user intent and working payment rails.
Multi-sport/internationalHeldDo not generalize before Korea tennis retention and revenue evidence.

Development Implications

  • Treat this map as the first stop before changing the roadmap, product spec, or market thesis.
  • If a new feature adds a user-facing workflow, update the relevant tab/support section in the same docs-only slice.
  • If a backend adapter, port, migration family, or edge function changes the product capability set, update the Backend Capability Map.
  • If a capability moves from scaffolded to production-ready, update this doc, Product Spec Sheet, Roadmap, Roadmap Implementation Plan, Production Readiness, and the blocker register as needed.
  • Keep current-state facts in generated docs. Do not hand-edit generated pages.

Verification

When this document changes, run:

bash
yarn docs:generate
yarn docs:check

Markdown remains the source of truth. Run yarn docs:check before handoff.