Awesome-omni-skill user-state-debugging
Expert knowledge on debugging user account issues, diagnostic scripts (inspect-user-state.js), fix scripts (fix-user-billing-state.js, reset-user-onboarding.js), onboarding problems, billing sync issues, and Clerk vs database mismatches. Use this skill when user asks about "user stuck", "onboarding broken", "billing out of sync", "debug user", "reset user", or "user state".
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/user-state-debugging" ~/.claude/skills/diegosouzapw-awesome-omni-skill-user-state-debugging && rm -rf "$T"
skills/development/user-state-debugging/SKILL.mdUser State Debugging Expert
You are an expert in debugging user account issues and using diagnostic scripts. This skill provides knowledge about common user state problems, diagnostic tools, and fix scripts.
When To Use This Skill
This skill activates when users:
- Debug stuck onboarding flows
- Investigate billing sync issues
- Fix user account problems
- Troubleshoot trial activation failures
- Diagnose plan limit issues
- Resolve Clerk vs database mismatches
- Clean up test user data
Core Knowledge
Common User State Issues
Issue Categories:
-
Onboarding Stuck
- User can't complete signup
- Stuck at step-1 or step-2
- Never reaches "completed"
-
Billing Out of Sync
- Paid in Stripe but shows free plan
- Plan limits incorrect
shows errorbilling_sync_status
-
Trial Not Activated
- Completed checkout but trial inactive
is "pending"trial_status- Trial dates are null
-
Clerk vs Database Mismatch
- User exists in Clerk but not in database
- Email mismatch between systems
- userId doesn't match
-
Plan Limits Wrong
- User has wrong campaign/creator limits
- Upgraded but limits not updated
- Can't create campaigns despite having limit
Primary Diagnostic Script
Script:
/scripts/inspect-user-state.js
Usage:
# By email node scripts/inspect-user-state.js --email user@example.com # By Clerk user ID node scripts/inspect-user-state.js --user-id user_2abc123xyz
What It Shows:
🔎 Inspecting user state ✅ Connected to Postgres 🆔 Resolved userId: user_2abc123xyz 👤 user_profiles: { id: 'xxx', user_id: 'user_2abc123xyz', email: 'user@example.com', full_name: 'John Doe', onboarding_step: 'completed', trial_status: 'active', trial_start_date: '2025-01-15T10:00:00Z', trial_end_date: '2025-01-22T10:00:00Z', current_plan: 'glow_up', plan_campaigns_limit: 3, plan_creators_limit: 1000, stripe_customer_id: 'cus_xxx', stripe_subscription_id: 'sub_xxx', subscription_status: 'trialing', billing_sync_status: 'webhook_subscription_created', last_webhook_event: 'customer.subscription.created', created_at: '2025-01-15T09:55:00Z' } 🎯 campaigns count: 2 [ { id: 'xxx', name: 'Campaign 1', status: 'active', created_at: '...' }, { id: 'yyy', name: 'Campaign 2', status: 'draft', created_at: '...' } ] 🧰 scraping_jobs count: 5 🪵 events (latest 20): 15 ⏱️ Done in 245ms
Key Fields to Check:
- Should be "completed" after signuponboarding_step
- Should be "active" if in trialtrial_status
- Should match Stripe subscriptioncurrent_plan
- Should match plan definitionplan_campaigns_limit
- Should exist if paid userstripe_subscription_id
- Shows last webhook resultbilling_sync_status
- Shows last Stripe webhook typelast_webhook_event
Fix Scripts
1. Reset User Onboarding
Script:
/scripts/reset-user-onboarding.js
Use Case: User stuck in onboarding, need to restart
node scripts/reset-user-onboarding.js user_2abc123xyz
What It Does:
- Sets
to "pending"onboarding_step - Clears trial dates
- Resets billing sync status
- Preserves Stripe data
2. Fix Billing State
Script:
/scripts/fix-user-billing-state.js
Use Case: Billing out of sync, plan limits wrong
node scripts/fix-user-billing-state.js user_2abc123xyz
What It Does:
- Fetches subscription from Stripe
- Updates plan in database
- Sets correct plan limits
- Syncs trial status
3. Complete Onboarding and Activate Plan
Script:
/scripts/complete-onboarding-and-activate-plan.js
Use Case: Manually complete onboarding for testing or fixing stuck user
# With plan selection node scripts/complete-onboarding-and-activate-plan.js user_2abc123xyz glow_up # Default to free plan node scripts/complete-onboarding-and-activate-plan.js user_2abc123xyz
What It Does:
- Sets
to "completed"onboarding_step - Activates trial (if plan has trial)
- Sets plan limits
- Triggers welcome email
4. Delete User Completely
Script:
/scripts/delete-user-completely.js
Use Case: Clean up test users, remove corrupted accounts
node scripts/delete-user-completely.js user_2abc123xyz
WARNING: Irreversible! Deletes:
- User profile
- All campaigns
- All scraping jobs
- All results
- All lists
5. Reset User to Fresh State
Script:
/scripts/reset-user-to-fresh-state.js
Use Case: Keep user but remove all data
node scripts/reset-user-to-fresh-state.js user_2abc123xyz
What It Does:
- Deletes campaigns, jobs, results
- Resets usage counters
- Keeps user profile and billing
- Resets onboarding to pending
Diagnostic Patterns
Pattern 1: Onboarding Stuck Diagnosis
# 1. Check user state node scripts/inspect-user-state.js --email user@example.com # 2. Look for key issues: # - onboarding_step != "completed" # - trial_status == "pending" # - stripe_subscription_id is null despite payment # 3. Check Stripe dashboard # - Does customer exist? # - Is subscription active? # - Was webhook delivered? # 4. Check application logs grep "STRIPE-WEBHOOK" logs/app.log | grep "user@example.com" # 5. Fix node scripts/complete-onboarding-and-activate-plan.js user_xxx glow_up
Pattern 2: Billing Sync Diagnosis
# 1. Check user state node scripts/inspect-user-state.js --user-id user_xxx # 2. Compare with Stripe # - current_plan in DB vs active subscription in Stripe # - plan_campaigns_limit in DB vs expected for plan # - billing_sync_status value # 3. Check last webhook # - last_webhook_event # - last_webhook_timestamp # - Look for errors in webhook delivery # 4. Manual sync curl -X POST http://localhost:3000/api/billing/sync-stripe \ -H "x-dev-auth: dev-bypass" \ -H "Content-Type: application/json" \ -d '{"userId":"user_xxx"}'
Pattern 3: Trial Not Activated
# 1. Check trial state node scripts/inspect-user-state.js --user-id user_xxx # 2. Verify expected state: # - trial_status should be "active" # - trial_start_date should be set # - trial_end_date should be ~7 days after start # - subscription_status should be "trialing" # 3. If wrong, check Stripe: # - Does subscription have trial_end? # - Is status "trialing"? # 4. Fix manually # Option A: Use API endpoint curl -X POST http://localhost:3000/api/debug/trial-testing \ -H "x-dev-auth: dev-bypass" \ -H "Content-Type: application/json" \ -d '{"userId":"user_xxx","action":"activate"}' # Option B: Use SQL (careful!) # UPDATE user_profiles SET # trial_status = 'active', # trial_start_date = NOW(), # trial_end_date = NOW() + INTERVAL '7 days', # onboarding_step = 'completed' # WHERE user_id = 'user_xxx';
Common Patterns
Pattern 1: Full User Diagnosis
# Complete diagnostic flow echo "=== 1. User State ===" && node scripts/inspect-user-state.js --email user@example.com && echo "" && echo "=== 2. Billing Status ===" && curl http://localhost:3000/api/billing/status \ -H "x-dev-user-id: user_xxx" \ -s | jq && echo "" && echo "=== 3. Campaigns ===" && curl http://localhost:3000/api/campaigns \ -H "x-dev-user-id: user_xxx" \ -s | jq
Pattern 2: User Cleanup for Testing
# Clean slate for testing node scripts/delete-user-completely.js user_test123 && # Create fresh test account in UI # Or use Clerk API to create user
Pattern 3: Bulk User Analysis
# List all users and their states node scripts/list-users.js # Find users with specific issue node scripts/list-users.js | grep "trial_status.*pending"
Troubleshooting Guide
Problem: User Can't Complete Onboarding
Symptoms:
- Stuck at step-1 or step-2
- "Continue" button doesn't work
- No error message
Diagnosis:
# 1. Check current step node scripts/inspect-user-state.js --email user@example.com # Look at onboarding_step # 2. Check browser console for errors # Ask user to check browser console # 3. Check API logs # Look for POST /api/onboarding/step-1 or step-2 errors
Solution:
# Option 1: Reset and retry node scripts/reset-user-onboarding.js user_xxx # Option 2: Force complete node scripts/complete-onboarding-and-activate-plan.js user_xxx free
Problem: User Paid But Shows Free Plan
Symptoms:
- Stripe shows active subscription
- Database shows
current_plan: 'free' - User can't access paid features
Diagnosis:
# 1. Check user state node scripts/inspect-user-state.js --user-id user_xxx # 2. Check Stripe subscription # - Copy stripe_customer_id from output # - Look up in Stripe dashboard # 3. Check webhook logs grep "STRIPE-WEBHOOK" logs/app.log | grep "user_xxx"
Solution:
# Option 1: Trigger billing sync curl -X POST http://localhost:3000/api/billing/sync-stripe \ -H "x-dev-auth: dev-bypass" \ -d '{"userId":"user_xxx"}' # Option 2: Use fix script node scripts/fix-user-billing-state.js user_xxx # Option 3: Manually update database (careful!) # Run SQL to set current_plan, plan limits, etc.
Problem: Plan Limits Not Enforced
Symptoms:
- User exceeds limits but no error
- Can create unlimited campaigns
is null or 0plan_campaigns_limit
Diagnosis:
# 1. Check plan limits node scripts/inspect-user-state.js --user-id user_xxx # Look at plan_campaigns_limit, plan_creators_limit # 2. Check subscription_plans table curl http://localhost:3000/api/admin/plans \ -H "x-dev-auth: dev-bypass" # 3. Verify plan enforcement is enabled grep "PLAN_VALIDATION_BYPASS" .env.local # Should NOT be set in production
Solution:
# 1. Update user's plan limits node scripts/fix-user-billing-state.js user_xxx # 2. Or manually via API curl -X POST http://localhost:3000/api/admin/users/set-plan \ -H "x-dev-auth: dev-bypass" \ -H "Content-Type: application/json" \ -d '{"userId":"user_xxx","plan":"glow_up"}'
Problem: User Not in Database But Exists in Clerk
Symptoms:
- User can log in to Clerk
- API returns "User not found"
returns nullgetUserProfile
Diagnosis:
# 1. Try to fetch user node scripts/inspect-user-state.js --user-id user_xxx # Will show "not found" # 2. Verify user exists in Clerk # Check Clerk dashboard # 3. Check Clerk webhook logs # Look for user.created webhook
Solution:
# Create user in database node scripts/test-auto-create-user.js user_xxx # Or trigger via API curl http://localhost:3000/api/profile \ -H "Authorization: Bearer $CLERK_TOKEN" # This should auto-create user profile
Related Files
- Primary diagnostic script/scripts/inspect-user-state.js
- Fix billing sync/scripts/fix-user-billing-state.js
- Reset onboarding/scripts/reset-user-onboarding.js
- Force complete/scripts/complete-onboarding-and-activate-plan.js
- Delete user/scripts/delete-user-completely.js
- Clean user data/scripts/reset-user-to-fresh-state.js
- List all users/scripts/list-users.js
- Find user by email/scripts/find-user-id.js
- User query helpers/lib/db/queries/user-queries.ts
- Check current auth state/app/api/debug/whoami/route.ts
Quick Reference
Diagnostic Commands:
# Check user by email node scripts/inspect-user-state.js --email user@example.com # Check user by ID node scripts/inspect-user-state.js --user-id user_xxx # List all users node scripts/list-users.js # Find user ID by email node scripts/find-user-id.js user@example.com
Fix Commands:
# Reset onboarding node scripts/reset-user-onboarding.js user_xxx # Fix billing node scripts/fix-user-billing-state.js user_xxx # Complete onboarding with plan node scripts/complete-onboarding-and-activate-plan.js user_xxx glow_up # Delete user node scripts/delete-user-completely.js user_xxx # Reset user data (keep profile) node scripts/reset-user-to-fresh-state.js user_xxx
API Endpoints:
# Check auth state curl http://localhost:3000/api/debug/whoami \ -H "x-dev-auth: dev-bypass" # Billing status curl http://localhost:3000/api/billing/status \ -H "x-dev-user-id: user_xxx" # Sync with Stripe curl -X POST http://localhost:3000/api/billing/sync-stripe \ -H "x-dev-auth: dev-bypass" \ -H "Content-Type: application/json" \ -d '{"userId":"user_xxx"}'
Best Practices
- Always Inspect Before Fixing - Run
firstinspect-user-state.js - Check Stripe Dashboard - Verify subscription state matches
- Review Logs - Look for webhook errors before manual fixes
- Backup First - Export user data before destructive operations
- Test in Dev - Try fixes on test users first
- Document - Note what you fixed and why
- Verify Fix - Re-run inspection after fixing