[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6D7XZN3AEZ0F46HXWHQYYEE":3,"skill-same:01M6D7XZN3AEZ0F46HXWHQYYEE":100},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":6,"ownerHtmlUrl":48,"ownerBlogUrl":49,"ownerDescription":50,"updatedAt":51,"install":52,"resources":65},"01M6D7XZN3AEZ0F46HXWHQYYEE","database-migrations",null,"数据库迁移最佳实践，涵盖模式变更、数据迁移、回滚以及零停机部署，适用于PostgreSQL、MySQL及常用ORM（Prisma、Drizzle、Django、TypeORM、golang-migrate）。","oabdelmaksoud\u002FSuperClaw","oabdelmaksoud","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F50699149?v=4","01M6D5CVVN778ZCDP1WHS816SP","Omar Abdelmaksoud","01M6D5CW1RHNSKCJR85GJACBFT",2,"MIT","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fdocs\u002Fzh-CN\u002Fskills\u002Fdatabase-migrations\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36],"database","database migrations","migrations","golang","migrate","django","typeorm","prisma","2026-11-10 10:12:30",false,"---\nname: database-migrations\ndescription: 数据库迁移最佳实践，涵盖模式变更、数据迁移、回滚以及零停机部署，适用于PostgreSQL、MySQL及常用ORM（Prisma、Drizzle、Django、TypeORM、golang-migrate）。\norigin: ECC\n---\n\n# 数据库迁移模式\n\n为生产系统提供安全、可逆的数据库模式变更。\n\n## 何时激活\n\n* 创建或修改数据库表\n* 添加\u002F删除列或索引\n* 运行数据迁移（回填、转换）\n* 计划零停机模式变更\n* 为新项目设置迁移工具\n\n## 核心原则\n\n1. **每个变更都是一次迁移** — 切勿手动更改生产数据库\n2. **迁移在生产环境中是只进不退的** — 回滚使用新的前向迁移\n3. **模式迁移和数据迁移是分开的** — 切勿在一个迁移中混合 DDL 和 DML\n4. **针对生产规模的数据测试迁移** — 适用于 100 行的迁移可能在 1000 万行时锁定\n5. **迁移一旦部署就是不可变的** — 切勿编辑已在生产中运行的迁移\n\n## 迁移安全检查清单\n\n应用任何迁移之前：\n\n* \\[ ] 迁移同时包含 UP 和 DOWN（或明确标记为不可逆）\n* \\[ ] 对大表没有全表锁（使用并发操作）\n* \\[ ] 新列有默认值或可为空（切勿添加没有默认值的 NOT NULL）\n* \\[ ] 索引是并发创建的（对于现有表，不与 CREATE TABLE 内联创建）\n* \\[ ] 数据回填是与模式变更分开的迁移\n* \\[ ] 已针对生产数据副本进行测试\n* \\[ ] 回滚计划已记录\n\n## PostgreSQL 模式\n\n### 安全地添加列\n\n```sql\n-- GOOD: Nullable column, no lock\nALTER TABLE users ADD COLUMN avatar_url TEXT;\n\n-- GOOD: Column with default (Postgres 11+ is instant, no rewrite)\nALTER TABLE users ADD COLUMN is_active BOOLEAN NOT NULL DEFAULT true;\n\n-- BAD: NOT NULL without default on existing table (requires full rewrite)\nALTER TABLE users ADD COLUMN role TEXT NOT NULL;\n-- This locks the table and rewrites every row\n```\n\n### 无停机添加索引\n\n```sql\n-- BAD: Blocks writes on large tables\nCREATE INDEX idx_users_email ON users (email);\n\n-- GOOD: Non-blocking, allows concurrent writes\nCREATE INDEX CONCURRENTLY idx_users_email ON users (email);\n\n-- Note: CONCURRENTLY cannot run inside a transaction block\n-- Most migration tools need special handling for this\n```\n\n### 重命名列（零停机）\n\n切勿在生产中直接重命名。使用扩展-收缩模式：\n\n```sql\n-- Step 1: Add new column (migration 001)\nALTER TABLE users ADD COLUMN display_name TEXT;\n\n-- Step 2: Backfill data (migration 002, data migration)\nUPDATE users SET display_name = username WHERE display_name IS NULL;\n\n-- Step 3: Update application code to read\u002Fwrite both columns\n-- Deploy application changes\n\n-- Step 4: Stop writing to old column, drop it (migration 003)\nALTER TABLE users DROP COLUMN username;\n```\n\n### 安全地删除列\n\n```sql\n-- Step 1: Remove all application references to the column\n-- Step 2: Deploy application without the column reference\n-- Step 3: Drop column in next migration\nALTER TABLE orders DROP COLUMN legacy_status;\n\n-- For Django: use SeparateDatabaseAndState to remove from model\n-- without generating DROP COLUMN (then drop in next migration)\n```\n\n### 大型数据迁移\n\n```sql\n-- BAD: Updates all rows in one transaction (locks table)\nUPDATE users SET normalized_email = LOWER(email);\n\n-- GOOD: Batch update with progress\nDO $$\nDECLARE\n  batch_size INT := 10000;\n  rows_updated INT;\nBEGIN\n  LOOP\n    UPDATE users\n    SET normalized_email = LOWER(email)\n    WHERE id IN (\n      SELECT id FROM users\n      WHERE normalized_email IS NULL\n      LIMIT batch_size\n      FOR UPDATE SKIP LOCKED\n    );\n    GET DIAGNOSTICS rows_updated = ROW_COUNT;\n    RAISE NOTICE 'Updated % rows', rows_updated;\n    EXIT WHEN rows_updated = 0;\n    COMMIT;\n  END LOOP;\nEND $$;\n```\n\n## Prisma (TypeScript\u002FNode.js)\n\n### 工作流\n\n```bash\n# Create migration from schema changes\nnpx prisma migrate dev --name add_user_avatar\n\n# Apply pending migrations in production\nnpx prisma migrate deploy\n\n# Reset database (dev only)\nnpx prisma migrate reset\n\n# Generate client after schema changes\nnpx prisma generate\n```\n\n### 模式示例\n\n```prisma\nmodel User {\n  id        String   @id @default(cuid())\n  email     String   @unique\n  name      String?\n  avatarUrl String?  @map(\"avatar_url\")\n  createdAt DateTime @default(now()) @map(\"created_at\")\n  updatedAt DateTime @updatedAt @map(\"updated_at\")\n  orders    Order[]\n\n  @@map(\"users\")\n  @@index([email])\n}\n```\n\n### 自定义 SQL 迁移\n\n对于 Prisma 无法表达的操作（并发索引、数据回填）：\n\n```bash\n# Create empty migration, then edit the SQL manually\nnpx prisma migrate dev --create-only --name add_email_index\n```\n\n```sql\n-- migrations\u002F20240115_add_email_index\u002Fmigration.sql\n-- Prisma cannot generate CONCURRENTLY, so we write it manually\nCREATE INDEX CONCURRENTLY IF NOT EXISTS idx_users_email ON users (email);\n```\n\n## Drizzle (TypeScript\u002FNode.js)\n\n### 工作流\n\n```bash\n# Generate migration from schema changes\nnpx drizzle-kit generate\n\n# Apply migrations\nnpx drizzle-kit migrate\n\n# Push schema directly (dev only, no migration file)\nnpx drizzle-kit push\n```\n\n### 模式示例\n\n```typescript\nimport { pgTable, text, timestamp, uuid, boolean } from \"drizzle-orm\u002Fpg-core\";\n\nexport const users = pgTable(\"users\", {\n  id: uuid(\"id\").primaryKey().defaultRandom(),\n  email: text(\"email\").notNull().unique(),\n  name: text(\"name\"),\n  isActive: boolean(\"is_active\").notNull().default(true),\n  createdAt: timestamp(\"created_at\").notNull().defaultNow(),\n  updatedAt: timestamp(\"updated_at\").notNull().defaultNow(),\n});\n```\n\n## Django (Python)\n\n### 工作流\n\n```bash\n# Generate migration from model changes\npython manage.py makemigrations\n\n# Apply migrations\npython manage.py migrate\n\n# Show migration status\npython manage.py showmigrations\n\n# Generate empty migration for custom SQL\npython manage.py makemigrations --empty app_name -n description\n```\n\n### 数据迁移\n\n```python\nfrom django.db import migrations\n\ndef backfill_display_names(apps, schema_editor):\n    User = apps.get_model(\"accounts\", \"User\")\n    batch_size = 5000\n    users = User.objects.filter(display_name=\"\")\n    while users.exists():\n        batch = list(users[:batch_size])\n        for user in batch:\n            user.display_name = user.username\n        User.objects.bulk_update(batch, [\"display_name\"], batch_size=batch_size)\n\ndef reverse_backfill(apps, schema_editor):\n    pass  # Data migration, no reverse needed\n\nclass Migration(migrations.Migration):\n    dependencies = [(\"accounts\", \"0015_add_display_name\")]\n\n    operations = [\n        migrations.RunPython(backfill_display_names, reverse_backfill),\n    ]\n```\n\n### SeparateDatabaseAndState\n\n从 Django 模型中删除列，而不立即从数据库中删除：\n\n```python\nclass Migration(migrations.Migration):\n    operations = [\n        migrations.SeparateDatabaseAndState(\n            state_operations=[\n                migrations.RemoveField(model_name=\"user\", name=\"legacy_field\"),\n            ],\n            database_operations=[],  # Don't touch the DB yet\n        ),\n    ]\n```\n\n## golang-migrate (Go)\n\n### 工作流\n\n```bash\n# Create migration pair\nmigrate create -ext sql -dir migrations -seq add_user_avatar\n\n# Apply all pending migrations\nmigrate -path migrations -database \"$DATABASE_URL\" up\n\n# Rollback last migration\nmigrate -path migrations -database \"$DATABASE_URL\" down 1\n\n# Force version (fix dirty state)\nmigrate -path migrations -database \"$DATABASE_URL\" force VERSION\n```\n\n### 迁移文件\n\n```sql\n-- migrations\u002F000003_add_user_avatar.up.sql\nALTER TABLE users ADD COLUMN avatar_url TEXT;\nCREATE INDEX CONCURRENTLY idx_users_avatar ON users (avatar_url) WHERE avatar_url IS NOT NULL;\n\n-- migrations\u002F000003_add_user_avatar.down.sql\nDROP INDEX IF EXISTS idx_users_avatar;\nALTER TABLE users DROP COLUMN IF EXISTS avatar_url;\n```\n\n## 零停机迁移策略\n\n对于关键的生产变更，遵循扩展-收缩模式：\n\n```\nPhase 1: EXPAND\n  - Add new column\u002Ftable (nullable or with default)\n  - Deploy: app writes to BOTH old and new\n  - Backfill existing data\n\nPhase 2: MIGRATE\n  - Deploy: app reads from NEW, writes to BOTH\n  - Verify data consistency\n\nPhase 3: CONTRACT\n  - Deploy: app only uses NEW\n  - Drop old column\u002Ftable in separate migration\n```\n\n### 时间线示例\n\n```\nDay 1: Migration adds new_status column (nullable)\nDay 1: Deploy app v2 — writes to both status and new_status\nDay 2: Run backfill migration for existing rows\nDay 3: Deploy app v3 — reads from new_status only\nDay 7: Migration drops old status column\n```\n\n## 反模式\n\n| 反模式 | 为何会失败 | 更好的方法 |\n|-------------|-------------|-----------------|\n| 在生产中手动执行 SQL | 没有审计追踪，不可重复 | 始终使用迁移文件 |\n| 编辑已部署的迁移 | 导致环境间出现差异 | 改为创建新迁移 |\n| 没有默认值的 NOT NULL | 锁定表，重写所有行 | 添加可为空列，回填数据，然后添加约束 |\n| 在大表上内联创建索引 | 在构建期间阻塞写入 | 使用 CREATE INDEX CONCURRENTLY |\n| 在一个迁移中混合模式和数据的变更 | 难以回滚，事务时间长 | 分开的迁移 |\n| 在移除代码之前删除列 | 应用程序在缺失列时出错 | 先移除代码，下一次部署再删除列 |\n","# 数据库迁移模式\n\n为生产系统提供安全、可逆的数据库模式变更。\n\n## 何时激活\n\n* 创建或修改数据库表\n* 添加\u002F删除列或索引\n* 运行数据迁移（回填、转换）\n* 计划零停机模式变更\n* 为新项目设置迁移工具\n\n## 核心原则\n\n1. **每个变更都是一次迁移** — 切勿手动更改生产数据库\n2. **迁移在生产环境中是只进不退的** — 回滚使用新的前向迁移\n3. **模式迁移和数据迁移是分开的** — 切勿在一个迁移中混合 DDL 和 DML\n4. **针对生产规模的数据测试迁移** — 适用于 100 行的迁移可能在 1000 万行时锁定\n5. **迁移一旦部署就是不可变的** — 切勿编辑已在生产中运行的迁移\n\n## 迁移安全检查清单\n\n应用任何迁移之前：\n\n* \\[ ] 迁移同时包含 UP 和 DOWN（或明确标记为不可逆）\n* \\[ ] 对大表没有全表锁（使用并发操作）\n* \\[ ] 新列有默认值或可为空（切勿添加没有默认值的 NOT NULL）\n* \\[ ] 索引是并发创建的（对于现有表，不与 CREATE TABLE 内联创建）\n* \\[ ] 数据回填是与模式变更分开的迁移\n* \\[ ] 已针对生产数据副本进行测试\n* \\[ ] 回滚计划已记录\n\n## PostgreSQL 模式\n\n### 安全地添加列\n\n```sql\n-- GOOD: Nullable column, no lock\nALTER TABLE users ADD COLUMN avatar_url TEXT;\n\n-- GOOD: Column with default (Postgres 11+ is instant, no rewrite)\nALTER TABLE users ADD COLUMN is_active BOOLEAN NOT NULL DEFAULT true;\n\n-- BAD: NOT NULL without default on existing table (requires full rewrite)\nALTER TABLE users ADD COLUMN role TEXT NOT NULL;\n-- This locks the table and rewrites every row\n```\n\n### 无停机添加索引\n\n```sql\n-- BAD: Blocks writes on large tables\nCREATE INDEX idx_users_email ON users (email);\n\n-- GOOD: Non-blocking, allows concurrent writes\nCREATE INDEX CONCURRENTLY idx_users_email ON users (email);\n\n-- Note: CONCURRENTLY cannot run inside a transaction block\n-- Most migration tools need special handling for this\n```\n\n### 重命名列（零停机）\n\n切勿在生产中直接重命名。使用扩展-收缩模式：\n\n```sql\n-- Step 1: Add new column (migration 001)\nALTER TABLE users ADD COLUMN display_name TEXT;\n\n-- Step 2: Backfill data (migration 002, data migration)\nUPDATE users SET display_name = username WHERE display_name IS NULL;\n\n-- Step 3: Update application code to read\u002Fwrite both columns\n-- Deploy application changes\n\n-- Step 4: Stop writing to old column, drop it (migration 003)\nALTER TABLE users DROP COLUMN username;\n```\n\n### 安全地删除列\n\n```sql\n-- Step 1: Remove all application references to the column\n-- Step 2: Deploy application without the column reference\n-- Step 3: Drop column in next migration\nALTER TABLE orders DROP COLUMN legacy_status;\n\n-- For Django: use SeparateDatabaseAndState to remove from model\n-- without generating DROP COLUMN (then drop in next migration)\n```\n\n### 大型数据迁移\n\n```sql\n-- BAD: Updates all rows in one transaction (locks table)\nUPDATE users SET normalized_email = LOWER(email);\n\n-- GOOD: Batch update with progress\nDO $$\nDECLARE\n  batch_size INT := 10000;\n  rows_updated INT;\nBEGIN\n  LOOP\n    UPDATE users\n    SET normalized_email = LOWER(email)\n    WHERE id IN (\n      SELECT id FROM users\n      WHERE normalized_email IS NULL\n      LIMIT batch_size\n      FOR UPDATE SKIP LOCKED\n    );\n    GET DIAGNOSTICS rows_updated = ROW_COUNT;\n    RAISE NOTICE 'Updated % rows', rows_updated;\n    EXIT WHEN rows_updated = 0;\n    COMMIT;\n  END LOOP;\nEND $$;\n```\n\n## Prisma (TypeScript\u002FNode.js)\n\n### 工作流\n\n```bash\n# Create migration from schema changes\nnpx prisma migrate dev --name add_user_avatar\n\n# Apply pending migrations in production\nnpx prisma migrate deploy\n\n# Reset database (dev only)\nnpx prisma migrate reset\n\n# Generate client after schema changes\nnpx prisma generate\n```\n\n### 模式示例\n\n```prisma\nmodel User {\n  id        String   @id @default(cuid())\n  email     String   @unique\n  name      String?\n  avatarUrl String?  @map(\"avatar_url\")\n  createdAt DateTime @default(now()) @map(\"created_at\")\n  updatedAt DateTime @updatedAt @map(\"updated_at\")\n  orders    Order[]\n\n  @@map(\"users\")\n  @@index([email])\n}\n```\n\n### 自定义 SQL 迁移\n\n对于 Prisma 无法表达的操作（并发索引、数据回填）：\n\n```bash\n# Create empty migration, then edit the SQL manually\nnpx prisma migrate dev --create-only --name add_email_index\n```\n\n```sql\n-- migrations\u002F20240115_add_email_index\u002Fmigration.sql\n-- Prisma cannot generate CONCURRENTLY, so we write it manually\nCREATE INDEX CONCURRENTLY IF NOT EXISTS idx_users_email ON users (email);\n```\n\n## Drizzle (TypeScript\u002FNode.js)\n\n### 工作流\n\n```bash\n# Generate migration from schema changes\nnpx drizzle-kit generate\n\n# Apply migrations\nnpx drizzle-kit migrate\n\n# Push schema directly (dev only, no migration file)\nnpx drizzle-kit push\n```\n\n### 模式示例\n\n```typescript\nimport { pgTable, text, timestamp, uuid, boolean } from \"drizzle-orm\u002Fpg-core\";\n\nexport const users = pgTable(\"users\", {\n  id: uuid(\"id\").primaryKey().defaultRandom(),\n  email: text(\"email\").notNull().unique(),\n  name: text(\"name\"),\n  isActive: boolean(\"is_active\").notNull().default(true),\n  createdAt: timestamp(\"created_at\").notNull().defaultNow(),\n  updatedAt: timestamp(\"updated_at\").notNull().defaultNow(),\n});\n```\n\n## Django (Python)\n\n### 工作流\n\n```bash\n# Generate migration from model changes\npython manage.py makemigrations\n\n# Apply migrations\npython manage.py migrate\n\n# Show migration status\npython manage.py showmigrations\n\n# Generate empty migration for custom SQL\npython manage.py makemigrations --empty app_name -n description\n```\n\n### 数据迁移\n\n```python\nfrom django.db import migrations\n\ndef backfill_display_names(apps, schema_editor):\n    User = apps.get_model(\"accounts\", \"User\")\n    batch_size = 5000\n    users = User.objects.filter(display_name=\"\")\n    while users.exists():\n        batch = list(users[:batch_size])\n        for user in batch:\n            user.display_name = user.username\n        User.objects.bulk_update(batch, [\"display_name\"], batch_size=batch_size)\n\ndef reverse_backfill(apps, schema_editor):\n    pass  # Data migration, no reverse needed\n\nclass Migration(migrations.Migration):\n    dependencies = [(\"accounts\", \"0015_add_display_name\")]\n\n    operations = [\n        migrations.RunPython(backfill_display_names, reverse_backfill),\n    ]\n```\n\n### SeparateDatabaseAndState\n\n从 Django 模型中删除列，而不立即从数据库中删除：\n\n```python\nclass Migration(migrations.Migration):\n    operations = [\n        migrations.SeparateDatabaseAndState(\n            state_operations=[\n                migrations.RemoveField(model_name=\"user\", name=\"legacy_field\"),\n            ],\n            database_operations=[],  # Don't touch the DB yet\n        ),\n    ]\n```\n\n## golang-migrate (Go)\n\n### 工作流\n\n```bash\n# Create migration pair\nmigrate create -ext sql -dir migrations -seq add_user_avatar\n\n# Apply all pending migrations\nmigrate -path migrations -database \"$DATABASE_URL\" up\n\n# Rollback last migration\nmigrate -path migrations -database \"$DATABASE_URL\" down 1\n\n# Force version (fix dirty state)\nmigrate -path migrations -database \"$DATABASE_URL\" force VERSION\n```\n\n### 迁移文件\n\n```sql\n-- migrations\u002F000003_add_user_avatar.up.sql\nALTER TABLE users ADD COLUMN avatar_url TEXT;\nCREATE INDEX CONCURRENTLY idx_users_avatar ON users (avatar_url) WHERE avatar_url IS NOT NULL;\n\n-- migrations\u002F000003_add_user_avatar.down.sql\nDROP INDEX IF EXISTS idx_users_avatar;\nALTER TABLE users DROP COLUMN IF EXISTS avatar_url;\n```\n\n## 零停机迁移策略\n\n对于关键的生产变更，遵循扩展-收缩模式：\n\n```\nPhase 1: EXPAND\n  - Add new column\u002Ftable (nullable or with default)\n  - Deploy: app writes to BOTH old and new\n  - Backfill existing data\n\nPhase 2: MIGRATE\n  - Deploy: app reads from NEW, writes to BOTH\n  - Verify data consistency\n\nPhase 3: CONTRACT\n  - Deploy: app only uses NEW\n  - Drop old column\u002Ftable in separate migration\n```\n\n### 时间线示例\n\n```\nDay 1: Migration adds new_status column (nullable)\nDay 1: Deploy app v2 — writes to both status and new_status\nDay 2: Run backfill migration for existing rows\nDay 3: Deploy app v3 — reads from new_status only\nDay 7: Migration drops old status column\n```\n\n## 反模式\n\n| 反模式 | 为何会失败 | 更好的方法 |\n|-------------|-------------|-----------------|\n| 在生产中手动执行 SQL | 没有审计追踪，不可重复 | 始终使用迁移文件 |\n| 编辑已部署的迁移 | 导致环境间出现差异 | 改为创建新迁移 |\n| 没有默认值的 NOT NULL | 锁定表，重写所有行 | 添加可为空列，回填数据，然后添加约束 |\n| 在大表上内联创建索引 | 在构建期间阻塞写入 | 使用 CREATE INDEX CONCURRENTLY |\n| 在一个迁移中混合模式和数据的变更 | 难以回滚，事务时间长 | 分开的迁移 |\n| 在移除代码之前删除列 | 应用程序在缺失列时出错 | 先移除代码，下一次部署再删除列 |\n",{"name":5,"origin":42,"description":7},"ECC","main","7b610356e36623652299fa2acb477ff821b1d920","upstream-sync\u002Fwork\u002Fecc\u002Fdocs\u002Fzh-CN\u002Fskills\u002Fdatabase-migrations",0,"https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fo-abdelmaksoud\u002F","Full-Stack Engineer | AI Systems Architect | Building autonomous multi-agent systems","2026-03-08 21:12:53",{"source":8,"skillName":5,"commands":53,"prompt":63,"zipAvailable":64},[54,57,60],{"tool":55,"command":56},"npx","npx skills add oabdelmaksoud\u002FSuperClaw --skill database-migrations",{"tool":58,"command":59},"bunx","bunx skills add oabdelmaksoud\u002FSuperClaw --skill database-migrations",{"tool":61,"command":62},"pnpm","pnpm dlx skills add oabdelmaksoud\u002FSuperClaw --skill database-migrations","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fdocs\u002Fzh-CN\u002Fskills\u002Fdatabase-migrations\u002FSKILL.md",true,[66,72,76,80,84,88,92,96],{"path":67,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":70,"sourceHtmlUrl":71},"references\u002Factivity-views.md","REFERENCE","参考文档",9205,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fhig-components-content\u002Freferences\u002Factivity-views.md",{"path":73,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":74,"sourceHtmlUrl":75},"references\u002Fcharts.md",25946,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fhig-components-content\u002Freferences\u002Fcharts.md",{"path":77,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":78,"sourceHtmlUrl":79},"references\u002Fcollections.md",3350,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fhig-components-content\u002Freferences\u002Fcollections.md",{"path":81,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":82,"sourceHtmlUrl":83},"references\u002Fcolor-wells.md",2715,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fhig-components-content\u002Freferences\u002Fcolor-wells.md",{"path":85,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":86,"sourceHtmlUrl":87},"references\u002Fimage-views.md",6676,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fhig-components-content\u002Freferences\u002Fimage-views.md",{"path":89,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":90,"sourceHtmlUrl":91},"references\u002Fimage-wells.md",2084,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fhig-components-content\u002Freferences\u002Fimage-wells.md",{"path":93,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":94,"sourceHtmlUrl":95},"references\u002Flockups.md",6145,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fhig-components-content\u002Freferences\u002Flockups.md",{"path":97,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":98,"sourceHtmlUrl":99},"references\u002Fweb-views.md",2303,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fhig-components-content\u002Freferences\u002Fweb-views.md",[101,120,134,163,189,208],{"skillNo":102,"name":103,"nameZh":6,"description":104,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":105,"categories":106,"keywords":110,"publishedAt":37},"01M6D88QCPTBZVCRED0NZ1Y8K8","visa-doc-translate","Translate visa application documents (images) to English and create a bilingual PDF with original and translation","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fvisa-doc-translate\u002FSKILL.md",[107],{"categoryNo":108,"categoryName":109,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000002","文档处理",[111,112,113,114,115,116,117,118,119],"translate","doc","visa doc translate","translation","application","create","images","PDF","documents",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":37},"01M6D88NBM95T3TFM50CYYAP65","verification-loop","A comprehensive verification system for Claude Code sessions.","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fverification-loop\u002FSKILL.md",[],[127,128,129,130,131,132,133],"verification","loop","verification loop","sessions","code","claude code sessions","system",{"skillNo":135,"name":136,"nameZh":6,"description":137,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":138,"categories":139,"keywords":149,"publishedAt":37},"01M6D88JFZ2P996GVRHJNSZSTM","tdd-workflow","Use this skill when writing new features, fixing bugs, or refactoring code. Enforces test-driven development with 80%+ coverage including unit, integration, and E2E tests.","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Ftdd-workflow\u002FSKILL.md",[140,143,146],{"categoryNo":141,"categoryName":142,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":144,"categoryName":145,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":147,"categoryName":148,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师",[150,151,152,153,154,155,131,156,157,158,159,160,161,162],"tdd","workflow","tdd workflow","e2e tests","e2e","integration","development","use","test","refactoring","coverage","tests","writing",{"skillNo":164,"name":165,"nameZh":6,"description":166,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":167,"categories":168,"keywords":169,"publishedAt":37},"01M6D88FTHRRSVJMXF2G7MQAK3","swiftui-patterns","SwiftUI architecture patterns, state management with @Observable, view composition, navigation, performance optimization, and modern iOS\u002FmacOS UI best practices.","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fswiftui-patterns\u002FSKILL.md",[],[170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188],"patterns","swiftui","swiftui patterns","architecture","macos","performance","state management","best practices","state","ui","Optimization","ios","architecture patterns","Composition","performance optimization","view","management","swiftui architecture","navigation",{"skillNo":190,"name":191,"nameZh":6,"description":192,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":193,"categories":194,"keywords":196,"publishedAt":37},"01M6D88D527QTQT9DKHTRFN6EA","swift-protocol-di-testing","Protocol-based dependency injection for testable Swift code — mock file system, network, and external APIs using focused protocols and Swift Testing.","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fswift-protocol-di-testing\u002FSKILL.md",[195],{"categoryNo":141,"categoryName":142,"taxonomyType":21,"taxonomyTypeDesc":22},[197,198,199,200,131,201,202,203,204,133,205,206,207],"swift protocol di testing","protocol","swift","testing","protocols","file","network","injection","dependency","swift testing","dependency injection",{"skillNo":209,"name":210,"nameZh":6,"description":211,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":212,"categories":213,"keywords":214,"publishedAt":37},"01M6D88AJW8H2QNWSW5ZY82R43","swift-concurrency-6-2","Swift 6.2 Approachable Concurrency — single-threaded by default, @concurrent for explicit background offloading, isolated conformances for main actor types.","https:\u002F\u002Fgithub.com\u002Foabdelmaksoud\u002FSuperClaw\u002Fblob\u002Fmain\u002Fupstream-sync\u002Fwork\u002Fecc\u002Fskills\u002Fswift-concurrency-6-2\u002FSKILL.md",[],[215,216,199,217,218,43],"concurrency","swift concurrency","swift concurrency 6 2","default"]