scripts/takeout/README.md
These scripts help manage the sync between Stripe subscriptions and GitHub team access for Tamagui's takeout products (Tamagui Pro, Takeout Stack, Team Seats).
team_slug: 'early-access'early-access teamprod_RlRd2DVrG0frHe) - includes takeout accessprod_NzLEazaqBgoKnC) - standalone takeoutprod_Rxu0x7jR0nWJSv) - team subscriptionscheck-discord-sync.tsPurpose: Audit Discord Takeout role vs active Stripe subscriptions
npx tsx scripts/takeout/check-discord-sync.ts
Shows:
Creates: tmp/discord-users-to-remove-*.json with users to remove
Use when: You want to audit Discord access or find stale Discord users
remove-discord-users.tsPurpose: Remove Discord Takeout role from users based on analysis file
# Dry run first
npx tsx scripts/takeout/remove-discord-users.ts tmp/discord-users-to-remove-*.json --dry-run
# Then actually remove
npx tsx scripts/takeout/remove-discord-users.ts tmp/discord-users-to-remove-*.json
Use when: After reviewing the discord-users-to-remove file and confirming it's safe
check-subscription-sync.tsPurpose: Audit sync between Stripe subscriptions and GitHub team membership
npx tsx scripts/takeout/check-subscription-sync.ts
Shows:
Use when: You suspect sync issues or want to verify everything is working
check-webhook-events.tsPurpose: View recent Stripe webhook events to debug issues
npx tsx scripts/takeout/check-webhook-events.ts [--limit 100]
Shows:
Use when: Debugging webhook issues or verifying webhooks are being received
analyze-stale-claims.tsPurpose: Find claims for cancelled subscriptions that need cleanup
npx tsx scripts/takeout/analyze-stale-claims.ts
Creates files in /tmp/:
active-subscriptions-*.json - All active Stripe subscription IDsvalid-claims-*.json - Claims that should be keptstale-claims-*.json - Claims to clean up (subscriptions cancelled)cleanup-summary-*.txt - Summary reportUse when: You want to identify and review stale claims before cleanup
cleanup-stale-claims.tsPurpose: Clean up stale claims (mark as unclaimed)
# Dry run first
npx tsx scripts/takeout/cleanup-stale-claims.ts tmp/stale-claims-*.json --dry-run
# Then actually clean up
npx tsx scripts/takeout/cleanup-stale-claims.ts tmp/stale-claims-*.json
Use when: After reviewing the stale claims file and confirming it's safe to clean up
Location: code/tamagui.dev/features/api/unclaimProduct.ts
Problem: When subscriptions were cancelled, the webhook tried to update claims but was missing the WHERE clause:
// BEFORE (BROKEN)
await supabaseAdmin.from('claims').update({
unclaimed_at: Number(new Date()).toString(),
})
// This tried to update ALL claims in the database!
Fix:
// AFTER (FIXED)
await supabaseAdmin
.from('claims')
.update({
unclaimed_at: new Date().toISOString(),
})
.eq('id', claim.id) // ← Added WHERE clause
Additional fixes:
await before unclaimRepoAccess() callteam_slugMigrated from direct repo collaborator access to GitHub team-based access:
Before:
repository_name: 'takeout' or 'unistack'After:
early-access GitHub teamteam_slug: 'early-access'Migration Stats:
team_slugAll scripts need these environment variables (automatically loaded from code/tamagui.dev/.env):
NEXT_PUBLIC_SUPABASE_URL - Supabase project URLSUPABASE_SERVICE_ROLE_KEY - Supabase service keySTRIPE_SECRET_KEY - Stripe secret keyGITHUB_ADMIN_TOKEN - GitHub PAT with org/team admin accessDISCORD_BOT_TOKEN - Discord bot token (for Discord sync scripts)npx tsx scripts/takeout/check-subscription-sync.ts
npx tsx scripts/takeout/check-discord-sync.ts
npx tsx scripts/takeout/check-webhook-events.ts
# 1. Analyze
npx tsx scripts/takeout/analyze-stale-claims.ts
# 2. Review the files in /tmp/
# 3. Clean up
npx tsx scripts/takeout/cleanup-stale-claims.ts tmp/stale-claims-*.json
# 1. Check Discord sync
npx tsx scripts/takeout/check-discord-sync.ts
# 2. Review tmp/discord-users-to-remove-*.json
# 3. Remove users with cancelled subscriptions
npx tsx scripts/takeout/remove-discord-users.ts tmp/discord-users-to-remove-*.json
Some subscriptions may not have claims if:
Solution: Users can claim access by visiting their account page on tamagui.dev
If active subscribers aren't in the team:
check-subscription-sync.ts to identify missing userscheck-webhook-events.tsIf claims aren't being marked as unclaimed:
unclaimProduct.ts is deployedcode/tamagui.dev/app/api/stripe/webhook+api.ts - Stripe webhook handlercode/tamagui.dev/features/api/unclaimProduct.ts - Unclaim logic (GitHub + Discord removal)code/tamagui.dev/features/user/claim-product.ts - Claim creation logiccode/tamagui.dev/features/github/helpers.ts - GitHub team managementcode/tamagui.dev/features/discord/helpers.ts - Discord client and constantscode/tamagui.dev/app/api/discord/channel+api.ts - Discord channel managementclaims, discord_invites, subscriptions