coffee_run CLAUDE.md
Coffee Run is a fun React + Supabase + Vite app for tracking team coffee runs. It exists to finally answer the eternal office question:
Coffee Run — AI Coding Agent Instructions
Intro
Coffee Run is a fun React + Supabase + Vite app for tracking team coffee runs. It exists to finally answer the eternal office question:
"Whose turn is it to get the coffee?"
React Component Patterns
ParticipantContext Loading Race Condition
CRITICAL: Components that use useOptionalParticipantContext() or useParticipantContext() and make Supabase queries MUST check the loading state before querying.
The Problem:
When users access the app via magic link (/p/:token), the ParticipantContext must:
- Set the participant token in the database session (
app.participant_token) - Allow RLS policies to evaluate correctly
There's a race condition where:
ParticipantContextsetsloading = false- Components render and start making queries
- But the token may not be fully set in the DB session yet
- RLS policies block the queries → empty results
The Solution:
Always check participantContext?.loading before making any database queries in useEffect hooks.
Pattern to follow:
const participantContext = useOptionalParticipantContext();
useEffect(() => {
// CRITICAL: Wait for participant context to finish loading
if (participantContext?.loading) {
return;
}
if (!accountId) {
return;
}
// Now safe to query - token is set in DB session
void fetchData();
}, [accountId, fetchData, participantContext?.loading]);
Components that need this pattern:
- Any view or component accessible via participant routes (
/p/:token/*) - Any component that calls Supabase with
participantContext?.token - Examples:
IOUsView,DashboardView,RunHistory,NextUp
Why it matters:
- RLS policies check
current_setting('app.participant_token', true) - If token not set → policies block queries → empty results
- This causes intermittent "no data" bugs that are hard to reproduce
When adding new components:
- Check if it uses
useOptionalParticipantContext() - Check if it makes Supabase queries in
useEffect - If yes to both → add the loading check
Supabase Development
⚠️ IMPORTANT: Refer to WORKTREE_SUPABASE.md for current instance details, including:
- Service Ports (Studio UI, API, DB, etc.)
- Docker Container Names
- Database Connection Commands
Migrations & Reset
# Create new migration
npx supabase migration new <descriptive_name>
# List migrations
npx supabase migration list
# Generate TypeScript types from schema
npx supabase gen types --local > src/types/database.ts
Querying the Database
Via Docker (when psql isn't installed locally):
Note: Confirm the container name in
WORKTREE_SUPABASE.md.
# Run a single query
docker exec supabase_db_coffee_run psql -U postgres -c "SELECT * FROM participants LIMIT 5;"
# Interactive session
docker exec -it supabase_db_coffee_run psql -U postgres
# Describe table structure
docker exec supabase_db_coffee_run psql -U postgres -c "\d participants"
# List all tables
docker exec supabase_db_coffee_run psql -U postgres -c "\dt"
Testing RLS Policies
The app uses app.participant_token for participant authentication:
-- Simulate participant access
SET app.participant_token = 'some-access-token-here';
-- Test participant can see their group
SELECT * FROM participants
WHERE account_id IN (
SELECT account_id FROM participants
WHERE access_token = current_setting('app.participant_token', true)
);
-- Reset to owner/admin context
RESET app.participant_token;
Tips
- Pin CLI version in
package.jsonto avoid breaking changes - Use
--localflag for local dev commands (it's often the default) - Use the Studio UI for quick schema inspection (URL in
WORKTREE_SUPABASE.md) - RLS policies require
app.participant_tokento be set — test both owner and participant contexts