|
| 1 | +# Administrative Scripts |
| 2 | + |
| 3 | +This document describes the scripts available in the `scripts/` directory for database seeding, migrations, and maintenance tasks. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +``` |
| 8 | +scripts/ |
| 9 | +├── lib/ # Shared utilities |
| 10 | +│ ├── index.ts # Exports all utilities |
| 11 | +│ ├── supabase.ts # Supabase client setup |
| 12 | +│ ├── storage.ts # Storage upload utilities |
| 13 | +│ ├── images.ts # Image/asset upload utilities |
| 14 | +│ └── explore-config.ts # Explore page configuration |
| 15 | +├── seed-data/ # Seed data files |
| 16 | +│ └── ... |
| 17 | +├── seed.ts # Main seeding script |
| 18 | +├── migrate-assets.ts # Asset migration script |
| 19 | +└── cleanup-orphaned-tabs.ts # Orphaned tab cleanup |
| 20 | +``` |
| 21 | + |
| 22 | +## Running Scripts |
| 23 | + |
| 24 | +All scripts use `tsx` for TypeScript execution: |
| 25 | + |
| 26 | +```bash |
| 27 | +# Run with local .env |
| 28 | +tsx scripts/seed.ts |
| 29 | + |
| 30 | +# Run against production (prompts for credentials) |
| 31 | +tsx scripts/seed.ts --env production |
| 32 | + |
| 33 | +# Preview changes without executing |
| 34 | +tsx scripts/cleanup-orphaned-tabs.ts --dry-run |
| 35 | +``` |
| 36 | + |
| 37 | +## Environment Configuration |
| 38 | + |
| 39 | +### Local Development |
| 40 | + |
| 41 | +Scripts automatically load credentials from `.env` files in this order: |
| 42 | +1. `.env.local` |
| 43 | +2. `.env.development.local` |
| 44 | +3. `.env` |
| 45 | + |
| 46 | +Required variables: |
| 47 | +```bash |
| 48 | +NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co |
| 49 | +SUPABASE_SERVICE_KEY=your-service-key |
| 50 | +``` |
| 51 | + |
| 52 | +### Remote Environments |
| 53 | + |
| 54 | +Use the `--env` flag to target remote environments: |
| 55 | + |
| 56 | +```bash |
| 57 | +tsx scripts/seed.ts --env production |
| 58 | +``` |
| 59 | + |
| 60 | +This will prompt for credentials interactively: |
| 61 | +``` |
| 62 | +🌐 Targeting remote environment: production |
| 63 | +Please enter the Supabase credentials for this environment: |
| 64 | +
|
| 65 | +NEXT_PUBLIC_SUPABASE_URL: https://prod.supabase.co |
| 66 | +SUPABASE_SERVICE_KEY: **** |
| 67 | +``` |
| 68 | + |
| 69 | +## Available Scripts |
| 70 | + |
| 71 | +### seed.ts |
| 72 | + |
| 73 | +Seeds the database with initial data including navigation pages, explore page, and default configurations. |
| 74 | + |
| 75 | +```bash |
| 76 | +# Seed local database |
| 77 | +tsx scripts/seed.ts |
| 78 | + |
| 79 | +# Seed production |
| 80 | +tsx scripts/seed.ts --env production |
| 81 | +``` |
| 82 | + |
| 83 | +**What it does:** |
| 84 | +1. Creates `spaceRegistrations` entries for navigation pages (home, explore) |
| 85 | +2. Uploads navigation page configurations to storage |
| 86 | +3. Sets up default tab orders |
| 87 | +4. Uploads any required assets |
| 88 | + |
| 89 | +### migrate-assets.ts |
| 90 | + |
| 91 | +Migrates assets between storage buckets or environments. |
| 92 | + |
| 93 | +```bash |
| 94 | +tsx scripts/migrate-assets.ts |
| 95 | +tsx scripts/migrate-assets.ts --env production |
| 96 | +``` |
| 97 | + |
| 98 | +**Use cases:** |
| 99 | +- Moving assets from development to production |
| 100 | +- Reorganizing storage structure |
| 101 | +- Batch asset updates |
| 102 | + |
| 103 | +### cleanup-orphaned-tabs.ts |
| 104 | + |
| 105 | +Finds and deletes tab files that are not referenced in their space's `tabOrder`. |
| 106 | + |
| 107 | +```bash |
| 108 | +# Preview what would be deleted |
| 109 | +tsx scripts/cleanup-orphaned-tabs.ts --dry-run |
| 110 | + |
| 111 | +# Preview with debug output |
| 112 | +tsx scripts/cleanup-orphaned-tabs.ts --dry-run --debug |
| 113 | + |
| 114 | +# Actually delete orphaned tabs (local) |
| 115 | +tsx scripts/cleanup-orphaned-tabs.ts |
| 116 | + |
| 117 | +# Clean up production |
| 118 | +tsx scripts/cleanup-orphaned-tabs.ts --env production |
| 119 | +``` |
| 120 | + |
| 121 | +**Flags:** |
| 122 | +- `--dry-run` - Preview changes without deleting |
| 123 | +- `--debug` - Show detailed debug output |
| 124 | +- `--env <name>` - Target a specific environment |
| 125 | + |
| 126 | +**How it works:** |
| 127 | +1. Queries `spaceRegistrations` table for all space IDs |
| 128 | +2. For each space, reads the `tabOrder` file |
| 129 | +3. Lists all files in the space's `tabs/` folder |
| 130 | +4. Identifies tabs not in `tabOrder` (orphaned) |
| 131 | +5. Deletes orphaned tab files (unless `--dry-run`) |
| 132 | + |
| 133 | +**Output example:** |
| 134 | +``` |
| 135 | +🧹 Orphaned Tab Cleanup Script |
| 136 | +================================ |
| 137 | +
|
| 138 | +🔍 DRY RUN MODE - No files will be deleted |
| 139 | +
|
| 140 | +📂 Listing spaces... |
| 141 | + Found 150 space(s) |
| 142 | +
|
| 143 | +📁 Space: abc-123-def |
| 144 | + Tab order: [Home, Gallery] |
| 145 | + Tab files: [Home, Gallery, OldTab] |
| 146 | + Orphaned: [OldTab] |
| 147 | +
|
| 148 | +📊 Summary |
| 149 | +========== |
| 150 | + Spaces processed: 150 |
| 151 | + Spaces with orphans: 3 |
| 152 | + Total orphaned tabs: 5 |
| 153 | +
|
| 154 | +📋 Orphaned tabs to delete: |
| 155 | + - abc-123-def/tabs/OldTab |
| 156 | + - ... |
| 157 | +
|
| 158 | +⚠️ Dry run - no files were deleted |
| 159 | + Run without --dry-run to delete these files |
| 160 | +``` |
| 161 | + |
| 162 | +## Shared Utilities (scripts/lib/) |
| 163 | + |
| 164 | +### supabase.ts |
| 165 | + |
| 166 | +Provides Supabase client initialization with support for local and remote environments. |
| 167 | + |
| 168 | +```typescript |
| 169 | +import { supabase, initializeSupabase, targetEnv } from './lib'; |
| 170 | + |
| 171 | +// Must call before using supabase if using --env flag |
| 172 | +await initializeSupabase(); |
| 173 | + |
| 174 | +// Now safe to use |
| 175 | +const { data } = await supabase.from('spaces').select('*'); |
| 176 | +``` |
| 177 | + |
| 178 | +### storage.ts |
| 179 | + |
| 180 | +Utilities for uploading space configurations to storage. |
| 181 | + |
| 182 | +```typescript |
| 183 | +import { uploadPageConfig, createNavPageSpace, getSpaceId } from './lib'; |
| 184 | + |
| 185 | +// Create a navigation page space registration |
| 186 | +const spaceId = await createNavPageSpace('explore'); |
| 187 | + |
| 188 | +// Upload tab configurations |
| 189 | +await uploadPageConfig('explore', { |
| 190 | + defaultTab: 'Home', |
| 191 | + tabOrder: ['Home', 'Trending'], |
| 192 | + tabs: { |
| 193 | + Home: { /* SpaceConfig */ }, |
| 194 | + Trending: { /* SpaceConfig */ }, |
| 195 | + }, |
| 196 | +}); |
| 197 | +``` |
| 198 | + |
| 199 | +### images.ts |
| 200 | + |
| 201 | +Utilities for uploading images and assets. |
| 202 | + |
| 203 | +```typescript |
| 204 | +import { uploadToSupabaseStorage, ensureImagesBucket } from './lib'; |
| 205 | + |
| 206 | +// Ensure the images bucket exists |
| 207 | +await ensureImagesBucket(); |
| 208 | + |
| 209 | +// Upload an image |
| 210 | +const url = await uploadToSupabaseStorage( |
| 211 | + 'images', |
| 212 | + 'logos/community-logo.png', |
| 213 | + imageBuffer |
| 214 | +); |
| 215 | +``` |
| 216 | + |
| 217 | +## Creating New Scripts |
| 218 | + |
| 219 | +Template for a new administrative script: |
| 220 | + |
| 221 | +```typescript |
| 222 | +#!/usr/bin/env tsx |
| 223 | +/** |
| 224 | + * Script Description |
| 225 | + * |
| 226 | + * Usage: |
| 227 | + * tsx scripts/my-script.ts |
| 228 | + * tsx scripts/my-script.ts --env production |
| 229 | + * tsx scripts/my-script.ts --dry-run |
| 230 | + */ |
| 231 | + |
| 232 | +import { supabase, initializeSupabase, targetEnv } from './lib'; |
| 233 | + |
| 234 | +// Parse CLI flags |
| 235 | +const args = process.argv.slice(2); |
| 236 | +const flags = { |
| 237 | + dryRun: args.includes('--dry-run'), |
| 238 | + debug: args.includes('--debug'), |
| 239 | +}; |
| 240 | + |
| 241 | +async function main() { |
| 242 | + console.log('🚀 My Script'); |
| 243 | + console.log('============\n'); |
| 244 | + |
| 245 | + if (flags.dryRun) { |
| 246 | + console.log('🔍 DRY RUN MODE - No changes will be made\n'); |
| 247 | + } |
| 248 | + |
| 249 | + if (targetEnv) { |
| 250 | + console.log(`🌐 Target environment: ${targetEnv}\n`); |
| 251 | + } |
| 252 | + |
| 253 | + // Initialize Supabase (required for --env flag) |
| 254 | + await initializeSupabase(); |
| 255 | + |
| 256 | + // Your script logic here |
| 257 | + // ... |
| 258 | + |
| 259 | + console.log('\n✨ Done!'); |
| 260 | +} |
| 261 | + |
| 262 | +main().catch((error) => { |
| 263 | + console.error('Fatal error:', error); |
| 264 | + process.exit(1); |
| 265 | +}); |
| 266 | +``` |
| 267 | + |
| 268 | +## Best Practices |
| 269 | + |
| 270 | +1. **Always use `--dry-run` first** - Preview changes before executing destructive operations |
| 271 | + |
| 272 | +2. **Use `--debug` for troubleshooting** - When scripts don't behave as expected |
| 273 | + |
| 274 | +3. **Back up before production runs** - Especially for cleanup/migration scripts |
| 275 | + |
| 276 | +4. **Test locally first** - Run against local Supabase before production |
| 277 | + |
| 278 | +5. **Check output carefully** - Review the summary before confirming destructive actions |
| 279 | + |
| 280 | +## Troubleshooting |
| 281 | + |
| 282 | +### "Missing required environment variables" |
| 283 | + |
| 284 | +Ensure your `.env` file contains: |
| 285 | +```bash |
| 286 | +NEXT_PUBLIC_SUPABASE_URL=... |
| 287 | +SUPABASE_SERVICE_KEY=... |
| 288 | +``` |
| 289 | + |
| 290 | +### "Error listing spaces from database" |
| 291 | + |
| 292 | +Check that: |
| 293 | +- Your Supabase credentials are correct |
| 294 | +- The `spaceRegistrations` table exists |
| 295 | +- Your service key has appropriate permissions |
| 296 | + |
| 297 | +### Script hangs on credential prompt |
| 298 | + |
| 299 | +When using `--env`, the script waits for interactive input. Make sure you're running in a terminal that supports input. |
| 300 | + |
| 301 | +## Related Documentation |
| 302 | + |
| 303 | +- [Supabase Integration](../INTEGRATIONS/SUPABASE.md) - Database and storage details |
| 304 | +- [Tab Operations](../SYSTEMS/SPACES/TAB_OPERATIONS.md) - How tabs work |
| 305 | +- [Development Guide](../DEVELOPMENT/DEVELOPMENT_GUIDE.md) - Local setup |
0 commit comments