v1.0.0 Build 77 iOS TestFlight

Mise

Hospitality staffing platform connecting restaurants with qualified workers across 6 US metros. React Native/Expo Router + Convex backend. Early-stage product in active development — shipping to TestFlight weekly, building out the core matching loop between talent and teams.

Project Identity

Elevator pitch: Mise is Tinder for hospitality jobs — workers swipe through AI-scored matches, restaurants discover pre-qualified talent, and the platform handles the messy middle of scheduling, perks, and team coordination.

Stack
Expo Router · Tamagui · Convex · Clerk
Bundle
com.lexalex.mise
Launch Cities
NYC · Chicago · SF · Seattle · Houston · Denver
Schema Tables
30+ Convex tables (users, workers, teams, jobPostings, talentJobMatches, metros, soupDeals…)

Architecture Snapshot

graph TB
  subgraph CLIENT["📱 Expo Router App"]
    direction TB
    AUTH["Auth\n(Clerk SSO)"]
    ONBOARD["Onboarding\n25-step worker\n11-step manager"]
    MATCH_UI["My Matches\nMatchCard, MatchIntroOverlay\nSectionList with state groups"]
    PERKS["Perks (Soup)\nDeals map, partners\nCity-scoped"]
    HIRING["Hiring\nJob posting wizard\nQuick Apply"]
    DASH["Dashboards\nWorker · Manager\nTeam management"]
  end

  subgraph CONVEX["⚡ Convex Backend"]
    direction TB
    SCHEMA["Schema\n30+ tables"]
    MATCHING["Talent Matching\n7-factor scoring engine\ntriggers + cron"]
    JOBS["Job Postings\nCRUD + matching"]
    TEAMS["Teams\nMemberships\nInvites"]
    METRO["Metro System\nSlugs, GPS bounds\nNeighborhoods"]
    SOUP["Soup Deals\nRedemptions\nInterests"]
    CRON["Daily Cron\nMatch refresh\n6 AM UTC"]
  end

  subgraph SERVICES["🔌 External"]
    CLERK_SVC["Clerk\nAuth + SSO"]
    PLACES["Google Places\nRestaurant search"]
    MAPS["Apple/Google Maps\nDeal pins, metro maps"]
  end

  AUTH --> CLERK_SVC
  ONBOARD --> SCHEMA
  MATCH_UI --> MATCHING
  MATCH_UI --> JOBS
  PERKS --> SOUP
  PERKS --> MAPS
  HIRING --> JOBS
  DASH --> TEAMS
  MATCHING --> SCHEMA
  JOBS --> SCHEMA
  TEAMS --> SCHEMA
  METRO --> SCHEMA
  SOUP --> SCHEMA
  CRON --> MATCHING
  ONBOARD --> PLACES

  style CLIENT fill:#f0fdf4,stroke:#4d7c0f,stroke-width:2px,color:#1c1917
  style CONVEX fill:#f0f9ff,stroke:#0369a1,stroke-width:2px,color:#1c1917
  style SERVICES fill:#fef3c7,stroke:#b45309,stroke-width:2px,color:#1c1917
    

Recent Activity Feb 24 – Mar 10, 2026

84 commits · 68 files changed · +7,427 / −2,333 lines · 1 contributor (Scotty + Claude Code)

🎯 Talent Matching — The Big Feature

Mar 8
Full Talent Matching build (~3,000 lines)
Schema (talentJobMatches table), 7-factor scoring engine (matchScoring.ts), state machine mutations (new → considering → sent/top_choice/not_interested), trigger system, daily cron, MatchCard UI, MatchIntroOverlay, MyMatchesScreen with 4-section SectionList, mock data for 12 Seattle jobs + 7 workers.
Mar 9–10
Post-launch polish
Made all My Matches sections collapsible. Routed all job-board links to my-matches. Restored full 25-step onboarding flow (fixed lookingForWork skip logic). Fixed ScheduleWidget ghost dots.

🏠 Onboarding Refinement

Feb 24–28
Accordion layouts, validation, UX tightening
Steps 10, 14, 18 → accordion layouts. Phone validation (10-digit US). SSN deprecation notice. Age option cleanup. Service styles added (Music/Club, Coffee Shop). Seattle neighborhoods updated. Schedule widget shared component. Years stepper on Step 11.
Mar 5–8
Steps 7, 11, 12 UX enhancements + salary display
Simplified salary display, scroll-to-day on Step 12, YOUR SELECTION summary repositioned below shift picker.

🔧 Platform Infrastructure

Mar 1–3
Auth flow overhaul
Deferred user type selection to post-auth. Patched user row on reset (no delete → prevents duplicates). Made userType optional in schema. Welcome copy replaces Y-in-Road buttons.
Mar 2–4
Hiring system graduated
Mocked hiring backend → real Convex mutations. Metro scoping. Manager view. Quick Apply. Applications → mobile card layout. Browse All Jobs navigation fixed.
Mar 5
Perks screen (Soup → Perks rename)
Soup tab renamed to "Perks" with moka pot icon. Deals/Partners tabs. Maps zoomed to neighborhood level. Tab labels refined to "The Soup" / "Mise Partners".
Throughout
6 TestFlight builds (72→77)
Continuous iOS deployment via EAS. Each significant feature or fix batch shipped to testers.

Decision Log

