@weirdfingers/baseboards 0.9.6 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +560 -469
- package/dist/index.js.map +1 -1
- package/package.json +2 -5
- package/templates/README.md +0 -122
- package/templates/api/.env.example +0 -65
- package/templates/api/ARTIFACT_RESOLUTION_GUIDE.md +0 -148
- package/templates/api/Dockerfile +0 -32
- package/templates/api/README.md +0 -264
- package/templates/api/alembic/env.py +0 -114
- package/templates/api/alembic/script.py.mako +0 -28
- package/templates/api/alembic/versions/20250101_000000_initial_schema.py +0 -506
- package/templates/api/alembic/versions/20251022_174729_remove_provider_name_from_generations.py +0 -75
- package/templates/api/alembic/versions/20251023_165852_switch_to_declarative_base_and_mapping.py +0 -467
- package/templates/api/alembic/versions/20251202_000000_add_artifact_lineage.py +0 -134
- package/templates/api/alembic/versions/2025925_62735_add_seed_data_for_default_tenant.py +0 -88
- package/templates/api/alembic.ini +0 -36
- package/templates/api/config/generators.yaml +0 -237
- package/templates/api/config/storage_config.yaml +0 -26
- package/templates/api/docs/ADDING_GENERATORS.md +0 -409
- package/templates/api/docs/GENERATORS_API.md +0 -502
- package/templates/api/docs/MIGRATIONS.md +0 -472
- package/templates/api/docs/TESTING_LIVE_APIS.md +0 -417
- package/templates/api/docs/storage_providers.md +0 -337
- package/templates/api/pyproject.toml +0 -205
- package/templates/api/src/boards/__init__.py +0 -10
- package/templates/api/src/boards/api/app.py +0 -172
- package/templates/api/src/boards/api/auth.py +0 -75
- package/templates/api/src/boards/api/endpoints/__init__.py +0 -3
- package/templates/api/src/boards/api/endpoints/jobs.py +0 -76
- package/templates/api/src/boards/api/endpoints/setup.py +0 -505
- package/templates/api/src/boards/api/endpoints/sse.py +0 -129
- package/templates/api/src/boards/api/endpoints/storage.py +0 -155
- package/templates/api/src/boards/api/endpoints/tenant_registration.py +0 -296
- package/templates/api/src/boards/api/endpoints/uploads.py +0 -149
- package/templates/api/src/boards/api/endpoints/webhooks.py +0 -13
- package/templates/api/src/boards/auth/__init__.py +0 -15
- package/templates/api/src/boards/auth/adapters/__init__.py +0 -27
- package/templates/api/src/boards/auth/adapters/auth0.py +0 -220
- package/templates/api/src/boards/auth/adapters/base.py +0 -73
- package/templates/api/src/boards/auth/adapters/clerk.py +0 -172
- package/templates/api/src/boards/auth/adapters/jwt.py +0 -122
- package/templates/api/src/boards/auth/adapters/none.py +0 -102
- package/templates/api/src/boards/auth/adapters/oidc.py +0 -284
- package/templates/api/src/boards/auth/adapters/supabase.py +0 -110
- package/templates/api/src/boards/auth/context.py +0 -35
- package/templates/api/src/boards/auth/factory.py +0 -129
- package/templates/api/src/boards/auth/middleware.py +0 -221
- package/templates/api/src/boards/auth/provisioning.py +0 -129
- package/templates/api/src/boards/auth/tenant_extraction.py +0 -278
- package/templates/api/src/boards/cli.py +0 -354
- package/templates/api/src/boards/config.py +0 -131
- package/templates/api/src/boards/database/__init__.py +0 -7
- package/templates/api/src/boards/database/cli.py +0 -110
- package/templates/api/src/boards/database/connection.py +0 -292
- package/templates/api/src/boards/database/models.py +0 -19
- package/templates/api/src/boards/database/seed_data.py +0 -182
- package/templates/api/src/boards/dbmodels/__init__.py +0 -441
- package/templates/api/src/boards/generators/__init__.py +0 -57
- package/templates/api/src/boards/generators/artifact_resolution.py +0 -405
- package/templates/api/src/boards/generators/artifacts.py +0 -53
- package/templates/api/src/boards/generators/base.py +0 -144
- package/templates/api/src/boards/generators/implementations/__init__.py +0 -14
- package/templates/api/src/boards/generators/implementations/fal/__init__.py +0 -25
- package/templates/api/src/boards/generators/implementations/fal/audio/__init__.py +0 -23
- package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_music_generation.py +0 -171
- package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_sound_effect_generation.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_text_to_speech.py +0 -176
- package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_tts_turbo.py +0 -195
- package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_sound_effects_v2.py +0 -194
- package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_tts_eleven_v3.py +0 -209
- package/templates/api/src/boards/generators/implementations/fal/audio/fal_elevenlabs_tts_turbo_v2_5.py +0 -206
- package/templates/api/src/boards/generators/implementations/fal/audio/fal_minimax_speech_26_hd.py +0 -237
- package/templates/api/src/boards/generators/implementations/fal/audio/minimax_music_v2.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/audio/minimax_speech_2_6_turbo.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/image/__init__.py +0 -63
- package/templates/api/src/boards/generators/implementations/fal/image/bytedance_seedream_v45_edit.py +0 -219
- package/templates/api/src/boards/generators/implementations/fal/image/clarity_upscaler.py +0 -220
- package/templates/api/src/boards/generators/implementations/fal/image/crystal_upscaler.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/image/fal_ideogram_character.py +0 -227
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2.py +0 -203
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_edit.py +0 -230
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro.py +0 -204
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro_edit.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_kontext.py +0 -216
- package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_ultra.py +0 -197
- package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image.py +0 -177
- package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image_edit.py +0 -208
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_15_edit.py +0 -216
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_5.py +0 -177
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_edit_image.py +0 -182
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_mini.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/image/ideogram_character_edit.py +0 -299
- package/templates/api/src/boards/generators/implementations/fal/image/ideogram_v2.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview.py +0 -191
- package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview_fast.py +0 -179
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana.py +0 -183
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_edit.py +0 -212
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro.py +0 -179
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro_edit.py +0 -226
- package/templates/api/src/boards/generators/implementations/fal/image/qwen_image.py +0 -249
- package/templates/api/src/boards/generators/implementations/fal/image/qwen_image_edit.py +0 -244
- package/templates/api/src/boards/generators/implementations/fal/image/reve_edit.py +0 -178
- package/templates/api/src/boards/generators/implementations/fal/image/reve_text_to_image.py +0 -155
- package/templates/api/src/boards/generators/implementations/fal/image/seedream_v45_text_to_image.py +0 -180
- package/templates/api/src/boards/generators/implementations/fal/utils.py +0 -61
- package/templates/api/src/boards/generators/implementations/fal/video/__init__.py +0 -77
- package/templates/api/src/boards/generators/implementations/fal/video/bytedance_seedance_v1_pro_text_to_video.py +0 -209
- package/templates/api/src/boards/generators/implementations/fal/video/creatify_lipsync.py +0 -161
- package/templates/api/src/boards/generators/implementations/fal/video/fal_bytedance_seedance_v1_pro_image_to_video.py +0 -222
- package/templates/api/src/boards/generators/implementations/fal/video/fal_minimax_hailuo_02_standard_text_to_video.py +0 -152
- package/templates/api/src/boards/generators/implementations/fal/video/fal_pixverse_lipsync.py +0 -197
- package/templates/api/src/boards/generators/implementations/fal/video/fal_sora_2_text_to_video.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/video/infinitalk.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_pro.py +0 -168
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_standard.py +0 -159
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_image_to_video.py +0 -175
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_text_to_video.py +0 -168
- package/templates/api/src/boards/generators/implementations/fal/video/minimax_hailuo_2_3_pro_image_to_video.py +0 -153
- package/templates/api/src/boards/generators/implementations/fal/video/sora2_image_to_video.py +0 -172
- package/templates/api/src/boards/generators/implementations/fal/video/sora_2_image_to_video_pro.py +0 -175
- package/templates/api/src/boards/generators/implementations/fal/video/sora_2_text_to_video_pro.py +0 -163
- package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2_pro.py +0 -155
- package/templates/api/src/boards/generators/implementations/fal/video/veed_fabric_1_0.py +0 -180
- package/templates/api/src/boards/generators/implementations/fal/video/veed_lipsync.py +0 -174
- package/templates/api/src/boards/generators/implementations/fal/video/veo3.py +0 -194
- package/templates/api/src/boards/generators/implementations/fal/video/veo31.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast_image_to_video.py +0 -191
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_first_last_frame_to_video.py +0 -187
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_image_to_video.py +0 -183
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_reference_to_video.py +0 -172
- package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_image_to_video.py +0 -212
- package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_text_to_video.py +0 -208
- package/templates/api/src/boards/generators/implementations/fal/video/wan_pro_image_to_video.py +0 -158
- package/templates/api/src/boards/generators/implementations/kie/__init__.py +0 -11
- package/templates/api/src/boards/generators/implementations/kie/base.py +0 -316
- package/templates/api/src/boards/generators/implementations/kie/image/__init__.py +0 -3
- package/templates/api/src/boards/generators/implementations/kie/image/nano_banana_edit.py +0 -190
- package/templates/api/src/boards/generators/implementations/kie/utils.py +0 -98
- package/templates/api/src/boards/generators/implementations/kie/video/__init__.py +0 -8
- package/templates/api/src/boards/generators/implementations/kie/video/veo3.py +0 -161
- package/templates/api/src/boards/generators/implementations/openai/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/audio/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/audio/whisper.py +0 -69
- package/templates/api/src/boards/generators/implementations/openai/image/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/image/dalle3.py +0 -96
- package/templates/api/src/boards/generators/implementations/replicate/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/image/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/image/flux_pro.py +0 -88
- package/templates/api/src/boards/generators/implementations/replicate/video/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/video/lipsync.py +0 -73
- package/templates/api/src/boards/generators/loader.py +0 -253
- package/templates/api/src/boards/generators/registry.py +0 -114
- package/templates/api/src/boards/generators/resolution.py +0 -632
- package/templates/api/src/boards/generators/testmods/class_gen.py +0 -34
- package/templates/api/src/boards/generators/testmods/import_side_effect.py +0 -35
- package/templates/api/src/boards/graphql/__init__.py +0 -7
- package/templates/api/src/boards/graphql/access_control.py +0 -136
- package/templates/api/src/boards/graphql/mutations/root.py +0 -148
- package/templates/api/src/boards/graphql/queries/root.py +0 -116
- package/templates/api/src/boards/graphql/resolvers/__init__.py +0 -8
- package/templates/api/src/boards/graphql/resolvers/auth.py +0 -12
- package/templates/api/src/boards/graphql/resolvers/board.py +0 -1053
- package/templates/api/src/boards/graphql/resolvers/generation.py +0 -666
- package/templates/api/src/boards/graphql/resolvers/generator.py +0 -50
- package/templates/api/src/boards/graphql/resolvers/lineage.py +0 -381
- package/templates/api/src/boards/graphql/resolvers/upload.py +0 -463
- package/templates/api/src/boards/graphql/resolvers/user.py +0 -25
- package/templates/api/src/boards/graphql/schema.py +0 -81
- package/templates/api/src/boards/graphql/types/board.py +0 -102
- package/templates/api/src/boards/graphql/types/generation.py +0 -166
- package/templates/api/src/boards/graphql/types/generator.py +0 -17
- package/templates/api/src/boards/graphql/types/user.py +0 -47
- package/templates/api/src/boards/jobs/repository.py +0 -153
- package/templates/api/src/boards/logging.py +0 -195
- package/templates/api/src/boards/middleware.py +0 -339
- package/templates/api/src/boards/progress/__init__.py +0 -4
- package/templates/api/src/boards/progress/models.py +0 -25
- package/templates/api/src/boards/progress/publisher.py +0 -64
- package/templates/api/src/boards/py.typed +0 -0
- package/templates/api/src/boards/redis_pool.py +0 -118
- package/templates/api/src/boards/storage/__init__.py +0 -52
- package/templates/api/src/boards/storage/base.py +0 -363
- package/templates/api/src/boards/storage/config.py +0 -187
- package/templates/api/src/boards/storage/factory.py +0 -288
- package/templates/api/src/boards/storage/implementations/__init__.py +0 -27
- package/templates/api/src/boards/storage/implementations/gcs.py +0 -340
- package/templates/api/src/boards/storage/implementations/local.py +0 -201
- package/templates/api/src/boards/storage/implementations/s3.py +0 -294
- package/templates/api/src/boards/storage/implementations/supabase.py +0 -218
- package/templates/api/src/boards/tenant_isolation.py +0 -446
- package/templates/api/src/boards/validation.py +0 -262
- package/templates/api/src/boards/workers/__init__.py +0 -1
- package/templates/api/src/boards/workers/actors.py +0 -274
- package/templates/api/src/boards/workers/cli.py +0 -125
- package/templates/api/src/boards/workers/context.py +0 -348
- package/templates/api/src/boards/workers/middleware.py +0 -58
- package/templates/api/src/py.typed +0 -0
- package/templates/compose.web.yaml +0 -35
- package/templates/compose.yaml +0 -116
- package/templates/docker/env.example +0 -23
- package/templates/web/.env.example +0 -28
- package/templates/web/Dockerfile +0 -51
- package/templates/web/components.json +0 -22
- package/templates/web/imageLoader.js +0 -18
- package/templates/web/next-env.d.ts +0 -5
- package/templates/web/next.config.js +0 -36
- package/templates/web/package.json +0 -41
- package/templates/web/postcss.config.mjs +0 -7
- package/templates/web/public/favicon.ico +0 -0
- package/templates/web/src/app/boards/[boardId]/page.tsx +0 -353
- package/templates/web/src/app/globals.css +0 -123
- package/templates/web/src/app/layout.tsx +0 -31
- package/templates/web/src/app/lineage/[generationId]/page.tsx +0 -235
- package/templates/web/src/app/page.tsx +0 -35
- package/templates/web/src/app/providers.tsx +0 -18
- package/templates/web/src/components/boards/ArtifactInputSlots.tsx +0 -206
- package/templates/web/src/components/boards/ArtifactPreview.tsx +0 -466
- package/templates/web/src/components/boards/GenerationGrid.tsx +0 -282
- package/templates/web/src/components/boards/GenerationInput.tsx +0 -370
- package/templates/web/src/components/boards/GeneratorSelector.tsx +0 -272
- package/templates/web/src/components/boards/UploadArtifact.tsx +0 -563
- package/templates/web/src/components/header.tsx +0 -32
- package/templates/web/src/components/theme-provider.tsx +0 -10
- package/templates/web/src/components/theme-toggle.tsx +0 -75
- package/templates/web/src/components/ui/alert-dialog.tsx +0 -157
- package/templates/web/src/components/ui/button.tsx +0 -58
- package/templates/web/src/components/ui/card.tsx +0 -92
- package/templates/web/src/components/ui/dropdown-menu.tsx +0 -200
- package/templates/web/src/components/ui/navigation-menu.tsx +0 -168
- package/templates/web/src/components/ui/toast.tsx +0 -128
- package/templates/web/src/components/ui/toaster.tsx +0 -35
- package/templates/web/src/components/ui/use-toast.ts +0 -187
- package/templates/web/src/hooks/useGeneratorMRU.ts +0 -57
- package/templates/web/src/lib/utils.ts +0 -6
- package/templates/web/tsconfig.json +0 -41
|
@@ -1,472 +0,0 @@
|
|
|
1
|
-
# Database Migrations Guide
|
|
2
|
-
|
|
3
|
-
This guide covers the complete workflow for making database schema changes in the Boards backend using our SQL DDL-first migration system.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The Boards backend uses a **schema-first approach** where:
|
|
8
|
-
|
|
9
|
-
1. **SQL DDL files** are the single source of truth for database schema
|
|
10
|
-
2. **SQLAlchemy models** are auto-generated from the schema
|
|
11
|
-
3. **Migration scripts** are auto-generated by comparing schemas
|
|
12
|
-
4. **Database changes** are applied via generated migrations
|
|
13
|
-
|
|
14
|
-
## Quick Reference
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
# Complete workflow
|
|
18
|
-
vim migrations/schemas/002_new_feature.sql # 1. Edit schema
|
|
19
|
-
python scripts/generate_migration.py --name new_feature # 2. Generate migration
|
|
20
|
-
psql boards_dev < migrations/generated/*_new_feature_up.sql # 3. Apply migration
|
|
21
|
-
python scripts/generate_models.py # 4. Regenerate models
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Detailed Workflow
|
|
25
|
-
|
|
26
|
-
### Step 1: Modify the SQL DDL Schema
|
|
27
|
-
|
|
28
|
-
Schema files are stored in `migrations/schemas/` and processed in alphabetical order.
|
|
29
|
-
|
|
30
|
-
#### Creating a New Schema File
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
cd packages/backend
|
|
34
|
-
|
|
35
|
-
# Create new schema file with incremental numbering
|
|
36
|
-
vim migrations/schemas/002_add_user_preferences.sql
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
#### Schema File Example
|
|
40
|
-
|
|
41
|
-
```sql
|
|
42
|
-
-- 002_add_user_preferences.sql
|
|
43
|
-
-- Add user preferences and notification settings
|
|
44
|
-
|
|
45
|
-
-- New table for user preferences
|
|
46
|
-
CREATE TABLE user_preferences (
|
|
47
|
-
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
48
|
-
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
49
|
-
theme VARCHAR(20) DEFAULT 'light' CHECK (theme IN ('light', 'dark')),
|
|
50
|
-
timezone VARCHAR(50) DEFAULT 'UTC',
|
|
51
|
-
email_notifications BOOLEAN DEFAULT TRUE,
|
|
52
|
-
push_notifications BOOLEAN DEFAULT FALSE,
|
|
53
|
-
metadata JSONB DEFAULT '{}',
|
|
54
|
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
55
|
-
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
56
|
-
UNIQUE(user_id)
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
-- Indexes for performance
|
|
60
|
-
CREATE INDEX idx_user_preferences_user ON user_preferences(user_id);
|
|
61
|
-
CREATE INDEX idx_user_preferences_theme ON user_preferences(theme);
|
|
62
|
-
|
|
63
|
-
-- Trigger for updated_at
|
|
64
|
-
CREATE TRIGGER update_user_preferences_updated_at
|
|
65
|
-
BEFORE UPDATE ON user_preferences
|
|
66
|
-
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
67
|
-
|
|
68
|
-
-- Add new column to existing table
|
|
69
|
-
ALTER TABLE boards ADD COLUMN view_count INTEGER DEFAULT 0;
|
|
70
|
-
CREATE INDEX idx_boards_view_count ON boards(view_count);
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
#### Schema File Best Practices
|
|
74
|
-
|
|
75
|
-
- **Incremental naming**: `001_`, `002_`, `003_` etc.
|
|
76
|
-
- **Descriptive names**: `add_user_preferences`, `create_analytics_tables`
|
|
77
|
-
- **Comments**: Document the purpose of changes
|
|
78
|
-
- **Idempotent**: Use `IF NOT EXISTS` where appropriate
|
|
79
|
-
- **Constraints**: Add proper constraints and validations
|
|
80
|
-
- **Indexes**: Include necessary indexes for performance
|
|
81
|
-
- **Triggers**: Add triggers for `updated_at` columns
|
|
82
|
-
|
|
83
|
-
### Step 2: Generate Migration Scripts
|
|
84
|
-
|
|
85
|
-
Use the migration generator to create UP and DOWN scripts:
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
# Generate migration comparing current DB to target schema
|
|
89
|
-
python scripts/generate_migration.py --name add_user_preferences
|
|
90
|
-
|
|
91
|
-
# Output files created:
|
|
92
|
-
# migrations/generated/20240830_143022_add_user_preferences_up.sql
|
|
93
|
-
# migrations/generated/20240830_143022_add_user_preferences_down.sql
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
#### Generated Migration Example
|
|
97
|
-
|
|
98
|
-
**UP Migration** (`*_up.sql`):
|
|
99
|
-
|
|
100
|
-
```sql
|
|
101
|
-
-- Migration: 20240830_143022_add_user_preferences UP
|
|
102
|
-
-- Generated: 2024-08-30T14:30:22.123456
|
|
103
|
-
|
|
104
|
-
CREATE TABLE "public"."user_preferences" (
|
|
105
|
-
"id" uuid DEFAULT uuid_generate_v4() NOT NULL,
|
|
106
|
-
"user_id" uuid NOT NULL,
|
|
107
|
-
"theme" varchar(20) DEFAULT 'light' NOT NULL,
|
|
108
|
-
"timezone" varchar(50) DEFAULT 'UTC',
|
|
109
|
-
"email_notifications" boolean DEFAULT true,
|
|
110
|
-
"push_notifications" boolean DEFAULT false,
|
|
111
|
-
"metadata" jsonb DEFAULT '{}'::jsonb,
|
|
112
|
-
"created_at" timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
|
|
113
|
-
"updated_at" timestamp with time zone DEFAULT CURRENT_TIMESTAMP
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
ALTER TABLE ONLY "public"."user_preferences"
|
|
117
|
-
ADD CONSTRAINT "user_preferences_pkey" PRIMARY KEY ("id");
|
|
118
|
-
|
|
119
|
-
-- ... additional DDL statements
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
**DOWN Migration** (`*_down.sql`):
|
|
123
|
-
|
|
124
|
-
```sql
|
|
125
|
-
-- Migration: 20240830_143022_add_user_preferences DOWN
|
|
126
|
-
-- Generated: 2024-08-30T14:30:22.123456
|
|
127
|
-
|
|
128
|
-
DROP TABLE IF EXISTS "public"."user_preferences";
|
|
129
|
-
ALTER TABLE "public"."boards" DROP COLUMN IF EXISTS "view_count";
|
|
130
|
-
DROP INDEX IF EXISTS "public"."idx_boards_view_count";
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Step 3: Review and Test Migration
|
|
134
|
-
|
|
135
|
-
Before applying, review the generated migration:
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
# Review the UP migration
|
|
139
|
-
cat migrations/generated/*add_user_preferences_up.sql
|
|
140
|
-
|
|
141
|
-
# Review the DOWN migration (for rollback)
|
|
142
|
-
cat migrations/generated/*add_user_preferences_down.sql
|
|
143
|
-
|
|
144
|
-
# Test on a copy of your database first (recommended)
|
|
145
|
-
pg_dump boards_dev > backup.sql
|
|
146
|
-
createdb boards_test
|
|
147
|
-
psql boards_test < backup.sql
|
|
148
|
-
psql boards_test < migrations/generated/*add_user_preferences_up.sql
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### Step 4: Apply Migration to Database
|
|
152
|
-
|
|
153
|
-
Apply the generated migration to your database:
|
|
154
|
-
|
|
155
|
-
```bash
|
|
156
|
-
# Method 1: Direct application with psql
|
|
157
|
-
psql boards_dev < migrations/generated/*add_user_preferences_up.sql
|
|
158
|
-
|
|
159
|
-
# Method 2: Using the migration runner (tracks applied migrations)
|
|
160
|
-
python migrations/migration_runner.py up --target add_user_preferences
|
|
161
|
-
|
|
162
|
-
# Verify the changes
|
|
163
|
-
psql boards_dev -c "\dt user_preferences"
|
|
164
|
-
psql boards_dev -c "SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'user_preferences';"
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Step 5: Regenerate SQLAlchemy Models
|
|
168
|
-
|
|
169
|
-
Update the Python models to reflect the new schema:
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
# Generate models from current database schema
|
|
173
|
-
python scripts/generate_models.py
|
|
174
|
-
|
|
175
|
-
# This updates: src/boards/database/models.py
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
#### Verify Generated Models
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
# Check that new models are generated
|
|
182
|
-
grep -A 10 "class UserPreferences" src/boards/database/models.py
|
|
183
|
-
|
|
184
|
-
# Test model import
|
|
185
|
-
python -c "from boards.database.models import UserPreferences; print(UserPreferences.__table__.columns.keys())"
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### Step 6: Update GraphQL Schema (if needed)
|
|
189
|
-
|
|
190
|
-
If you added new tables/columns, update the GraphQL types:
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
# Add new types to GraphQL schema
|
|
194
|
-
vim src/boards/graphql/types/user_preferences.py
|
|
195
|
-
|
|
196
|
-
# Add resolvers
|
|
197
|
-
vim src/boards/graphql/resolvers/user_preferences.py
|
|
198
|
-
|
|
199
|
-
# Update queries/mutations
|
|
200
|
-
vim src/boards/graphql/queries/root.py
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### Step 7: Test the Changes
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
# Start the development server
|
|
207
|
-
uvicorn boards.api.app:app --reload --port 8000
|
|
208
|
-
|
|
209
|
-
# Test GraphQL endpoint
|
|
210
|
-
curl -X POST http://localhost:8088/graphql \
|
|
211
|
-
-H "Content-Type: application/json" \
|
|
212
|
-
-d '{"query": "{ __schema { types { name } } }"}'
|
|
213
|
-
|
|
214
|
-
# Or open GraphiQL: http://localhost:8088/graphql
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
## Rollback Procedure
|
|
218
|
-
|
|
219
|
-
If you need to undo a migration:
|
|
220
|
-
|
|
221
|
-
### Method 1: Using DOWN Migration
|
|
222
|
-
|
|
223
|
-
```bash
|
|
224
|
-
# Apply the DOWN migration
|
|
225
|
-
psql boards_dev < migrations/generated/*add_user_preferences_down.sql
|
|
226
|
-
|
|
227
|
-
# Regenerate models to reflect rollback
|
|
228
|
-
python scripts/generate_models.py
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### Method 2: Using Migration Runner
|
|
232
|
-
|
|
233
|
-
```bash
|
|
234
|
-
# Rollback to previous migration
|
|
235
|
-
python migrations/migration_runner.py down --target 001_initial_schema
|
|
236
|
-
|
|
237
|
-
# Or rollback completely
|
|
238
|
-
python migrations/migration_runner.py down --target zero
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### Method 3: Database Restore
|
|
242
|
-
|
|
243
|
-
```bash
|
|
244
|
-
# If you have a backup
|
|
245
|
-
dropdb boards_dev
|
|
246
|
-
createdb boards_dev
|
|
247
|
-
psql boards_dev < backup.sql
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Common Migration Patterns
|
|
251
|
-
|
|
252
|
-
### Adding a New Table
|
|
253
|
-
|
|
254
|
-
```sql
|
|
255
|
-
-- 003_add_analytics.sql
|
|
256
|
-
CREATE TABLE page_views (
|
|
257
|
-
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
258
|
-
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
259
|
-
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
260
|
-
page_path VARCHAR(255) NOT NULL,
|
|
261
|
-
viewed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
262
|
-
metadata JSONB DEFAULT '{}'
|
|
263
|
-
);
|
|
264
|
-
|
|
265
|
-
CREATE INDEX idx_page_views_tenant ON page_views(tenant_id);
|
|
266
|
-
CREATE INDEX idx_page_views_user ON page_views(user_id);
|
|
267
|
-
CREATE INDEX idx_page_views_path ON page_views(page_path);
|
|
268
|
-
CREATE INDEX idx_page_views_date ON page_views(viewed_at);
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
### Adding Columns to Existing Table
|
|
272
|
-
|
|
273
|
-
```sql
|
|
274
|
-
-- 004_add_board_features.sql
|
|
275
|
-
-- Add new columns to boards table
|
|
276
|
-
ALTER TABLE boards ADD COLUMN is_archived BOOLEAN DEFAULT FALSE;
|
|
277
|
-
ALTER TABLE boards ADD COLUMN archived_at TIMESTAMP WITH TIME ZONE;
|
|
278
|
-
ALTER TABLE boards ADD COLUMN tags TEXT[] DEFAULT '{}';
|
|
279
|
-
|
|
280
|
-
-- Add indexes
|
|
281
|
-
CREATE INDEX idx_boards_archived ON boards(is_archived);
|
|
282
|
-
CREATE INDEX idx_boards_archived_at ON boards(archived_at);
|
|
283
|
-
CREATE INDEX idx_boards_tags ON boards USING GIN(tags);
|
|
284
|
-
|
|
285
|
-
-- Add constraint
|
|
286
|
-
ALTER TABLE boards ADD CONSTRAINT check_archived_date
|
|
287
|
-
CHECK (is_archived = FALSE OR archived_at IS NOT NULL);
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
### Creating Indexes
|
|
291
|
-
|
|
292
|
-
```sql
|
|
293
|
-
-- 005_optimize_queries.sql
|
|
294
|
-
-- Add indexes for common query patterns
|
|
295
|
-
|
|
296
|
-
-- Composite index for board member queries
|
|
297
|
-
CREATE INDEX idx_board_members_board_role ON board_members(board_id, role);
|
|
298
|
-
|
|
299
|
-
-- Partial index for active generations
|
|
300
|
-
CREATE INDEX idx_generations_active ON generations(board_id, created_at)
|
|
301
|
-
WHERE status IN ('pending', 'processing');
|
|
302
|
-
|
|
303
|
-
-- Text search index
|
|
304
|
-
CREATE INDEX idx_boards_title_search ON boards USING gin(to_tsvector('english', title));
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### Modifying Column Types
|
|
308
|
-
|
|
309
|
-
```sql
|
|
310
|
-
-- 006_extend_varchar_limits.sql
|
|
311
|
-
-- Increase varchar limits based on usage patterns
|
|
312
|
-
|
|
313
|
-
ALTER TABLE users ALTER COLUMN display_name TYPE VARCHAR(500);
|
|
314
|
-
ALTER TABLE boards ALTER COLUMN title TYPE VARCHAR(500);
|
|
315
|
-
ALTER TABLE generations ALTER COLUMN generator_name TYPE VARCHAR(200);
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
### Adding Foreign Keys
|
|
319
|
-
|
|
320
|
-
```sql
|
|
321
|
-
-- 007_add_missing_constraints.sql
|
|
322
|
-
-- Add foreign key constraints that were missed
|
|
323
|
-
|
|
324
|
-
-- Add foreign key from provider_configs to something
|
|
325
|
-
ALTER TABLE provider_configs
|
|
326
|
-
ADD CONSTRAINT fk_provider_configs_updated_by
|
|
327
|
-
FOREIGN KEY (updated_by) REFERENCES users(id);
|
|
328
|
-
|
|
329
|
-
-- Add check constraints
|
|
330
|
-
ALTER TABLE credit_transactions
|
|
331
|
-
ADD CONSTRAINT check_positive_amount CHECK (amount >= 0);
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
## Production Deployment
|
|
335
|
-
|
|
336
|
-
### Pre-deployment Checklist
|
|
337
|
-
|
|
338
|
-
- [ ] Migration tested on development database
|
|
339
|
-
- [ ] Migration tested on staging database with production-like data
|
|
340
|
-
- [ ] Backup created before deployment
|
|
341
|
-
- [ ] Rollback plan prepared
|
|
342
|
-
- [ ] Downtime requirements communicated
|
|
343
|
-
- [ ] Performance impact assessed
|
|
344
|
-
|
|
345
|
-
### Deployment Steps
|
|
346
|
-
|
|
347
|
-
```bash
|
|
348
|
-
# 1. Create backup
|
|
349
|
-
pg_dump boards_production > backup_$(date +%Y%m%d_%H%M%S).sql
|
|
350
|
-
|
|
351
|
-
# 2. Apply migration
|
|
352
|
-
psql boards_production < migrations/generated/*_migration_up.sql
|
|
353
|
-
|
|
354
|
-
# 3. Regenerate models on server
|
|
355
|
-
python scripts/generate_models.py
|
|
356
|
-
|
|
357
|
-
# 4. Restart application
|
|
358
|
-
systemctl restart boards-api
|
|
359
|
-
|
|
360
|
-
# 5. Verify deployment
|
|
361
|
-
curl -f http://localhost:8088/health
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
### Zero-downtime Migrations
|
|
365
|
-
|
|
366
|
-
For large tables, consider these strategies:
|
|
367
|
-
|
|
368
|
-
1. **Add columns as nullable first**:
|
|
369
|
-
|
|
370
|
-
```sql
|
|
371
|
-
-- Step 1: Add nullable column
|
|
372
|
-
ALTER TABLE large_table ADD COLUMN new_column VARCHAR(255);
|
|
373
|
-
|
|
374
|
-
-- Step 2: Backfill data (in application code)
|
|
375
|
-
-- Step 3: Add NOT NULL constraint
|
|
376
|
-
ALTER TABLE large_table ALTER COLUMN new_column SET NOT NULL;
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
2. **Use CREATE INDEX CONCURRENTLY**:
|
|
380
|
-
|
|
381
|
-
```sql
|
|
382
|
-
-- Non-blocking index creation
|
|
383
|
-
CREATE INDEX CONCURRENTLY idx_large_table_new_column ON large_table(new_column);
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
3. **Staged rollouts**: Apply changes gradually across multiple deployments
|
|
387
|
-
|
|
388
|
-
## Troubleshooting
|
|
389
|
-
|
|
390
|
-
### Common Issues
|
|
391
|
-
|
|
392
|
-
**Migration fails with constraint violation:**
|
|
393
|
-
|
|
394
|
-
```bash
|
|
395
|
-
# Check existing data
|
|
396
|
-
psql boards_dev -c "SELECT COUNT(*) FROM users WHERE email IS NULL;"
|
|
397
|
-
|
|
398
|
-
# Fix data first, then retry migration
|
|
399
|
-
psql boards_dev -c "UPDATE users SET email = 'unknown@example.com' WHERE email IS NULL;"
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
**Generated models are incorrect:**
|
|
403
|
-
|
|
404
|
-
```bash
|
|
405
|
-
# Clear and regenerate
|
|
406
|
-
rm src/boards/database/models.py
|
|
407
|
-
python scripts/generate_models.py
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
**Migration generates no changes:**
|
|
411
|
-
|
|
412
|
-
```bash
|
|
413
|
-
# Check if schema files match current database
|
|
414
|
-
python scripts/generate_migration.py --name test --dry-run
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
**Schema conflicts:**
|
|
418
|
-
|
|
419
|
-
```bash
|
|
420
|
-
# Compare schemas manually
|
|
421
|
-
pg_dump boards_dev --schema-only > current_schema.sql
|
|
422
|
-
# Apply DDL files to temp database and compare
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
### Getting Help
|
|
426
|
-
|
|
427
|
-
1. Check the generated migration files first
|
|
428
|
-
2. Test on a development database copy
|
|
429
|
-
3. Review PostgreSQL logs: `tail -f /var/log/postgresql/postgresql.log`
|
|
430
|
-
4. Use `EXPLAIN ANALYZE` for performance testing
|
|
431
|
-
|
|
432
|
-
## Best Practices Summary
|
|
433
|
-
|
|
434
|
-
✅ **DO:**
|
|
435
|
-
|
|
436
|
-
- Always test migrations on development/staging first
|
|
437
|
-
- Use descriptive migration names
|
|
438
|
-
- Include proper indexes and constraints
|
|
439
|
-
- Document complex changes
|
|
440
|
-
- Create backups before production migrations
|
|
441
|
-
- Use transactions for complex migrations
|
|
442
|
-
|
|
443
|
-
❌ **DON'T:**
|
|
444
|
-
|
|
445
|
-
- Apply migrations directly to production without testing
|
|
446
|
-
- Create migrations that can't be rolled back
|
|
447
|
-
- Forget to regenerate models after schema changes
|
|
448
|
-
- Skip index creation for new columns
|
|
449
|
-
- Make breaking changes without a migration strategy
|
|
450
|
-
|
|
451
|
-
## File Structure Reference
|
|
452
|
-
|
|
453
|
-
```
|
|
454
|
-
packages/backend/
|
|
455
|
-
├── migrations/
|
|
456
|
-
│ ├── schemas/ # DDL source files (edit these)
|
|
457
|
-
│ │ ├── 001_initial_schema.sql
|
|
458
|
-
│ │ ├── 002_add_user_preferences.sql
|
|
459
|
-
│ │ └── 003_add_analytics.sql
|
|
460
|
-
│ ├── generated/ # Generated migration scripts (don't edit)
|
|
461
|
-
│ │ ├── 20240830_143022_add_user_preferences_up.sql
|
|
462
|
-
│ │ ├── 20240830_143022_add_user_preferences_down.sql
|
|
463
|
-
│ │ └── ...
|
|
464
|
-
│ └── migration_runner.py # Migration application tool
|
|
465
|
-
├── scripts/
|
|
466
|
-
│ ├── generate_models.py # DDL → SQLAlchemy models
|
|
467
|
-
│ └── generate_migration.py # Schema diff → migration scripts
|
|
468
|
-
└── src/boards/database/
|
|
469
|
-
└── models.py # Generated SQLAlchemy models (don't edit)
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
Remember: The schema files in `migrations/schemas/` are your source of truth. Everything else is generated!
|