# Schema Validation Setup Guide This guide explains how to set up and use the automated schema validation tools to prevent field mismatches in the submission pipeline. ## Overview The validation system consists of three layers: 1. **Pre-migration Script** - Quick validation before deploying migrations 2. **Integration Tests** - Comprehensive Playwright tests for CI/CD 3. **GitHub Actions** - Automated checks on every pull request ## Quick Start ### 1. Add NPM Scripts Add these scripts to your `package.json`: ```json { "scripts": { "validate-schema": "tsx scripts/validate-schema.ts", "test:schema": "playwright test schema-validation", "test:schema:ui": "playwright test schema-validation --ui", "pre-migrate": "npm run validate-schema" } } ``` ### 2. Environment Variables Create a `.env.test` file: ```env SUPABASE_SERVICE_ROLE_KEY=your_service_role_key_here ``` **⚠️ Important**: Never commit this file! Add it to `.gitignore`: ```gitignore .env.test .env.local ``` ### 3. Install Dependencies If not already installed: ```bash npm install --save-dev @supabase/supabase-js @playwright/test tsx ``` ## Using the Validation Tools ### Pre-Migration Validation Script **When to use**: Before applying any database migration **Run manually:** ```bash npm run validate-schema ``` **What it checks:** - ✅ Submission tables match main tables - ✅ Version tables have all required fields - ✅ Critical fields are correct (e.g., `category` vs `ride_type`) - ✅ Database functions exist and are accessible **Example output:** ``` 🔍 Starting schema validation... Submission Tables: ──────────────────────────────────────────────────────────────────────────────── ✅ Parks: submission table matches main table ✅ Rides: submission table matches main table ✅ Companies: submission table matches main table ✅ Ride Models: submission table matches main table Version Tables: ──────────────────────────────────────────────────────────────────────────────── ✅ Parks: version table has all fields ✅ Rides: version table has all fields ✅ Companies: version table has all fields ✅ Ride Models: version table has all fields Critical Fields: ──────────────────────────────────────────────────────────────────────────────── ✅ rides table does NOT have ride_type column ✅ rides table has category column ✅ ride_models has both category and ride_type Functions: ──────────────────────────────────────────────────────────────────────────────── ✅ create_entity_from_submission exists and is accessible ✅ update_entity_from_submission exists and is accessible ✅ process_approval_transaction exists and is accessible ════════════════════════════════════════════════════════════════════════════════ Total: 15 passed, 0 failed ════════════════════════════════════════════════════════════════════════════════ ✅ All schema validations passed. Safe to deploy. ``` ### Integration Tests **When to use**: In CI/CD, before merging PRs, after major changes **Run all tests:** ```bash npm run test:schema ``` **Run in UI mode (for debugging):** ```bash npm run test:schema:ui ``` **Run specific test suite:** ```bash npx playwright test schema-validation --grep "Entity Tables" ``` **What it tests:** - All pre-migration script checks PLUS: - Field-by-field data type comparison - NOT NULL constraint validation - Foreign key existence checks - Known field name variations (e.g., `height_requirement_cm` vs `height_requirement`) ### GitHub Actions (Automated) **Automatically runs on:** - Every pull request that touches: - `supabase/migrations/**` - `src/lib/moderation/**` - `supabase/functions/**` - Pushes to `main` or `develop` branches - Manual workflow dispatch **What it does:** 1. Runs validation script 2. Runs integration tests 3. Checks for breaking migration patterns 4. Validates migration file naming 5. Comments on PRs with helpful guidance if tests fail ## Workflow Examples ### Before Creating a Migration ```bash # 1. Make schema changes locally # 2. Validate before creating migration npm run validate-schema # 3. If validation passes, create migration supabase db diff -f add_new_field # 4. Run validation again npm run validate-schema # 5. Commit and push git add . git commit -m "Add new field to rides table" git push ``` ### After Modifying Entity Schemas ```bash # 1. Modified rides table schema # 2. Run full test suite npm run test:schema # 3. Check specific validation npx playwright test schema-validation --grep "rides" # 4. Fix any issues # 5. Re-run tests npm run test:schema ``` ### During Code Review **PR Author:** 1. Ensure all validation tests pass locally 2. Push changes 3. Wait for GitHub Actions to complete 4. Address any automated feedback **Reviewer:** 1. Check that GitHub Actions passed 2. Review schema changes in migrations 3. Verify documentation was updated 4. Approve if all checks pass ## Common Issues and Solutions ### Issue: "Missing fields" Error **Symptom:** ``` ❌ Rides: submission table matches main table └─ Missing fields: category ``` **Cause**: Field was added to main table but not submission table **Solution:** ```sql -- In your migration file ALTER TABLE ride_submissions ADD COLUMN category TEXT NOT NULL; ``` ### Issue: "Type mismatch" Error **Symptom:** ``` ❌ Rides: submission table matches main table └─ Type mismatches: max_speed_kmh: main=numeric, submission=integer ``` **Cause**: Data types don't match between tables **Solution:** ```sql -- In your migration file ALTER TABLE ride_submissions ALTER COLUMN max_speed_kmh TYPE NUMERIC USING max_speed_kmh::numeric; ``` ### Issue: "Column does not exist" in Production **Symptom**: Approval fails with `column "category" does not exist` **Immediate action:** 1. Run validation script to identify issue 2. Create emergency migration to add missing field 3. Deploy immediately 4. Update functions if needed **Prevention**: Always run validation before deploying ### Issue: Tests Pass Locally but Fail in CI **Possible causes:** - Different database state in CI vs local - Missing environment variables - Outdated schema in test database **Solution:** ```bash # Pull latest schema supabase db pull # Reset local database supabase db reset # Re-run tests npm run test:schema ``` ## Best Practices ### ✅ Do's - ✅ Run validation script before every migration - ✅ Run integration tests before merging PRs - ✅ Update all three tables when adding fields (main, submission, version) - ✅ Document field name variations in tests - ✅ Check GitHub Actions results before merging - ✅ Keep SCHEMA_REFERENCE.md up to date ### ❌ Don'ts - ❌ Don't skip validation "because it's a small change" - ❌ Don't add fields to only main tables - ❌ Don't ignore failing tests - ❌ Don't bypass CI checks - ❌ Don't commit service role keys - ❌ Don't modify submission pipeline functions without testing ## Continuous Integration Setup ### GitHub Secrets Add to your repository secrets: ``` SUPABASE_SERVICE_ROLE_KEY=your_service_role_key_here ``` **Steps:** 1. Go to repository Settings → Secrets and variables → Actions 2. Click "New repository secret" 3. Name: `SUPABASE_SERVICE_ROLE_KEY` 4. Value: Your service role key from Supabase dashboard 5. Save ### Branch Protection Rules Recommended settings: ``` Branch: main ✓ Require status checks to pass before merging ✓ validate-schema (Schema Validation) ✓ migration-safety-check (Migration Safety Check) ✓ Require branches to be up to date before merging ``` ## Troubleshooting ### Script Won't Run **Error:** `tsx: command not found` **Solution:** ```bash npm install -g tsx # or npx tsx scripts/validate-schema.ts ``` ### Authentication Errors **Error:** `Invalid API key` **Solution:** 1. Check `.env.test` has correct service role key 2. Verify key has not expired 3. Ensure environment variable is loaded: ```bash source .env.test npm run validate-schema ``` ### Tests Timeout **Error:** Tests timeout after 30 seconds **Solution:** ```bash # Increase timeout npx playwright test schema-validation --timeout=60000 ``` ## Maintenance ### Adding New Entity Types When adding a new entity type (e.g., `events`): 1. **Update validation script:** ```typescript // In scripts/validate-schema.ts await validateSubmissionTable('events', 'event_submissions', 'Events'); await validateVersionTable('events', 'event_versions', 'Events'); ``` 2. **Update integration tests:** ```typescript // In tests/integration/schema-validation.test.ts test('events: submission table matches main table schema', async () => { // Add test logic }); ``` 3. **Update documentation:** - `docs/submission-pipeline/SCHEMA_REFERENCE.md` - This file (`VALIDATION_SETUP.md`) ### Updating Field Mappings When version tables use different field names: ```typescript // In both script and tests const fieldMapping: { [key: string]: string } = { 'new_main_field': 'version_field_name', }; ``` ## Related Documentation - [Schema Reference](./SCHEMA_REFERENCE.md) - Complete field mappings - [Integration Tests README](../../tests/integration/README.md) - Detailed test documentation - [Submission Pipeline](./README.md) - Pipeline overview - [Versioning System](../versioning/README.md) - Version table details ## Support **Questions?** Check the documentation above or review existing migration files. **Found a bug in validation?** Open an issue with: - Expected behavior - Actual behavior - Validation script output - Database schema snippets