aidevops 2.52.1
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/.agent/AGENTS.md +614 -0
- package/.agent/accounts.md +65 -0
- package/.agent/aidevops/add-new-mcp-to-aidevops.md +456 -0
- package/.agent/aidevops/api-integrations.md +335 -0
- package/.agent/aidevops/architecture.md +510 -0
- package/.agent/aidevops/configs.md +274 -0
- package/.agent/aidevops/docs.md +244 -0
- package/.agent/aidevops/extension.md +311 -0
- package/.agent/aidevops/mcp-integrations.md +340 -0
- package/.agent/aidevops/mcp-troubleshooting.md +162 -0
- package/.agent/aidevops/memory-patterns.md +172 -0
- package/.agent/aidevops/providers.md +217 -0
- package/.agent/aidevops/recommendations.md +321 -0
- package/.agent/aidevops/requirements.md +301 -0
- package/.agent/aidevops/resources.md +214 -0
- package/.agent/aidevops/security-requirements.md +174 -0
- package/.agent/aidevops/security.md +350 -0
- package/.agent/aidevops/service-links.md +400 -0
- package/.agent/aidevops/services.md +357 -0
- package/.agent/aidevops/setup.md +153 -0
- package/.agent/aidevops/troubleshooting.md +389 -0
- package/.agent/aidevops.md +124 -0
- package/.agent/build-plus.md +244 -0
- package/.agent/content/guidelines.md +109 -0
- package/.agent/content.md +87 -0
- package/.agent/health.md +59 -0
- package/.agent/legal.md +59 -0
- package/.agent/loop-state/full-loop.local.md +16 -0
- package/.agent/loop-state/ralph-loop.local.md +10 -0
- package/.agent/marketing.md +440 -0
- package/.agent/memory/README.md +260 -0
- package/.agent/onboarding.md +796 -0
- package/.agent/plan-plus.md +245 -0
- package/.agent/research.md +100 -0
- package/.agent/sales.md +333 -0
- package/.agent/scripts/101domains-helper.sh +701 -0
- package/.agent/scripts/add-missing-returns.sh +140 -0
- package/.agent/scripts/agent-browser-helper.sh +311 -0
- package/.agent/scripts/agno-setup.sh +712 -0
- package/.agent/scripts/ahrefs-mcp-wrapper.js +168 -0
- package/.agent/scripts/aidevops-update-check.sh +71 -0
- package/.agent/scripts/ampcode-cli.sh +522 -0
- package/.agent/scripts/auto-version-bump.sh +156 -0
- package/.agent/scripts/autogen-helper.sh +512 -0
- package/.agent/scripts/beads-sync-helper.sh +596 -0
- package/.agent/scripts/closte-helper.sh +5 -0
- package/.agent/scripts/cloudron-helper.sh +321 -0
- package/.agent/scripts/codacy-cli-chunked.sh +581 -0
- package/.agent/scripts/codacy-cli.sh +442 -0
- package/.agent/scripts/code-audit-helper.sh +5 -0
- package/.agent/scripts/coderabbit-cli.sh +417 -0
- package/.agent/scripts/coderabbit-pro-analysis.sh +238 -0
- package/.agent/scripts/commands/code-simplifier.md +86 -0
- package/.agent/scripts/commands/full-loop.md +246 -0
- package/.agent/scripts/commands/postflight-loop.md +103 -0
- package/.agent/scripts/commands/recall.md +182 -0
- package/.agent/scripts/commands/remember.md +132 -0
- package/.agent/scripts/commands/save-todo.md +175 -0
- package/.agent/scripts/commands/session-review.md +154 -0
- package/.agent/scripts/comprehensive-quality-fix.sh +106 -0
- package/.agent/scripts/context-builder-helper.sh +522 -0
- package/.agent/scripts/coolify-cli-helper.sh +674 -0
- package/.agent/scripts/coolify-helper.sh +380 -0
- package/.agent/scripts/crawl4ai-examples.sh +401 -0
- package/.agent/scripts/crawl4ai-helper.sh +1078 -0
- package/.agent/scripts/crewai-helper.sh +681 -0
- package/.agent/scripts/dev-browser-helper.sh +513 -0
- package/.agent/scripts/dns-helper.sh +396 -0
- package/.agent/scripts/domain-research-helper.sh +917 -0
- package/.agent/scripts/dspy-helper.sh +285 -0
- package/.agent/scripts/dspyground-helper.sh +291 -0
- package/.agent/scripts/eeat-score-helper.sh +1242 -0
- package/.agent/scripts/efficient-return-fix.sh +92 -0
- package/.agent/scripts/extract-opencode-prompts.sh +128 -0
- package/.agent/scripts/find-missing-returns.sh +113 -0
- package/.agent/scripts/fix-auth-headers.sh +104 -0
- package/.agent/scripts/fix-common-strings.sh +254 -0
- package/.agent/scripts/fix-content-type.sh +100 -0
- package/.agent/scripts/fix-error-messages.sh +130 -0
- package/.agent/scripts/fix-misplaced-returns.sh +74 -0
- package/.agent/scripts/fix-remaining-literals.sh +152 -0
- package/.agent/scripts/fix-return-statements.sh +41 -0
- package/.agent/scripts/fix-s131-default-cases.sh +249 -0
- package/.agent/scripts/fix-sc2155-simple.sh +102 -0
- package/.agent/scripts/fix-shellcheck-critical.sh +187 -0
- package/.agent/scripts/fix-string-literals.sh +273 -0
- package/.agent/scripts/full-loop-helper.sh +773 -0
- package/.agent/scripts/generate-opencode-agents.sh +497 -0
- package/.agent/scripts/generate-opencode-commands.sh +1629 -0
- package/.agent/scripts/generate-skills.sh +366 -0
- package/.agent/scripts/git-platforms-helper.sh +640 -0
- package/.agent/scripts/gitea-cli-helper.sh +743 -0
- package/.agent/scripts/github-cli-helper.sh +702 -0
- package/.agent/scripts/gitlab-cli-helper.sh +682 -0
- package/.agent/scripts/gsc-add-user-helper.sh +325 -0
- package/.agent/scripts/gsc-sitemap-helper.sh +678 -0
- package/.agent/scripts/hetzner-helper.sh +485 -0
- package/.agent/scripts/hostinger-helper.sh +229 -0
- package/.agent/scripts/keyword-research-helper.sh +1815 -0
- package/.agent/scripts/langflow-helper.sh +544 -0
- package/.agent/scripts/linkedin-automation.py +241 -0
- package/.agent/scripts/linter-manager.sh +599 -0
- package/.agent/scripts/linters-local.sh +434 -0
- package/.agent/scripts/list-keys-helper.sh +488 -0
- package/.agent/scripts/local-browser-automation.py +339 -0
- package/.agent/scripts/localhost-helper.sh +744 -0
- package/.agent/scripts/loop-common.sh +806 -0
- package/.agent/scripts/mainwp-helper.sh +728 -0
- package/.agent/scripts/markdown-formatter.sh +338 -0
- package/.agent/scripts/markdown-lint-fix.sh +311 -0
- package/.agent/scripts/mass-fix-returns.sh +58 -0
- package/.agent/scripts/mcp-diagnose.sh +167 -0
- package/.agent/scripts/mcp-inspector-helper.sh +449 -0
- package/.agent/scripts/memory-helper.sh +650 -0
- package/.agent/scripts/monitor-code-review.sh +255 -0
- package/.agent/scripts/onboarding-helper.sh +706 -0
- package/.agent/scripts/opencode-github-setup-helper.sh +797 -0
- package/.agent/scripts/opencode-test-helper.sh +213 -0
- package/.agent/scripts/pagespeed-helper.sh +464 -0
- package/.agent/scripts/pandoc-helper.sh +362 -0
- package/.agent/scripts/postflight-check.sh +555 -0
- package/.agent/scripts/pre-commit-hook.sh +259 -0
- package/.agent/scripts/pre-edit-check.sh +169 -0
- package/.agent/scripts/qlty-cli.sh +356 -0
- package/.agent/scripts/quality-cli-manager.sh +525 -0
- package/.agent/scripts/quality-feedback-helper.sh +462 -0
- package/.agent/scripts/quality-fix.sh +263 -0
- package/.agent/scripts/quality-loop-helper.sh +1108 -0
- package/.agent/scripts/ralph-loop-helper.sh +836 -0
- package/.agent/scripts/ralph-upstream-check.sh +341 -0
- package/.agent/scripts/secretlint-helper.sh +847 -0
- package/.agent/scripts/servers-helper.sh +241 -0
- package/.agent/scripts/ses-helper.sh +619 -0
- package/.agent/scripts/session-review-helper.sh +404 -0
- package/.agent/scripts/setup-linters-wizard.sh +379 -0
- package/.agent/scripts/setup-local-api-keys.sh +330 -0
- package/.agent/scripts/setup-mcp-integrations.sh +472 -0
- package/.agent/scripts/shared-constants.sh +246 -0
- package/.agent/scripts/site-crawler-helper.sh +1487 -0
- package/.agent/scripts/snyk-helper.sh +940 -0
- package/.agent/scripts/sonarcloud-autofix.sh +193 -0
- package/.agent/scripts/sonarcloud-cli.sh +191 -0
- package/.agent/scripts/sonarscanner-cli.sh +455 -0
- package/.agent/scripts/spaceship-helper.sh +747 -0
- package/.agent/scripts/stagehand-helper.sh +321 -0
- package/.agent/scripts/stagehand-python-helper.sh +321 -0
- package/.agent/scripts/stagehand-python-setup.sh +441 -0
- package/.agent/scripts/stagehand-setup.sh +439 -0
- package/.agent/scripts/system-cleanup.sh +340 -0
- package/.agent/scripts/terminal-title-helper.sh +388 -0
- package/.agent/scripts/terminal-title-setup.sh +549 -0
- package/.agent/scripts/test-stagehand-both-integration.sh +317 -0
- package/.agent/scripts/test-stagehand-integration.sh +309 -0
- package/.agent/scripts/test-stagehand-python-integration.sh +341 -0
- package/.agent/scripts/todo-ready.sh +263 -0
- package/.agent/scripts/tool-version-check.sh +362 -0
- package/.agent/scripts/toon-helper.sh +469 -0
- package/.agent/scripts/twilio-helper.sh +917 -0
- package/.agent/scripts/updown-helper.sh +279 -0
- package/.agent/scripts/validate-mcp-integrations.sh +250 -0
- package/.agent/scripts/validate-version-consistency.sh +131 -0
- package/.agent/scripts/vaultwarden-helper.sh +597 -0
- package/.agent/scripts/vercel-cli-helper.sh +816 -0
- package/.agent/scripts/verify-mirrors.sh +169 -0
- package/.agent/scripts/version-manager.sh +831 -0
- package/.agent/scripts/webhosting-helper.sh +471 -0
- package/.agent/scripts/webhosting-verify.sh +238 -0
- package/.agent/scripts/wordpress-mcp-helper.sh +508 -0
- package/.agent/scripts/worktree-helper.sh +595 -0
- package/.agent/scripts/worktree-sessions.sh +577 -0
- package/.agent/seo/dataforseo.md +215 -0
- package/.agent/seo/domain-research.md +532 -0
- package/.agent/seo/eeat-score.md +659 -0
- package/.agent/seo/google-search-console.md +366 -0
- package/.agent/seo/gsc-sitemaps.md +282 -0
- package/.agent/seo/keyword-research.md +521 -0
- package/.agent/seo/serper.md +278 -0
- package/.agent/seo/site-crawler.md +387 -0
- package/.agent/seo.md +236 -0
- package/.agent/services/accounting/quickfile.md +159 -0
- package/.agent/services/communications/telfon.md +470 -0
- package/.agent/services/communications/twilio.md +569 -0
- package/.agent/services/crm/fluentcrm.md +449 -0
- package/.agent/services/email/ses.md +399 -0
- package/.agent/services/hosting/101domains.md +378 -0
- package/.agent/services/hosting/closte.md +177 -0
- package/.agent/services/hosting/cloudflare.md +251 -0
- package/.agent/services/hosting/cloudron.md +478 -0
- package/.agent/services/hosting/dns-providers.md +335 -0
- package/.agent/services/hosting/domain-purchasing.md +344 -0
- package/.agent/services/hosting/hetzner.md +327 -0
- package/.agent/services/hosting/hostinger.md +287 -0
- package/.agent/services/hosting/localhost.md +419 -0
- package/.agent/services/hosting/spaceship.md +353 -0
- package/.agent/services/hosting/webhosting.md +330 -0
- package/.agent/social-media.md +69 -0
- package/.agent/templates/plans-template.md +114 -0
- package/.agent/templates/prd-template.md +129 -0
- package/.agent/templates/tasks-template.md +108 -0
- package/.agent/templates/todo-template.md +89 -0
- package/.agent/tools/ai-assistants/agno.md +471 -0
- package/.agent/tools/ai-assistants/capsolver.md +326 -0
- package/.agent/tools/ai-assistants/configuration.md +221 -0
- package/.agent/tools/ai-assistants/overview.md +209 -0
- package/.agent/tools/ai-assistants/status.md +171 -0
- package/.agent/tools/ai-assistants/windsurf.md +193 -0
- package/.agent/tools/ai-orchestration/autogen.md +406 -0
- package/.agent/tools/ai-orchestration/crewai.md +445 -0
- package/.agent/tools/ai-orchestration/langflow.md +405 -0
- package/.agent/tools/ai-orchestration/openprose.md +487 -0
- package/.agent/tools/ai-orchestration/overview.md +362 -0
- package/.agent/tools/ai-orchestration/packaging.md +647 -0
- package/.agent/tools/browser/agent-browser.md +464 -0
- package/.agent/tools/browser/browser-automation.md +400 -0
- package/.agent/tools/browser/chrome-devtools.md +282 -0
- package/.agent/tools/browser/crawl4ai-integration.md +422 -0
- package/.agent/tools/browser/crawl4ai-resources.md +277 -0
- package/.agent/tools/browser/crawl4ai-usage.md +416 -0
- package/.agent/tools/browser/crawl4ai.md +585 -0
- package/.agent/tools/browser/dev-browser.md +341 -0
- package/.agent/tools/browser/pagespeed.md +260 -0
- package/.agent/tools/browser/playwright.md +266 -0
- package/.agent/tools/browser/playwriter.md +310 -0
- package/.agent/tools/browser/stagehand-examples.md +456 -0
- package/.agent/tools/browser/stagehand-python.md +483 -0
- package/.agent/tools/browser/stagehand.md +421 -0
- package/.agent/tools/build-agent/agent-review.md +224 -0
- package/.agent/tools/build-agent/build-agent.md +784 -0
- package/.agent/tools/build-mcp/aidevops-plugin.md +476 -0
- package/.agent/tools/build-mcp/api-wrapper.md +445 -0
- package/.agent/tools/build-mcp/build-mcp.md +240 -0
- package/.agent/tools/build-mcp/deployment.md +401 -0
- package/.agent/tools/build-mcp/server-patterns.md +632 -0
- package/.agent/tools/build-mcp/transports.md +366 -0
- package/.agent/tools/code-review/auditing.md +383 -0
- package/.agent/tools/code-review/automation.md +219 -0
- package/.agent/tools/code-review/best-practices.md +203 -0
- package/.agent/tools/code-review/codacy.md +151 -0
- package/.agent/tools/code-review/code-simplifier.md +174 -0
- package/.agent/tools/code-review/code-standards.md +309 -0
- package/.agent/tools/code-review/coderabbit.md +101 -0
- package/.agent/tools/code-review/management.md +155 -0
- package/.agent/tools/code-review/qlty.md +248 -0
- package/.agent/tools/code-review/secretlint.md +565 -0
- package/.agent/tools/code-review/setup.md +250 -0
- package/.agent/tools/code-review/snyk.md +563 -0
- package/.agent/tools/code-review/tools.md +230 -0
- package/.agent/tools/content/summarize.md +353 -0
- package/.agent/tools/context/augment-context-engine.md +468 -0
- package/.agent/tools/context/context-builder-agent.md +76 -0
- package/.agent/tools/context/context-builder.md +375 -0
- package/.agent/tools/context/context7.md +371 -0
- package/.agent/tools/context/dspy.md +302 -0
- package/.agent/tools/context/dspyground.md +374 -0
- package/.agent/tools/context/llm-tldr.md +219 -0
- package/.agent/tools/context/osgrep.md +488 -0
- package/.agent/tools/context/prompt-optimization.md +338 -0
- package/.agent/tools/context/toon.md +292 -0
- package/.agent/tools/conversion/pandoc.md +304 -0
- package/.agent/tools/credentials/api-key-management.md +154 -0
- package/.agent/tools/credentials/api-key-setup.md +224 -0
- package/.agent/tools/credentials/environment-variables.md +180 -0
- package/.agent/tools/credentials/vaultwarden.md +382 -0
- package/.agent/tools/data-extraction/outscraper.md +974 -0
- package/.agent/tools/deployment/coolify-cli.md +388 -0
- package/.agent/tools/deployment/coolify-setup.md +353 -0
- package/.agent/tools/deployment/coolify.md +345 -0
- package/.agent/tools/deployment/vercel.md +390 -0
- package/.agent/tools/git/authentication.md +132 -0
- package/.agent/tools/git/gitea-cli.md +193 -0
- package/.agent/tools/git/github-actions.md +207 -0
- package/.agent/tools/git/github-cli.md +223 -0
- package/.agent/tools/git/gitlab-cli.md +190 -0
- package/.agent/tools/git/opencode-github-security.md +350 -0
- package/.agent/tools/git/opencode-github.md +328 -0
- package/.agent/tools/git/opencode-gitlab.md +252 -0
- package/.agent/tools/git/security.md +196 -0
- package/.agent/tools/git.md +207 -0
- package/.agent/tools/opencode/oh-my-opencode.md +375 -0
- package/.agent/tools/opencode/opencode-anthropic-auth.md +446 -0
- package/.agent/tools/opencode/opencode.md +651 -0
- package/.agent/tools/social-media/bird.md +437 -0
- package/.agent/tools/task-management/beads.md +336 -0
- package/.agent/tools/terminal/terminal-title.md +251 -0
- package/.agent/tools/ui/shadcn.md +196 -0
- package/.agent/tools/ui/ui-skills.md +115 -0
- package/.agent/tools/wordpress/localwp.md +311 -0
- package/.agent/tools/wordpress/mainwp.md +391 -0
- package/.agent/tools/wordpress/scf.md +527 -0
- package/.agent/tools/wordpress/wp-admin.md +729 -0
- package/.agent/tools/wordpress/wp-dev.md +940 -0
- package/.agent/tools/wordpress/wp-preferred.md +398 -0
- package/.agent/tools/wordpress.md +95 -0
- package/.agent/workflows/branch/bugfix.md +63 -0
- package/.agent/workflows/branch/chore.md +95 -0
- package/.agent/workflows/branch/experiment.md +115 -0
- package/.agent/workflows/branch/feature.md +59 -0
- package/.agent/workflows/branch/hotfix.md +98 -0
- package/.agent/workflows/branch/refactor.md +92 -0
- package/.agent/workflows/branch/release.md +96 -0
- package/.agent/workflows/branch.md +347 -0
- package/.agent/workflows/bug-fixing.md +267 -0
- package/.agent/workflows/changelog.md +129 -0
- package/.agent/workflows/code-audit-remote.md +279 -0
- package/.agent/workflows/conversation-starter.md +69 -0
- package/.agent/workflows/error-feedback.md +578 -0
- package/.agent/workflows/feature-development.md +355 -0
- package/.agent/workflows/git-workflow.md +702 -0
- package/.agent/workflows/multi-repo-workspace.md +268 -0
- package/.agent/workflows/plans.md +709 -0
- package/.agent/workflows/postflight.md +604 -0
- package/.agent/workflows/pr.md +571 -0
- package/.agent/workflows/preflight.md +278 -0
- package/.agent/workflows/ralph-loop.md +773 -0
- package/.agent/workflows/release.md +498 -0
- package/.agent/workflows/session-manager.md +254 -0
- package/.agent/workflows/session-review.md +311 -0
- package/.agent/workflows/sql-migrations.md +631 -0
- package/.agent/workflows/version-bump.md +283 -0
- package/.agent/workflows/wiki-update.md +333 -0
- package/.agent/workflows/worktree.md +477 -0
- package/LICENSE +21 -0
- package/README.md +1446 -0
- package/VERSION +1 -0
- package/aidevops.sh +1746 -0
- package/bin/aidevops +21 -0
- package/package.json +75 -0
- package/scripts/npm-postinstall.js +60 -0
- package/setup.sh +2366 -0
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
---
|
|
2
|
+
mode: subagent
|
|
3
|
+
---
|
|
4
|
+
# SQL Migrations Workflow
|
|
5
|
+
|
|
6
|
+
<!-- AI-CONTEXT-START -->
|
|
7
|
+
|
|
8
|
+
## Quick Reference
|
|
9
|
+
|
|
10
|
+
- **Purpose**: Version-controlled database schema changes with rollback support
|
|
11
|
+
- **Declarative**: `schemas/` - Define desired state, generate migrations automatically
|
|
12
|
+
- **Migrations**: `migrations/` - Versioned, timestamped migration files
|
|
13
|
+
- **Naming**: `{timestamp}_{action}_{target}.sql`
|
|
14
|
+
|
|
15
|
+
**Directory Structure**:
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
project/
|
|
19
|
+
├── schemas/ # Declarative schema files (source of truth)
|
|
20
|
+
│ ├── 00_extensions.sql # PostgreSQL extensions
|
|
21
|
+
│ ├── 01_types.sql # Custom types and enums
|
|
22
|
+
│ ├── 10_users.sql # Users table and related
|
|
23
|
+
│ ├── 20_products.sql # Products domain
|
|
24
|
+
│ └── 30_orders.sql # Orders domain
|
|
25
|
+
├── migrations/ # Generated migration files (auto-generated)
|
|
26
|
+
│ ├── 20240502100843_create_users_table.sql
|
|
27
|
+
│ └── 20240503142030_add_email_to_users.sql
|
|
28
|
+
└── seeds/ # Initial/test data
|
|
29
|
+
└── 001_base_data.sql
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Critical Rules**:
|
|
33
|
+
|
|
34
|
+
- NEVER modify migrations that have been pushed/deployed
|
|
35
|
+
- ALWAYS generate migrations via diff (don't write manually)
|
|
36
|
+
- ALWAYS review generated migrations before committing
|
|
37
|
+
- ALWAYS backup before running migrations in production
|
|
38
|
+
- ONE logical change per migration file
|
|
39
|
+
|
|
40
|
+
**Workflow**:
|
|
41
|
+
|
|
42
|
+
1. Edit schema files in `schemas/`
|
|
43
|
+
2. Run diff to generate migration
|
|
44
|
+
3. Review generated migration
|
|
45
|
+
4. Apply migration locally
|
|
46
|
+
5. Commit both schema and migration files
|
|
47
|
+
|
|
48
|
+
<!-- AI-CONTEXT-END -->
|
|
49
|
+
|
|
50
|
+
## Declarative Schema Workflow (Recommended)
|
|
51
|
+
|
|
52
|
+
The declarative approach lets you define your desired database state in `schemas/` files, then automatically generate migrations by diffing against the current database.
|
|
53
|
+
|
|
54
|
+
### Why Declarative?
|
|
55
|
+
|
|
56
|
+
| Approach | Pros | Cons |
|
|
57
|
+
|----------|------|------|
|
|
58
|
+
| **Declarative** | Single source of truth, easy to review, auto-generated migrations | Requires diff tool, some edge cases |
|
|
59
|
+
| **Imperative** | Full control, works everywhere | Scattered across files, manual, error-prone |
|
|
60
|
+
|
|
61
|
+
### Schema File Organization
|
|
62
|
+
|
|
63
|
+
Prefix files with numbers to control execution order (dependencies):
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
schemas/
|
|
67
|
+
├── 00_extensions.sql # CREATE EXTENSION IF NOT EXISTS ...
|
|
68
|
+
├── 01_types.sql # Custom types, enums
|
|
69
|
+
├── 10_users.sql # Core user tables
|
|
70
|
+
├── 11_user_profiles.sql # User-related tables (depends on users)
|
|
71
|
+
├── 20_products.sql # Product domain
|
|
72
|
+
├── 30_orders.sql # Order domain (depends on users, products)
|
|
73
|
+
└── 90_views.sql # Views (depend on tables)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Writing Schema Files
|
|
77
|
+
|
|
78
|
+
Each file declares the desired state of related tables:
|
|
79
|
+
|
|
80
|
+
```sql
|
|
81
|
+
-- schemas/10_users.sql
|
|
82
|
+
|
|
83
|
+
CREATE TABLE IF NOT EXISTS "users" (
|
|
84
|
+
"id" SERIAL PRIMARY KEY,
|
|
85
|
+
"email" VARCHAR(255) NOT NULL UNIQUE,
|
|
86
|
+
"name" VARCHAR(255),
|
|
87
|
+
"created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
88
|
+
"updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
|
92
|
+
|
|
93
|
+
-- Related function
|
|
94
|
+
CREATE OR REPLACE FUNCTION update_updated_at()
|
|
95
|
+
RETURNS TRIGGER AS $$
|
|
96
|
+
BEGIN
|
|
97
|
+
NEW.updated_at = CURRENT_TIMESTAMP;
|
|
98
|
+
RETURN NEW;
|
|
99
|
+
END;
|
|
100
|
+
$$ LANGUAGE plpgsql;
|
|
101
|
+
|
|
102
|
+
CREATE TRIGGER users_updated_at
|
|
103
|
+
BEFORE UPDATE ON users
|
|
104
|
+
FOR EACH ROW
|
|
105
|
+
EXECUTE FUNCTION update_updated_at();
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Generating Migrations
|
|
109
|
+
|
|
110
|
+
When you modify a schema file, generate a migration:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Supabase CLI
|
|
114
|
+
supabase db diff -f add_phone_to_users
|
|
115
|
+
|
|
116
|
+
# Generic approach (using migra or similar)
|
|
117
|
+
migra postgresql://localhost/mydb schemas/ > migrations/$(date +%Y%m%d%H%M%S)_add_phone_to_users.sql
|
|
118
|
+
|
|
119
|
+
# Prisma (schema.prisma is declarative)
|
|
120
|
+
npx prisma migrate dev --name add_phone_to_users
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Reviewing Generated Migrations
|
|
124
|
+
|
|
125
|
+
**ALWAYS review before committing:**
|
|
126
|
+
|
|
127
|
+
```sql
|
|
128
|
+
-- migrations/20240502101659_add_phone_to_users.sql
|
|
129
|
+
-- Generated by: supabase db diff
|
|
130
|
+
|
|
131
|
+
ALTER TABLE "public"."users" ADD COLUMN "phone" VARCHAR(20);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Check for:
|
|
135
|
+
|
|
136
|
+
- ✅ Only expected changes
|
|
137
|
+
- ✅ No destructive operations (unless intended)
|
|
138
|
+
- ✅ Correct column types and constraints
|
|
139
|
+
- ⚠️ Data migrations may need manual adjustment
|
|
140
|
+
|
|
141
|
+
### Applying Migrations
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Supabase
|
|
145
|
+
supabase migration up
|
|
146
|
+
|
|
147
|
+
# Generic
|
|
148
|
+
psql $DATABASE_URL -f migrations/20240502101659_add_phone_to_users.sql
|
|
149
|
+
|
|
150
|
+
# Prisma
|
|
151
|
+
npx prisma migrate deploy
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Tool-Specific Commands
|
|
155
|
+
|
|
156
|
+
| Tool | Schema Format | Diff Command | Apply Command |
|
|
157
|
+
|------|---------------|--------------|---------------|
|
|
158
|
+
| **Supabase** | SQL files | `supabase db diff -f name` | `supabase migration up` |
|
|
159
|
+
| **Drizzle** | TypeScript | `npx drizzle-kit generate` | `npx drizzle-kit migrate` |
|
|
160
|
+
| **Prisma** | Prisma Schema | `npx prisma migrate dev --name name` | `npx prisma migrate deploy` |
|
|
161
|
+
| **Atlas** | HCL/SQL/ORM | `atlas migrate diff name` | `atlas migrate apply` |
|
|
162
|
+
| **migra** | SQL files | `migra $DB schemas/` | `psql $DB -f file.sql` |
|
|
163
|
+
| **Flyway** | SQL files | N/A (imperative) | `flyway migrate` |
|
|
164
|
+
| **Laravel** | PHP | `php artisan make:migration` | `php artisan migrate` |
|
|
165
|
+
| **Rails** | Ruby | `rails g migration` | `rails db:migrate` |
|
|
166
|
+
|
|
167
|
+
### Drizzle ORM (TypeScript)
|
|
168
|
+
|
|
169
|
+
Drizzle uses TypeScript schema files as the source of truth:
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// schemas/users.ts
|
|
173
|
+
import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';
|
|
174
|
+
|
|
175
|
+
export const users = pgTable('users', {
|
|
176
|
+
id: serial('id').primaryKey(),
|
|
177
|
+
email: text('email').notNull().unique(),
|
|
178
|
+
name: text('name'),
|
|
179
|
+
createdAt: timestamp('created_at').defaultNow(),
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# Generate migration from schema changes
|
|
185
|
+
npx drizzle-kit generate
|
|
186
|
+
|
|
187
|
+
# Apply migrations
|
|
188
|
+
npx drizzle-kit migrate
|
|
189
|
+
|
|
190
|
+
# Push directly (dev only, no migration file)
|
|
191
|
+
npx drizzle-kit push
|
|
192
|
+
|
|
193
|
+
# Pull existing DB schema to TypeScript
|
|
194
|
+
npx drizzle-kit pull
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Atlas (Universal)
|
|
198
|
+
|
|
199
|
+
Atlas works with HCL, SQL, or any ORM schema:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Declarative: apply schema directly
|
|
203
|
+
atlas schema apply -u "postgres://..." --to file://schema.sql
|
|
204
|
+
|
|
205
|
+
# Versioned: generate migration file
|
|
206
|
+
atlas migrate diff add_users \
|
|
207
|
+
--dir "file://migrations" \
|
|
208
|
+
--to "file://schema.sql" \
|
|
209
|
+
--dev-url "docker://postgres/15"
|
|
210
|
+
|
|
211
|
+
# Apply versioned migrations
|
|
212
|
+
atlas migrate apply -u "postgres://..."
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Known Limitations
|
|
216
|
+
|
|
217
|
+
Some entities require manual migrations (not captured by diff tools):
|
|
218
|
+
|
|
219
|
+
- DML statements (`INSERT`, `UPDATE`, `DELETE`)
|
|
220
|
+
- RLS policy modifications
|
|
221
|
+
- View ownership and grants
|
|
222
|
+
- Materialized views
|
|
223
|
+
- Table partitions
|
|
224
|
+
- Comments
|
|
225
|
+
- Some ALTER POLICY statements
|
|
226
|
+
|
|
227
|
+
For these, create manual migration files alongside generated ones.
|
|
228
|
+
|
|
229
|
+
## Naming Convention
|
|
230
|
+
|
|
231
|
+
### Timestamp-Based (Recommended)
|
|
232
|
+
|
|
233
|
+
```text
|
|
234
|
+
{YYYYMMDDHHMMSS}_{action}_{target}_{details}.sql
|
|
235
|
+
|
|
236
|
+
Examples:
|
|
237
|
+
20240502100843_create_users_table.sql
|
|
238
|
+
20240502101659_add_email_to_users.sql
|
|
239
|
+
20240503142030_drop_legacy_sessions_table.sql
|
|
240
|
+
20240504083015_add_index_email_unique_to_users.sql
|
|
241
|
+
20240505091200_rename_name_to_full_name_in_users.sql
|
|
242
|
+
```text
|
|
243
|
+
|
|
244
|
+
### Action Prefixes
|
|
245
|
+
|
|
246
|
+
| Prefix | Purpose | Example |
|
|
247
|
+
|--------|---------|---------|
|
|
248
|
+
| `create_` | New table | `create_users_table.sql` |
|
|
249
|
+
| `add_` | New column/index | `add_email_to_users.sql` |
|
|
250
|
+
| `drop_` | Remove table/column | `drop_legacy_table.sql` |
|
|
251
|
+
| `rename_` | Rename column/table | `rename_name_to_full_name_in_users.sql` |
|
|
252
|
+
| `alter_` | Modify column type | `alter_price_to_decimal_in_products.sql` |
|
|
253
|
+
| `seed_` | Initial data | `seed_default_roles.sql` |
|
|
254
|
+
| `backfill_` | Data migration | `backfill_user_status.sql` |
|
|
255
|
+
|
|
256
|
+
### Bad Names to Avoid
|
|
257
|
+
|
|
258
|
+
```text
|
|
259
|
+
migration_1.sql # Not descriptive
|
|
260
|
+
fix_stuff.sql # Vague
|
|
261
|
+
20240502_changes.sql # No specificity
|
|
262
|
+
update_db.sql # Meaningless
|
|
263
|
+
```text
|
|
264
|
+
|
|
265
|
+
## File Structure
|
|
266
|
+
|
|
267
|
+
### Up/Down Pattern (Required)
|
|
268
|
+
|
|
269
|
+
Every migration MUST have both up and down sections:
|
|
270
|
+
|
|
271
|
+
```sql
|
|
272
|
+
-- migrations/20240502100843_create_users_table.sql
|
|
273
|
+
|
|
274
|
+
-- ====== UP ======
|
|
275
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
276
|
+
id SERIAL PRIMARY KEY,
|
|
277
|
+
email VARCHAR(255) NOT NULL UNIQUE,
|
|
278
|
+
name VARCHAR(255),
|
|
279
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
280
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
CREATE INDEX idx_users_email ON users(email);
|
|
284
|
+
|
|
285
|
+
-- ====== DOWN ======
|
|
286
|
+
DROP INDEX IF EXISTS idx_users_email;
|
|
287
|
+
DROP TABLE IF EXISTS users;
|
|
288
|
+
```text
|
|
289
|
+
|
|
290
|
+
### Idempotent Migrations (Preferred)
|
|
291
|
+
|
|
292
|
+
Write migrations that can run multiple times safely:
|
|
293
|
+
|
|
294
|
+
```sql
|
|
295
|
+
-- PostgreSQL
|
|
296
|
+
CREATE TABLE IF NOT EXISTS users (...);
|
|
297
|
+
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
|
298
|
+
|
|
299
|
+
-- Column addition (PostgreSQL)
|
|
300
|
+
DO $$
|
|
301
|
+
BEGIN
|
|
302
|
+
IF NOT EXISTS (
|
|
303
|
+
SELECT 1 FROM information_schema.columns
|
|
304
|
+
WHERE table_name = 'users' AND column_name = 'phone'
|
|
305
|
+
) THEN
|
|
306
|
+
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
|
|
307
|
+
END IF;
|
|
308
|
+
END $$;
|
|
309
|
+
|
|
310
|
+
-- MySQL
|
|
311
|
+
CREATE TABLE IF NOT EXISTS users (...);
|
|
312
|
+
-- MySQL doesn't support IF NOT EXISTS for indexes, use procedures
|
|
313
|
+
```text
|
|
314
|
+
|
|
315
|
+
## Directory Structure
|
|
316
|
+
|
|
317
|
+
```text
|
|
318
|
+
project/
|
|
319
|
+
├── migrations/
|
|
320
|
+
│ ├── 20240502100843_create_users_table.sql
|
|
321
|
+
│ ├── 20240502101659_add_email_to_users.sql
|
|
322
|
+
│ └── 20240503142030_create_products_table.sql
|
|
323
|
+
├── seeds/
|
|
324
|
+
│ ├── 001_base_data.sql # Required reference data
|
|
325
|
+
│ └── 002_test_data.sql # Development/test data
|
|
326
|
+
└── scripts/
|
|
327
|
+
├── migrate.sh # Run pending migrations
|
|
328
|
+
└── rollback.sh # Rollback last migration
|
|
329
|
+
```text
|
|
330
|
+
|
|
331
|
+
## Schema vs Data Migrations
|
|
332
|
+
|
|
333
|
+
**Keep them separate:**
|
|
334
|
+
|
|
335
|
+
```sql
|
|
336
|
+
-- V6__add_status_column.sql (Schema - fast, reversible)
|
|
337
|
+
ALTER TABLE orders ADD COLUMN status VARCHAR(20) DEFAULT 'pending';
|
|
338
|
+
|
|
339
|
+
-- V7__backfill_order_status.sql (Data - slow, may be irreversible)
|
|
340
|
+
UPDATE orders SET status = 'completed' WHERE shipped_at IS NOT NULL;
|
|
341
|
+
UPDATE orders SET status = 'pending' WHERE shipped_at IS NULL;
|
|
342
|
+
```text
|
|
343
|
+
|
|
344
|
+
## Rollback Strategies
|
|
345
|
+
|
|
346
|
+
### Reversible Operations
|
|
347
|
+
|
|
348
|
+
| Operation | Rollback |
|
|
349
|
+
|-----------|----------|
|
|
350
|
+
| `CREATE TABLE` | `DROP TABLE` |
|
|
351
|
+
| `ADD COLUMN` | `DROP COLUMN` |
|
|
352
|
+
| `CREATE INDEX` | `DROP INDEX` |
|
|
353
|
+
| `ADD CONSTRAINT` | `DROP CONSTRAINT` |
|
|
354
|
+
|
|
355
|
+
### Irreversible Operations
|
|
356
|
+
|
|
357
|
+
| Operation | Why | Mitigation |
|
|
358
|
+
|-----------|-----|------------|
|
|
359
|
+
| `DROP TABLE` | Data lost | Backup first, or rename instead |
|
|
360
|
+
| `DROP COLUMN` | Data lost | Backup column data first |
|
|
361
|
+
| `TRUNCATE` | Data lost | Never use in migrations |
|
|
362
|
+
| Data `UPDATE` | Original values lost | Store originals in backup table |
|
|
363
|
+
|
|
364
|
+
### Marking Irreversible Migrations
|
|
365
|
+
|
|
366
|
+
```sql
|
|
367
|
+
-- ====== DOWN ======
|
|
368
|
+
-- IRREVERSIBLE: This migration cannot be rolled back.
|
|
369
|
+
-- Data was permanently deleted. Restore from backup if needed.
|
|
370
|
+
SELECT 'This migration is irreversible' AS warning;
|
|
371
|
+
-- Or raise an error:
|
|
372
|
+
-- RAISE EXCEPTION 'Cannot rollback: data was deleted';
|
|
373
|
+
```text
|
|
374
|
+
|
|
375
|
+
## Production Safety
|
|
376
|
+
|
|
377
|
+
### Expand-Contract Pattern
|
|
378
|
+
|
|
379
|
+
For risky changes (rename column, change type), use three phases:
|
|
380
|
+
|
|
381
|
+
```sql
|
|
382
|
+
-- Phase 1: EXPAND (add new, keep old)
|
|
383
|
+
-- 20240601_add_email_new_to_users.sql
|
|
384
|
+
ALTER TABLE users ADD COLUMN email_new VARCHAR(255);
|
|
385
|
+
UPDATE users SET email_new = email;
|
|
386
|
+
|
|
387
|
+
-- Phase 2: APPLICATION UPDATE
|
|
388
|
+
-- Deploy code that writes to BOTH columns, reads from new
|
|
389
|
+
|
|
390
|
+
-- Phase 3: CONTRACT (remove old)
|
|
391
|
+
-- 20240615_drop_old_email_from_users.sql
|
|
392
|
+
ALTER TABLE users DROP COLUMN email;
|
|
393
|
+
ALTER TABLE users RENAME COLUMN email_new TO email;
|
|
394
|
+
```text
|
|
395
|
+
|
|
396
|
+
### Safe Operations Checklist
|
|
397
|
+
|
|
398
|
+
| Operation | Safe? | Strategy |
|
|
399
|
+
|-----------|-------|----------|
|
|
400
|
+
| Add nullable column | ✅ | Direct |
|
|
401
|
+
| Add NOT NULL column | ⚠️ | Add nullable → backfill → add constraint |
|
|
402
|
+
| Drop column | ⚠️ | Remove from code first → wait → drop |
|
|
403
|
+
| Rename column | ⚠️ | Expand-contract pattern |
|
|
404
|
+
| Add index | ⚠️ | Use `CONCURRENTLY` (PostgreSQL) |
|
|
405
|
+
| Change column type | ⚠️ | Create new column → migrate → drop old |
|
|
406
|
+
|
|
407
|
+
### Concurrent Index Creation (PostgreSQL)
|
|
408
|
+
|
|
409
|
+
```sql
|
|
410
|
+
-- ✅ Safe: Non-blocking
|
|
411
|
+
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
|
|
412
|
+
|
|
413
|
+
-- ⚠️ Blocks writes during creation
|
|
414
|
+
CREATE INDEX idx_users_email ON users(email);
|
|
415
|
+
```text
|
|
416
|
+
|
|
417
|
+
## Git Workflow Integration
|
|
418
|
+
|
|
419
|
+
### Branch Naming
|
|
420
|
+
|
|
421
|
+
When creating migrations, use appropriate branch type:
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
# Schema changes
|
|
425
|
+
git checkout -b feature/add-user-preferences-table
|
|
426
|
+
|
|
427
|
+
# Bug fixes to schema
|
|
428
|
+
git checkout -b bugfix/fix-orders-foreign-key
|
|
429
|
+
|
|
430
|
+
# Data migrations
|
|
431
|
+
git checkout -b chore/backfill-user-status
|
|
432
|
+
```text
|
|
433
|
+
|
|
434
|
+
### Commit Messages
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
# Schema migrations
|
|
438
|
+
git commit -m "feat(db): add user_preferences table with indexes"
|
|
439
|
+
git commit -m "feat(db): add email column to users table"
|
|
440
|
+
|
|
441
|
+
# Data migrations
|
|
442
|
+
git commit -m "chore(db): backfill user status from legacy field"
|
|
443
|
+
|
|
444
|
+
# Fixes
|
|
445
|
+
git commit -m "fix(db): correct foreign key constraint on orders"
|
|
446
|
+
```text
|
|
447
|
+
|
|
448
|
+
### Pre-Push Checklist
|
|
449
|
+
|
|
450
|
+
Before pushing migration files:
|
|
451
|
+
|
|
452
|
+
1. ✅ Migration has both UP and DOWN sections
|
|
453
|
+
2. ✅ DOWN section actually reverses the UP changes
|
|
454
|
+
3. ✅ Tested locally (run up, run down, run up again)
|
|
455
|
+
4. ✅ No modifications to already-pushed migrations
|
|
456
|
+
5. ✅ Timestamp is current (regenerate if rebasing)
|
|
457
|
+
|
|
458
|
+
## Team Collaboration
|
|
459
|
+
|
|
460
|
+
### Avoiding Conflicts
|
|
461
|
+
|
|
462
|
+
1. **Pull before creating** new migrations
|
|
463
|
+
2. **Use timestamps** (not sequential numbers) for ordering
|
|
464
|
+
3. **One migration per PR** when possible
|
|
465
|
+
4. **Rebase carefully** - may need to regenerate timestamps
|
|
466
|
+
|
|
467
|
+
### Conflict Resolution
|
|
468
|
+
|
|
469
|
+
If two developers create migrations with same timestamp:
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
# Developer B rebases and regenerates timestamp
|
|
473
|
+
git rebase main
|
|
474
|
+
# Rename migration file with new timestamp
|
|
475
|
+
mv migrations/20240502100843_add_phone.sql \
|
|
476
|
+
migrations/20240502101530_add_phone.sql
|
|
477
|
+
```text
|
|
478
|
+
|
|
479
|
+
### Never Modify Pushed Migrations
|
|
480
|
+
|
|
481
|
+
Once a migration is pushed to a shared branch:
|
|
482
|
+
|
|
483
|
+
```text
|
|
484
|
+
❌ NEVER edit the migration file
|
|
485
|
+
❌ NEVER rename the migration file
|
|
486
|
+
❌ NEVER delete the migration file
|
|
487
|
+
|
|
488
|
+
✅ Create a NEW migration to fix issues
|
|
489
|
+
✅ Create a NEW migration to rollback changes
|
|
490
|
+
```text
|
|
491
|
+
|
|
492
|
+
## CI/CD Integration
|
|
493
|
+
|
|
494
|
+
### GitHub Actions Example
|
|
495
|
+
|
|
496
|
+
```yaml
|
|
497
|
+
name: Database Migration
|
|
498
|
+
on:
|
|
499
|
+
push:
|
|
500
|
+
branches: [main]
|
|
501
|
+
paths:
|
|
502
|
+
- 'migrations/**'
|
|
503
|
+
|
|
504
|
+
jobs:
|
|
505
|
+
migrate:
|
|
506
|
+
runs-on: ubuntu-latest
|
|
507
|
+
steps:
|
|
508
|
+
- uses: actions/checkout@v4
|
|
509
|
+
|
|
510
|
+
- name: Backup database
|
|
511
|
+
run: |
|
|
512
|
+
pg_dump $DATABASE_URL > backup_$(date +%Y%m%d_%H%M%S).sql
|
|
513
|
+
env:
|
|
514
|
+
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
515
|
+
|
|
516
|
+
- name: Run migrations
|
|
517
|
+
run: |
|
|
518
|
+
# Your migration tool command
|
|
519
|
+
flyway migrate
|
|
520
|
+
# OR: npx prisma migrate deploy
|
|
521
|
+
# OR: bundle exec rails db:migrate
|
|
522
|
+
env:
|
|
523
|
+
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
524
|
+
|
|
525
|
+
- name: Verify migration
|
|
526
|
+
run: |
|
|
527
|
+
# Run a simple query to verify database is accessible
|
|
528
|
+
psql $DATABASE_URL -c "SELECT 1"
|
|
529
|
+
```text
|
|
530
|
+
|
|
531
|
+
## Tool-Specific Patterns
|
|
532
|
+
|
|
533
|
+
### Flyway
|
|
534
|
+
|
|
535
|
+
```text
|
|
536
|
+
migrations/
|
|
537
|
+
├── V1__create_users.sql
|
|
538
|
+
├── V2__add_email_to_users.sql
|
|
539
|
+
├── R__refresh_views.sql # Repeatable
|
|
540
|
+
└── U2__undo_add_email.sql # Undo
|
|
541
|
+
```text
|
|
542
|
+
|
|
543
|
+
### Prisma
|
|
544
|
+
|
|
545
|
+
```bash
|
|
546
|
+
npx prisma migrate dev --name add_user_email # Development
|
|
547
|
+
npx prisma migrate deploy # Production
|
|
548
|
+
npx prisma migrate reset # Reset (dev only)
|
|
549
|
+
```text
|
|
550
|
+
|
|
551
|
+
### Laravel
|
|
552
|
+
|
|
553
|
+
```bash
|
|
554
|
+
php artisan make:migration create_users_table
|
|
555
|
+
php artisan migrate
|
|
556
|
+
php artisan migrate:rollback
|
|
557
|
+
php artisan migrate:fresh --seed # Dev only
|
|
558
|
+
```text
|
|
559
|
+
|
|
560
|
+
### Rails
|
|
561
|
+
|
|
562
|
+
```bash
|
|
563
|
+
rails generate migration CreateUsers
|
|
564
|
+
rails db:migrate
|
|
565
|
+
rails db:rollback
|
|
566
|
+
rails db:migrate:redo # Rollback + migrate
|
|
567
|
+
```text
|
|
568
|
+
|
|
569
|
+
### Raw SQL (Framework-Agnostic)
|
|
570
|
+
|
|
571
|
+
```bash
|
|
572
|
+
# Simple migration runner script
|
|
573
|
+
#!/bin/bash
|
|
574
|
+
for f in migrations/*.sql; do
|
|
575
|
+
echo "Running $f..."
|
|
576
|
+
psql $DATABASE_URL -f "$f"
|
|
577
|
+
done
|
|
578
|
+
```text
|
|
579
|
+
|
|
580
|
+
## Rollback Procedures
|
|
581
|
+
|
|
582
|
+
### Single Migration Rollback
|
|
583
|
+
|
|
584
|
+
```bash
|
|
585
|
+
# Extract and run DOWN section
|
|
586
|
+
# Most tools have built-in commands:
|
|
587
|
+
flyway undo
|
|
588
|
+
npx prisma migrate resolve --rolled-back 20240502100843_add_email
|
|
589
|
+
rails db:rollback STEP=1
|
|
590
|
+
php artisan migrate:rollback --step=1
|
|
591
|
+
```text
|
|
592
|
+
|
|
593
|
+
### Point-in-Time Recovery
|
|
594
|
+
|
|
595
|
+
For catastrophic failures, restore from backup:
|
|
596
|
+
|
|
597
|
+
```bash
|
|
598
|
+
# PostgreSQL
|
|
599
|
+
pg_restore -d dbname backup_before_migration.dump
|
|
600
|
+
|
|
601
|
+
# MySQL
|
|
602
|
+
mysql dbname < backup_before_migration.sql
|
|
603
|
+
```text
|
|
604
|
+
|
|
605
|
+
## Migration Tracking Table
|
|
606
|
+
|
|
607
|
+
Most tools create a tracking table:
|
|
608
|
+
|
|
609
|
+
```sql
|
|
610
|
+
-- Example: Flyway schema_history
|
|
611
|
+
CREATE TABLE flyway_schema_history (
|
|
612
|
+
installed_rank INT PRIMARY KEY,
|
|
613
|
+
version VARCHAR(50),
|
|
614
|
+
description VARCHAR(200),
|
|
615
|
+
type VARCHAR(20),
|
|
616
|
+
script VARCHAR(1000),
|
|
617
|
+
checksum INT,
|
|
618
|
+
installed_by VARCHAR(100),
|
|
619
|
+
installed_on TIMESTAMP,
|
|
620
|
+
execution_time INT,
|
|
621
|
+
success BOOLEAN
|
|
622
|
+
);
|
|
623
|
+
```text
|
|
624
|
+
|
|
625
|
+
Query to see migration status:
|
|
626
|
+
|
|
627
|
+
```sql
|
|
628
|
+
SELECT version, description, installed_on, success
|
|
629
|
+
FROM flyway_schema_history
|
|
630
|
+
ORDER BY installed_rank;
|
|
631
|
+
```text
|