Talent-controlled matching (privacy-first)
Matches start private ("new"). Workers decide when teams see them — progressing through considering → sent/top_choice. This reverses the typical job board dynamic where employers browse candidates. Rationale: hospitality workers are the scarce resource, not jobs.
7-factor scoring replaces 3-factor
Old: position (40), metro (30), availability (20), experience (10). New: position (30), service style (15), compensation (15), metro (15), availability (10), skills (10), experience (5). Why: the old system gave too much weight to position alone and ignored pay alignment entirely.
Deferred user type selection to post-auth
Previously the "Y-in-Road" screen asked worker vs. manager before login. Now: authenticate first, then select type in Step 24 of onboarding. Simpler auth flow, fewer edge cases with Clerk SSO cancellation.
Job Board → My Matches (navigation consolidation)
The old job-board screen was a placeholder. All navigation now routes to my-matches, which is the real destination. The job-board route file is dead code for future cleanup.
Account reset patches rows, doesn't delete
Deleting user rows on reset caused duplicate tokenIdentifier conflicts when re-creating. Now: patch existing row (clear fields, keep ID). Convex unique index constraint respected.

State of Things

12
Working Features
3
In Progress
5
Unmerged Branches
77
TestFlight Build

✓ Working & Shipped

  • 25-step worker onboarding
  • 11-step manager onboarding
  • 7-factor talent matching + MyMatchesScreen
  • Hiring system (job posting, Quick Apply)
  • Perks / Soup Deals with map pins
  • City Wishlist & Voting (Phase 1)
  • Metro system (6 cities, neighborhoods, GPS)
  • Clerk auth (email, Google, Apple SSO)
  • Account reset for testing
  • Restaurant autocomplete (Google Places)
  • Scheduling widget (shared component)
  • Applications (mobile card layout)

⟳ In Progress / Incomplete

  • "I'm In" workflow (match acceptance → TBD events)
  • Top Choice workflow (team-side visibility)
  • Team setup form (backend stubs only)

⚠ Known Gaps

  • No iOS Google Maps key (Apple Maps only on iOS)
  • Legacy talent table still in schema
  • 16+ TODO comments across source
  • Job board route file is dead code
  • 5 unmerged feature branches
Uncommitted changes: CLAUDE.md and Executive_Summary_3_8_26.md have local modifications.

Mental Model Essentials

  • Two user types, one auth: Workers and managers share the users table (Clerk token). Type-specific data lives in workers or managers tables linked by userId. User type is optional during onboarding and set at Step 24.
  • Metro is the scoping boundary: Almost everything is metro-scoped — job postings, matches, soup deals, neighborhoods. Workers outside the 6 launch metros go to the City Wishlist flow. Metro slugs like seattle-wa are the canonical identifiers.
  • Match state machine: talentJobMatches status flows: new → considering → sent / top_choice / not_interested. Workers control visibility — teams only see matches in "sent" or "top_choice" status. Top Choices capped at 10.
  • Onboarding version tracking: Workers have onboardingVersion (v1 = old 7-step, v2 = 25-step). forceNewUserMode lets testers re-run onboarding without clearing DB. lookingForWork determines if user sees all 25 steps or condensed 9.
  • Convex reactivity: UI updates automatically when backend data changes. Match cards move between SectionList groups in real-time. No manual refresh needed — but pull-to-refresh exists for user comfort.
  • Legacy "talent" table still exists: The original talent table (pre-worker/manager split) is still in the schema. teamMembers references talentId. Migration incomplete — both old and new tables coexist.
  • Webhook mutations must be internalMutation: Clerk webhooks use internal mutations (not public) for security. This is a Convex requirement.
  • Maps platform split: iOS uses Apple Maps (MapKit, no key needed). Android uses Google Maps (PROVIDER_GOOGLE). Unifying on Google Maps for iOS requires adding googleMapsApiKey to app.json + native rebuild. Decision pending.

Cognitive Debt Hotspots

HIGH

TalentProfileFormScreen.tsx — 2,000+ line monolith

The 25-step worker onboarding is a single file with 20 commits in the last 50. Every step's UI, validation, and state management lives here. No documented rationale for why it isn't broken into per-step components. Suggestion: extract each step into its own component file under components/onboarding/steps/ — the form state can remain centralized.

HIGH

Legacy talent + teamMembers tables

The original data model (talent, teamMembers, talentSkills, talentLanguages) coexists with the new model (workers, workerTeamMemberships, workerSkills, workerLanguages). Some code paths may still reference legacy tables. Suggestion: audit all queries for talent table usage and plan a migration sprint.

MEDIUM

Match scoring engine used in two places with different data paths

matchScoring.ts is called by both jobMatching.ts (real-time query for JobRecommendationsChunk) and triggers/matching.ts (batch generation for talentJobMatches). The shared engine is good, but the two callers resolve skills differently and the real-time path doesn't generate persistent matches. Suggestion: add a doc comment to scoreWorkerAgainstJob() explaining the two usage contexts.

MEDIUM

5 unmerged feature branches

feature/development, feature/test-team-creation, feature/userboard-initial-load, mise-talent-plus, team-onboarding. Unknown state — may contain valuable work or may be stale. Suggestion: audit each branch, merge or archive.

LOW

Dead route: job-board.tsx

All navigation now points to my-matches. The job-board route file is dead code. Commit message explicitly calls it out. Suggestion: delete the file in the next cleanup pass.

LOW

Disabled route files (.disabled extensions)

Multiple .tsx.disabled files in the authenticated routes directory (soup.web.tsx.disabled, SoupMapNative.native.tsx.disabled, etc.). These are abandoned experiments. Suggestion: delete or move to an archive directory.

Ma ka hana ka ʻike — In working, one learns. 🌺
Generated March 10, 2026 · Mise Project Recap