Goal: Every person (Alex, Lex, Scott) wears three hats — testing the full persona matrix independently, across two restaurants.
| Person | Path | Team(s) | Role | Switch Profile Shows | |
|---|---|---|---|---|---|
| Alex | alex@bluehourdigital.com | Team (manager) | iL Bistro + Queen City Grill | owner | No switch — always management |
| Alex | alexmichaelholden@gmail.com | Talent | iL Bistro + Queen City Grill | member | Personal + iL Bistro (member) + Queen City Grill (member) |
| Alex | alex@yourmise.com | Talent | iL Bistro + Queen City Grill | assistant_manager | Personal + iL Bistro (mgmt) + Queen City Grill (mgmt) |
| Lex | petras.lex@gmail.com | Team (manager) | iL Bistro + Queen City Grill | owner | No switch — always management |
| Lex | lexpetras@gmail.com | Talent | iL Bistro + Queen City Grill | member | Personal + iL Bistro (member) + Queen City Grill (member) |
| Lex | lex@yourmise.com | Talent | iL Bistro + Queen City Grill | assistant_manager | Personal + iL Bistro (mgmt) + Queen City Grill (mgmt) |
| Scott | ssoderstrom@gmail.com | Team (manager) | iL Bistro + Queen City Grill | owner | No switch — always management |
| Scott | scott@yourmise.com | Talent | iL Bistro + Queen City Grill | member | Personal + iL Bistro (member) + Queen City Grill (member) |
| Scott | scott@paumalu-innovations.com | Talent | iL Bistro + Queen City Grill | assistant_manager | Personal + iL Bistro (mgmt) + Queen City Grill (mgmt) |
Total: 9 Clerk accounts, 2 restaurants, 3 personas per person.
A single worker can have multiple workerTeamMemberships rows:
workerId: "lex-worker"
├── teamId: "il-bistro", role: "member"
└── teamId: "queen-city-grill", role: "assistant_manager"
What the backend currently does (convex/experienceContext.ts):
- Returns ALL teams in the teams[] array
- Sets isManagement: true for any team where role is assistant_manager
What Switch Profile does now (Option B implemented in 0946592):
- Shows all teams — both management and member teams
- SubLabel shows "Management" for assistant_manager / owner roles, "Team Member" for member roles
- Tapping any team switches the in-team context (messages, announcements, policies)
- Management chrome (header color, forum topics, Post Deal button) only activates when the selected team has isManagement: true
Send this to Alex, Lex, Scott:
I've wiped all old accounts. Please do the following for each of your 3 emails:
- Open Mise and sign up with Email 1 (Google or basic email/password)
- Stop at the "Who are you?" screen — the three cards (Talent, Team, Vendor)
- Do NOT tap anything yet. Send me a screenshot so I know you reached it
- Sign out, repeat with Email 2, then Email 3
Which email → which card: | Your Email | Tap This Card | |---|---| |
alex@bluehourdigital.com| Team | |alexmichaelholden@gmail.com| Talent | |alex@yourmise.com| Talent | |petras.lex@gmail.com| Team | |lexpetras@gmail.com| Talent | |lex@yourmise.com| Talent | |ssoderstrom@gmail.com| Team | |scott@yourmise.com| Talent | |scott@paumalu-innovations.com| Talent |Wait for my go-ahead before tapping through. I need to prep the backend first.
Important: Everyone should pick the same metro during onboarding (e.g. Seattle or NYC) so soup deals are consistent.
Each manager email taps Team, completes onboarding, creates a restaurant:
| Manager Email | Creates Team |
|---|---|
alex@bluehourdigital.com |
iL Bistro |
petras.lex@gmail.com |
Queen City Grill |
ssoderstrom@gmail.com |
Place Pigalle (optional third team) |
This automatically creates:
- users row with userType = "manager"
- managers row
- teams row
- managerTeamMemberships with role = "owner"
If you want every manager to be on every team, run these mutations. For example, make Alex an owner on Queen City Grill too:
// Alex on Queen City Grill
await ctx.db.insert("managerTeamMemberships", {
managerId: "<alex-manager-id>",
teamId: "<queen-city-team-id>",
role: "owner",
joinedAt: Date.now(),
});
Repeat for all cross-combinations.
After the 6 Talent emails have signed up and reached the "Who are you?" screen (or completed it), get their Convex IDs:
# Get all users, look for the 6 talent emails
convex data users --limit 20 --order desc | grep -E "(alexmichaelholden|lexpetras|scott@yourmise|alex@yourmise|lex@yourmise|scott@paumalu)"
# Get their worker IDs
convex data workers --limit 20 --order desc
For each talent account, create memberships on all teams:
Alex's talent emails:
// alexmichaelholden@gmail.com — member on both teams
await ctx.db.insert("workerTeamMemberships", {
workerId: "<alex-holden-worker-id>",
teamId: "<il-bistro-team-id>",
position: "server",
role: "member",
joinedAt: Date.now(),
});
await ctx.db.insert("workerTeamMemberships", {
workerId: "<alex-holden-worker-id>",
teamId: "<queen-city-team-id>",
position: "bartender",
role: "member",
joinedAt: Date.now(),
});
// alex@yourmise.com — assistant_manager on both teams
await ctx.db.insert("workerTeamMemberships", {
workerId: "<alex-yourmise-worker-id>",
teamId: "<il-bistro-team-id>",
position: "shift_supervisor",
role: "assistant_manager",
joinedAt: Date.now(),
});
await ctx.db.insert("workerTeamMemberships", {
workerId: "<alex-yourmise-worker-id>",
teamId: "<queen-city-team-id>",
position: "shift_supervisor",
role: "assistant_manager",
joinedAt: Date.now(),
});
Repeat for Lex and Scott's talent emails.
Result: Each assistant_manager account has 2 management teams in Switch Profile.
Currently, SwitchProfilePanel.tsx filters to isManagement teams only:
const managementTeams = useMemo(() => teams.filter((t) => t.isManagement), [teams]);
To show ALL teams (which you want to test):
const allTeams = useMemo(() => teams, [teams]);
And in PersonaContext.tsx, deriveDefaultActiveProfile should pick the first team (not just first management team):
function deriveDefaultActiveProfile(teams) {
const first = teams[0]; // any team, not just management
if (first) {
return { kind: 'management', teamId: first.teamId, teamName: first.name };
}
return { kind: 'personal' };
}
But wait — a regular member on iL Bistro shouldn't default to "management". They should default to "Personal" and be able to switch to iL Bistro as a team context.
This means Switch Profile needs two sections: 1. Personal (always) 2. Teams (all teams the user belongs to, not just management ones)
When a user selects a team where isManagement: true, they get the management chrome (header, tabs, forum topics). When they select a team where isManagement: false, they get the member view of that team.
This is a product decision — do you want me to implement this expanded Switch Profile as part of testing setup, or keep the current isManagement filter and test what's there?
| Test | Expected |
|---|---|
| Home board | soup-deals, mini-feed, quick-post-box, team-metrics |
| Soup "Post Deal" | Visible and functional |
| Bottom tabs | Home, Messages, Perks, Hiring, My Team |
| Forum topics | SOS!, The Line, etc. |
| My Team tab | iL Bistro (and Queen City Grill if cross-membership added) |
| Test | Expected |
|---|---|
| Switch Profile | Current: Personal only (member teams hidden). Desired: Personal + iL Bistro + Queen City Grill |
| Home board | soup-deals, mini-feed, quick-post-box |
| Soup "Post Deal" | Not visible (member role) |
| Forum topics | Hands!, Shift Drinks, etc. |
| Test | Expected |
|---|---|
| Default | Personal profile → talent view |
| Switch Profile | Personal + iL Bistro (mgmt) + Queen City Grill (mgmt) |
| Switch to iL Bistro mgmt | Header ochre, forum topics SOS!, Post Deal visible |
| Switch to Queen City Grill mgmt | Same, but team-scoped data changes |
| Switch back to Personal | Everything flips to talent view |
Repeat for Lex and Scott.
# Get all users (find your 9 accounts)
convex data users --limit 50 --order desc
# Get all workers
convex data workers --limit 50 --order desc
# Get all managers
convex data managers --limit 10 --order desc
# Get all teams
convex data teams --limit 10 --order desc
# Get memberships
convex data workerTeamMemberships --limit 50 --order desc
convex data managerTeamMemberships --limit 50 --order desc
# Clear all mock data (if you want pristine)
convex run devTools:clearAllMockData '{}'
Commit: ddc3ffc on main
| File | Change |
|---|---|
expo-app/src/contexts/PersonaContext.tsx |
Added isManagement: boolean to ActiveProfile type; updated deriveDefaultActiveProfile to pick first team (any team); updated deriveShellVariantFromActive to check active.isManagement; added effect to sync isManagement flag when role changes |
expo-app/src/hooks/useUserPermissions.ts |
isWorkerPlus now requires activeProfile.isManagement === true, not just kind === 'management' |
expo-app/src/components/persona/SwitchProfilePanel.tsx |
Shows all teams with subLabel "Management" or "Team Member"; passes isManagement flag on pick |
expo-app/src/components/mobile/MobileAvatarMenu.tsx |
Subtitle reflects "Management" or "Team Member" based on isManagement flag |
With Option B, a worker on both iL Bistro (member) and Queen City Grill (assistant_manager) sees:
Tapping iL Bistro switches team-scoped data to iL Bistro but keeps talent chrome. Tapping Queen City Grill switches team-scoped data AND activates management chrome.