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.
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.
Next Steps
Inferred from recent momentum, open TODOs, and explicit notes in Executive_Summary_3_8_26.md.
Test matching with real accounts — 3 test accounts configured (scott@yourmise.com, petras.lex@gmail.com, talent1alex@yourmise.com). Verify My Matches tab works end-to-end on TestFlight build 77.
"I'm In" workflow — Currently shows a placeholder alert. Needs: notification to team, team-side dashboard visibility, match acceptance event chain.
Top Choice workflow — What happens when a team sees they've been Top Choiced? Notification design, team dashboard integration, response actions.
Match expiration / refresh UX — Stale matches after a job closes need graceful handling. Daily cron refreshes at 6 AM UTC but UI doesn't yet reflect expired matches.
Team-side talent dashboard — Managers currently can't see incoming matches. This is the other half of the matching loop.
Legacy table migration — Plan a sprint to move all talent → workers references and remove the old tables.
Branch cleanup — Audit 5 unmerged branches, merge or archive.
Ma ka hana ka ʻike — In working, one learns. 🌺
Generated March 10, 2026 · Mise Project Recap