ui-syncup 0.3.13 → 0.4.0-beta.2
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/.agents/skills/ai-spec-workflow/SKILL.md +58 -0
- package/.agents/skills/ai-spec-workflow/references/AI_SPECIFICATION_WORKFLOW.md +1434 -0
- package/.agents/skills/ai-spec-workflow/references/templates/design-template.md +729 -0
- package/.agents/skills/ai-spec-workflow/references/templates/requirements-template.md +179 -0
- package/.agents/skills/ai-spec-workflow/references/templates/tasks-template.md +501 -0
- package/.agents/skills/animation-designer/SKILL.md +688 -0
- package/.agents/skills/animation-designer/manifest.yaml +44 -0
- package/.agents/skills/brainstorming/SKILL.md +54 -0
- package/.agents/skills/contract-driven-ui/SKILL.md +270 -0
- package/.agents/skills/dispatching-parallel-agents/SKILL.md +180 -0
- package/.agents/skills/executing-plans/SKILL.md +76 -0
- package/.agents/skills/executing-specs/SKILL.md +53 -0
- package/.agents/skills/finishing-a-development-branch/SKILL.md +200 -0
- package/.agents/skills/github-workflow-automation/SKILL.md +846 -0
- package/.agents/skills/react-best-practices/AGENTS.md +2249 -0
- package/.agents/skills/react-best-practices/README.md +123 -0
- package/.agents/skills/react-best-practices/SKILL.md +121 -0
- package/.agents/skills/react-best-practices/metadata.json +15 -0
- package/.agents/skills/react-best-practices/rules/_sections.md +46 -0
- package/.agents/skills/react-best-practices/rules/_template.md +28 -0
- package/.agents/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/.agents/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/.agents/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/.agents/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/.agents/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/.agents/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/.agents/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/.agents/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/.agents/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/.agents/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/.agents/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/.agents/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/.agents/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/.agents/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/.agents/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/.agents/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/.agents/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/.agents/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/.agents/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/.agents/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/.agents/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/.agents/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/.agents/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/.agents/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/.agents/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/.agents/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/.agents/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/.agents/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/.agents/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/.agents/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/.agents/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/.agents/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/.agents/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/.agents/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/.agents/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/.agents/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/.agents/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/.agents/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/.agents/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/.agents/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/.agents/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/.agents/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/.agents/skills/react-best-practices/rules/server-cache-react.md +26 -0
- package/.agents/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
- package/.agents/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/.agents/skills/react-ui-patterns/SKILL.md +289 -0
- package/.agents/skills/receiving-code-review/SKILL.md +213 -0
- package/.agents/skills/requesting-code-review/SKILL.md +105 -0
- package/.agents/skills/requesting-code-review/code-reviewer.md +146 -0
- package/.agents/skills/reviewing-code/SKILL.md +28 -0
- package/.agents/skills/shadcn/SKILL.md +240 -0
- package/.agents/skills/shadcn/agents/openai.yml +5 -0
- package/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
- package/.agents/skills/shadcn/assets/shadcn.png +0 -0
- package/.agents/skills/shadcn/cli.md +255 -0
- package/.agents/skills/shadcn/customization.md +202 -0
- package/.agents/skills/shadcn/evals/evals.json +47 -0
- package/.agents/skills/shadcn/mcp.md +94 -0
- package/.agents/skills/shadcn/rules/base-vs-radix.md +306 -0
- package/.agents/skills/shadcn/rules/composition.md +195 -0
- package/.agents/skills/shadcn/rules/forms.md +192 -0
- package/.agents/skills/shadcn/rules/icons.md +101 -0
- package/.agents/skills/shadcn/rules/styling.md +162 -0
- package/.agents/skills/steering-creation/SKILL.md +221 -0
- package/.agents/skills/steering-creation/references/STEERING_CREATION_INSTRUCTION.md +850 -0
- package/.agents/skills/subagent-driven-development/SKILL.md +240 -0
- package/.agents/skills/subagent-driven-development/code-quality-reviewer-prompt.md +20 -0
- package/.agents/skills/subagent-driven-development/implementer-prompt.md +78 -0
- package/.agents/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/.agents/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/.agents/skills/systematic-debugging/SKILL.md +296 -0
- package/.agents/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/.agents/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/.agents/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/.agents/skills/systematic-debugging/find-polluter.sh +63 -0
- package/.agents/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/.agents/skills/systematic-debugging/test-academic.md +14 -0
- package/.agents/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/.agents/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/.agents/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/.agents/skills/test-driven-development/SKILL.md +371 -0
- package/.agents/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/.agents/skills/using-git-worktrees/SKILL.md +217 -0
- package/.agents/skills/using-superpowers/SKILL.md +87 -0
- package/.agents/skills/verification-before-completion/SKILL.md +139 -0
- package/.agents/skills/web-design-guidelines/SKILL.md +36 -0
- package/.agents/skills/writing-plans/SKILL.md +116 -0
- package/.agents/skills/writing-skills/SKILL.md +655 -0
- package/.agents/skills/writing-skills/anthropic-best-practices.md +1150 -0
- package/.agents/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/.agents/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/.agents/skills/writing-skills/persuasion-principles.md +187 -0
- package/.agents/skills/writing-skills/render-graphs.js +168 -0
- package/.agents/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/.ai/steering/product.md +51 -0
- package/.ai/steering/structure.md +275 -0
- package/.ai/steering/tech.md +188 -0
- package/.claude/agents/database-architect.md +96 -0
- package/.claude/agents/deployment-pipeline-architect.md +122 -0
- package/.claude/agents/nextjs-expert.md +69 -0
- package/.claude/agents/ui-design-expert.md +106 -0
- package/.claudeignore +69 -0
- package/.dockerignore +8 -0
- package/.env.development +86 -0
- package/.env.example +171 -0
- package/.env.production +139 -0
- package/.env.test +58 -0
- package/.gitattributes +2 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +33 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +20 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +23 -0
- package/.github/workflows/ci.yml +64 -0
- package/.github/workflows/release.yml +174 -0
- package/.nvmrc +1 -0
- package/.releaserc.json +18 -0
- package/.vercelignore +73 -0
- package/AGENTS.md +544 -0
- package/CHANGELOG.md +69 -0
- package/CODE_OF_CONDUCT.md +21 -0
- package/CONTRIBUTING.md +32 -0
- package/Dockerfile +84 -0
- package/LICENSE +21 -0
- package/README.md +328 -59
- package/SECURITY.md +16 -0
- package/bun.lock +3853 -0
- package/cli/README.md +94 -0
- package/cli/bun.lock +306 -0
- package/cli/index.ts +96 -0
- package/cli/package-lock.json +2157 -0
- package/cli/package.json +30 -0
- package/cli/src/commands/backup.ts +78 -0
- package/cli/src/commands/doctor.ts +82 -0
- package/cli/src/commands/init.ts +234 -0
- package/cli/src/commands/logs.ts +26 -0
- package/cli/src/commands/open.ts +23 -0
- package/cli/src/commands/remove.ts +44 -0
- package/cli/src/commands/restart.ts +21 -0
- package/cli/src/commands/restore.ts +90 -0
- package/cli/src/commands/start.ts +26 -0
- package/cli/src/commands/status.ts +25 -0
- package/cli/src/commands/stop.ts +20 -0
- package/cli/src/commands/upgrade.ts +28 -0
- package/cli/src/lib/docker.ts +40 -0
- package/cli/src/lib/env.ts +42 -0
- package/cli/src/lib/ui.ts +43 -0
- package/cli/tsconfig.json +13 -0
- package/cli/tsup.config.ts +12 -0
- package/components.json +24 -0
- package/docker/README.md +430 -0
- package/docker/compose.dev-minio.yml +30 -0
- package/docker/compose.dev.yml +39 -0
- package/docker/compose.local.yml +84 -0
- package/docker/compose.yml +153 -0
- package/docs/VERSIONING.md +101 -0
- package/docs/database/DRIZZLE_COMMANDS_EXPLAINED.md +1779 -0
- package/docs/database/DRIZZLE_ZOD_POSTGRESQL_INSTRUCTION.md +646 -0
- package/docs/database/MIGRATION_BEST_PRACTICES.md +601 -0
- package/docs/database/MIGRATION_ROLLBACK.md +1080 -0
- package/docs/database/MIGRATION_SYSTEM.md +165 -0
- package/docs/database/MIGRATION_TROUBLESHOOTING.md +881 -0
- package/docs/development/ENVIRONMENT_CONFIG.md +896 -0
- package/docs/development/LOCAL_DEVELOPMENT.md +456 -0
- package/docs/development/REMOTE_DATABASE_SETUP.md +786 -0
- package/docs/development/STORAGE_SETUP.md +207 -0
- package/docs/development/SUPABASE_LOCAL_SETUP.md +178 -0
- package/docs/development/TESTING.md +714 -0
- package/docs/feature-architectures/LOADING_ARCHITECTURE.md +343 -0
- package/docs/feature-architectures/NOTIFICATION_ARCHITECTURE.md +858 -0
- package/docs/feature-architectures/RATE_LIMIT_RESET.md +147 -0
- package/docs/feature-architectures/RBAC.md +1132 -0
- package/docs/feature-architectures/RESOURCE_LIMITS.md +69 -0
- package/docs/feature-architectures/SECURITY.md +284 -0
- package/docs/feature-architectures/WORKSPACES.md +278 -0
- package/docs/plans/admin-setup-wizard-routing-plan.md +623 -0
- package/drizzle/0000_purple_wilson_fisk.sql +360 -0
- package/drizzle/0001_drop_instance_public_url.sql +1 -0
- package/drizzle/meta/0000_snapshot.json +3118 -0
- package/drizzle/meta/_journal.json +20 -0
- package/drizzle.config.ts +13 -0
- package/eslint.config.mjs +44 -0
- package/install.sh +180 -0
- package/next.config.ts +91 -0
- package/package.json +128 -22
- package/playwright.config.ts +70 -0
- package/postcss.config.mjs +7 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/logo.svg +11 -0
- package/public/next.svg +1 -0
- package/public/playground/CPM-101/as-is-image.jpg +0 -0
- package/public/playground/CPM-101/to-be-image.jpg +0 -0
- package/public/playground/TEST-1/LinkedIn-skeleton-screen.png +0 -0
- package/public/playground/TEST-1/https___dev-to-uploads.s3.amazonaws.com_uploads_articles_vuahe90ka1mkx9aepmea.webp +0 -0
- package/public/playground/TEST-1/linkedin_skeletonscreen.jpg +0 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/scripts/__tests__/migrate.integration.test.ts +642 -0
- package/scripts/__tests__/migrate.property.test.ts +1714 -0
- package/scripts/__tests__/migrate.test.ts +536 -0
- package/scripts/admin-reset-password.ts +114 -0
- package/scripts/check-email-queue.ts +99 -0
- package/scripts/check-sessions.ts +50 -0
- package/scripts/db-pull-data.sh +73 -0
- package/scripts/force-verify-email.sh +13 -0
- package/scripts/migrate.ts +693 -0
- package/scripts/process-email-queue.ts +26 -0
- package/scripts/reset-db.ts +47 -0
- package/scripts/reset-rate-limit.sh +26 -0
- package/scripts/reset-remote-db.sql +31 -0
- package/scripts/retry-failed-emails.ts +67 -0
- package/scripts/seed.ts +605 -0
- package/scripts/setup-monitoring.sh +440 -0
- package/scripts/sync-migration-tracking.ts +113 -0
- package/scripts/test-ci-error-handling.sh +237 -0
- package/scripts/test-ci-workflow.sh +200 -0
- package/scripts/test-migration.sh +151 -0
- package/scripts/validate-env.ts +25 -0
- package/scripts/validate-migration-system.ts +566 -0
- package/scripts/verify-ci-status-reporting.sh +206 -0
- package/scripts/verify-user-email.sql +22 -0
- package/scripts/verify-vercel-integration.ts +292 -0
- package/seed_data.md +54 -0
- package/src/app/(protected)/(team)/(routes)/[projectSlug]/error.tsx +89 -0
- package/src/app/(protected)/(team)/(routes)/[projectSlug]/loading.tsx +101 -0
- package/src/app/(protected)/(team)/(routes)/[projectSlug]/page.tsx +91 -0
- package/src/app/(protected)/(team)/(routes)/issue/[issueKey]/README.md +192 -0
- package/src/app/(protected)/(team)/(routes)/issue/[issueKey]/error.tsx +58 -0
- package/src/app/(protected)/(team)/(routes)/issue/[issueKey]/loading.tsx +14 -0
- package/src/app/(protected)/(team)/(routes)/issue/[issueKey]/not-found.tsx +47 -0
- package/src/app/(protected)/(team)/(routes)/issue/[issueKey]/page.tsx +91 -0
- package/src/app/(protected)/(team)/projects/page.tsx +16 -0
- package/src/app/(protected)/(team)/team/settings/(section)/instance/page.tsx +52 -0
- package/src/app/(protected)/(team)/team/settings/(section)/integrations/loading.tsx +5 -0
- package/src/app/(protected)/(team)/team/settings/(section)/integrations/page.tsx +23 -0
- package/src/app/(protected)/(team)/team/settings/(section)/members/loading.tsx +5 -0
- package/src/app/(protected)/(team)/team/settings/(section)/members/page.tsx +35 -0
- package/src/app/(protected)/(team)/team/settings/layout.tsx +72 -0
- package/src/app/(protected)/(team)/team/settings/loading.tsx +5 -0
- package/src/app/(protected)/(team)/team/settings/page.tsx +71 -0
- package/src/app/(protected)/dev/auth/README.md +151 -0
- package/src/app/(protected)/dev/auth/page.tsx +590 -0
- package/src/app/(protected)/layout.test.tsx +209 -0
- package/src/app/(protected)/layout.tsx +28 -0
- package/src/app/(protected)/onboarding/page.tsx +27 -0
- package/src/app/(protected)/settings/integrations/page.tsx +23 -0
- package/src/app/(protected)/settings/layout.tsx +26 -0
- package/src/app/(protected)/settings/notifications/page.tsx +26 -0
- package/src/app/(protected)/settings/other/page.tsx +23 -0
- package/src/app/(protected)/settings/page.tsx +23 -0
- package/src/app/(protected)/settings/preferences/page.tsx +23 -0
- package/src/app/(protected)/settings/security/page.tsx +37 -0
- package/src/app/(public)/forgot-password/page.tsx +20 -0
- package/src/app/(public)/invite/project/[token]/error.tsx +50 -0
- package/src/app/(public)/invite/project/[token]/loading.tsx +39 -0
- package/src/app/(public)/invite/project/[token]/page.tsx +156 -0
- package/src/app/(public)/layout.tsx +9 -0
- package/src/app/(public)/privacy-policy/page.tsx +12 -0
- package/src/app/(public)/reset-password/page.tsx +37 -0
- package/src/app/(public)/setup/__tests__/page.test.tsx +30 -0
- package/src/app/(public)/setup/page.tsx +17 -0
- package/src/app/(public)/share/issue/[token]/page.tsx +51 -0
- package/src/app/(public)/sign-in/page.tsx +55 -0
- package/src/app/(public)/sign-up/page.tsx +23 -0
- package/src/app/(public)/verify-email/page.tsx +22 -0
- package/src/app/(public)/verify-email-confirm/page.tsx +40 -0
- package/src/app/api/auth/[...all]/route.ts +6 -0
- package/src/app/api/auth/delete-account/route.ts +134 -0
- package/src/app/api/auth/dev/force-verify/route.ts +180 -0
- package/src/app/api/auth/dev/reset-rate-limit/route.ts +144 -0
- package/src/app/api/auth/dev/sessions/route.ts +172 -0
- package/src/app/api/auth/forgot-password/__tests__/forgot-password.property.test.ts +397 -0
- package/src/app/api/auth/forgot-password/route.ts +277 -0
- package/src/app/api/auth/logout/route.ts +115 -0
- package/src/app/api/auth/me/route.ts +123 -0
- package/src/app/api/auth/providers/__tests__/route.test.ts +236 -0
- package/src/app/api/auth/providers/route.ts +119 -0
- package/src/app/api/auth/resend-verification/route.ts +262 -0
- package/src/app/api/auth/reset-password/__tests__/reset-password.property.test.ts +493 -0
- package/src/app/api/auth/reset-password/__tests__/route.test.ts +284 -0
- package/src/app/api/auth/reset-password/route.ts +251 -0
- package/src/app/api/auth/verify-email/route.ts +232 -0
- package/src/app/api/example-cors/route.ts +61 -0
- package/src/app/api/health/route.ts +14 -0
- package/src/app/api/invite/project/[token]/__tests__/accept-invitation.integration.test.ts +348 -0
- package/src/app/api/invite/project/[token]/decline/route.ts +99 -0
- package/src/app/api/invite/project/[token]/route.ts +269 -0
- package/src/app/api/issues/[issueId]/activities/route.ts +213 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/annotations/[annotationId]/comments/[commentId]/route.ts +486 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/annotations/[annotationId]/comments/route.ts +283 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/annotations/[annotationId]/read/route.ts +242 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/annotations/[annotationId]/route.ts +534 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/annotations/route.ts +514 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/route.ts +161 -0
- package/src/app/api/issues/[issueId]/attachments/route.ts +376 -0
- package/src/app/api/issues/[issueId]/route.ts +516 -0
- package/src/app/api/notifications/[id]/read/route.ts +131 -0
- package/src/app/api/notifications/__tests__/notifications.integration.test.ts +350 -0
- package/src/app/api/notifications/read-all/route.ts +72 -0
- package/src/app/api/notifications/route.ts +148 -0
- package/src/app/api/notifications/unread-count/route.ts +77 -0
- package/src/app/api/projects/[id]/activities/route.ts +174 -0
- package/src/app/api/projects/[id]/invitations/[invitationId]/resend/route.ts +99 -0
- package/src/app/api/projects/[id]/invitations/[invitationId]/route.ts +96 -0
- package/src/app/api/projects/[id]/invitations/route.ts +254 -0
- package/src/app/api/projects/[id]/issues/route.ts +452 -0
- package/src/app/api/projects/[id]/join/route.ts +207 -0
- package/src/app/api/projects/[id]/members/[memberId]/route.ts +364 -0
- package/src/app/api/projects/[id]/members/me/route.ts +121 -0
- package/src/app/api/projects/[id]/members/route.ts +129 -0
- package/src/app/api/projects/[id]/route.ts +476 -0
- package/src/app/api/projects/route.ts +394 -0
- package/src/app/api/setup/admin/route.ts +255 -0
- package/src/app/api/setup/complete/__tests__/route.test.ts +60 -0
- package/src/app/api/setup/complete/route.ts +244 -0
- package/src/app/api/setup/config/route.ts +195 -0
- package/src/app/api/setup/export/route.ts +111 -0
- package/src/app/api/setup/health/route.ts +74 -0
- package/src/app/api/setup/import/route.ts +154 -0
- package/src/app/api/setup/status/route.ts +82 -0
- package/src/app/api/setup/workspace/route.ts +252 -0
- package/src/app/api/teams/[teamId]/export/route.ts +115 -0
- package/src/app/api/teams/[teamId]/invitations/[invitationId]/resend/route.ts +132 -0
- package/src/app/api/teams/[teamId]/invitations/[invitationId]/route.ts +117 -0
- package/src/app/api/teams/[teamId]/invitations/route.ts +363 -0
- package/src/app/api/teams/[teamId]/members/[userId]/route.ts +335 -0
- package/src/app/api/teams/[teamId]/members/route.ts +184 -0
- package/src/app/api/teams/[teamId]/members/search/route.ts +202 -0
- package/src/app/api/teams/[teamId]/route.ts +423 -0
- package/src/app/api/teams/[teamId]/switch/route.ts +140 -0
- package/src/app/api/teams/[teamId]/transfer-ownership/route.ts +212 -0
- package/src/app/api/teams/invitations/[token]/accept/route.ts +140 -0
- package/src/app/api/teams/invitations/by-id/[id]/accept/route.ts +98 -0
- package/src/app/api/teams/invitations/by-id/[id]/decline/route.ts +90 -0
- package/src/app/api/teams/route.ts +278 -0
- package/src/app/api/uploads/media/route.ts +118 -0
- package/src/app/api/uploads/presigned/route.ts +49 -0
- package/src/app/api/user/linked-accounts/route.ts +35 -0
- package/src/app/email-preview/page.tsx +11 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/global-error.tsx +21 -0
- package/src/app/layout.tsx +50 -0
- package/src/app/page.tsx +5 -0
- package/src/components/icons/atlassian-icon.tsx +22 -0
- package/src/components/icons/index.ts +1 -0
- package/src/components/layout/SIDEBAR_LAYOUT_BEST_PRACTICES.md +240 -0
- package/src/components/layout/app-shell-header-store.tsx +20 -0
- package/src/components/layout/app-shell-skeleton.tsx +89 -0
- package/src/components/layout/app-shell-wrapper.tsx +32 -0
- package/src/components/layout/app-shell.test.tsx +155 -0
- package/src/components/layout/app-shell.tsx +100 -0
- package/src/components/shared/headers/app-header-configurator.tsx +42 -0
- package/src/components/shared/headers/app-header.tsx +103 -0
- package/src/components/shared/headers/header-user-menu.tsx +247 -0
- package/src/components/shared/headers/index.ts +44 -0
- package/src/components/shared/headers/page-header.tsx +25 -0
- package/src/components/shared/notifications/__tests__/notification-bell.test.tsx +159 -0
- package/src/components/shared/notifications/__tests__/notification-dropdown.test.tsx +296 -0
- package/src/components/shared/notifications/__tests__/notification-item.test.tsx +328 -0
- package/src/components/shared/notifications/index.ts +45 -0
- package/src/components/shared/notifications/notification-actions.tsx +295 -0
- package/src/components/shared/notifications/notification-bell-button.tsx +77 -0
- package/src/components/shared/notifications/notification-dropdown.tsx +160 -0
- package/src/components/shared/notifications/notification-group-item.tsx +268 -0
- package/src/components/shared/notifications/notification-item.tsx +193 -0
- package/src/components/shared/notifications/notification-load-more.tsx +50 -0
- package/src/components/shared/notifications/notification-panel.tsx +49 -0
- package/src/components/shared/notifications/utils.tsx +127 -0
- package/src/components/shared/permission-guard/index.ts +1 -0
- package/src/components/shared/permission-guard/permission-tooltip.tsx +45 -0
- package/src/components/shared/relative-time.tsx +53 -0
- package/src/components/shared/section-container.tsx +32 -0
- package/src/components/shared/service-status-banner.tsx +121 -0
- package/src/components/shared/settings-sidebar/index.ts +2 -0
- package/src/components/shared/settings-sidebar/team-setting-aside.tsx +97 -0
- package/src/components/shared/settings-sidebar/user-settings-aside.tsx +66 -0
- package/src/components/shared/sidebar/app-sidebar.tsx +146 -0
- package/src/components/shared/sidebar/index.ts +36 -0
- package/src/components/shared/sidebar/sidebar-main.tsx +81 -0
- package/src/components/shared/sidebar/sidebar-project.tsx +61 -0
- package/src/components/shared/sidebar/sidebar-team-avatar.tsx +126 -0
- package/src/components/shared/sidebar/sidebar-team-switcher.tsx +185 -0
- package/src/components/shared/sidebar/type.ts +97 -0
- package/src/components/ui/alert-dialog.tsx +157 -0
- package/src/components/ui/alert.tsx +66 -0
- package/src/components/ui/avatar-upload.tsx +147 -0
- package/src/components/ui/avatar.tsx +53 -0
- package/src/components/ui/badge.tsx +46 -0
- package/src/components/ui/breadcrumb.tsx +109 -0
- package/src/components/ui/button.tsx +60 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/checkbox.tsx +32 -0
- package/src/components/ui/collapsible.tsx +33 -0
- package/src/components/ui/command.tsx +184 -0
- package/src/components/ui/dialog.tsx +143 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/empty.tsx +104 -0
- package/src/components/ui/field.tsx +244 -0
- package/src/components/ui/image-cropper-dialog.tsx +167 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/optimized-image.tsx +220 -0
- package/src/components/ui/pagination.tsx +127 -0
- package/src/components/ui/popover.tsx +48 -0
- package/src/components/ui/progress.tsx +31 -0
- package/src/components/ui/radio-group.tsx +45 -0
- package/src/components/ui/scroll-area.tsx +58 -0
- package/src/components/ui/select.tsx +187 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +139 -0
- package/src/components/ui/sidebar.tsx +733 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/sonner.tsx +40 -0
- package/src/components/ui/spinner.tsx +16 -0
- package/src/components/ui/switch.tsx +31 -0
- package/src/components/ui/table.tsx +116 -0
- package/src/components/ui/tabs.tsx +66 -0
- package/src/components/ui/textarea.tsx +23 -0
- package/src/components/ui/tooltip.tsx +61 -0
- package/src/config/__tests__/workspace.property.test.ts +40 -0
- package/src/config/auth.ts +62 -0
- package/src/config/integrations.ts +126 -0
- package/src/config/quotas.ts +20 -0
- package/src/config/roles.ts +463 -0
- package/src/config/settings-nav.ts +39 -0
- package/src/config/team-settings-nav.ts +37 -0
- package/src/config/user-settings-nav.ts +42 -0
- package/src/config/version.ts +1 -0
- package/src/config/workspace.ts +64 -0
- package/src/features/annotations/README.md +283 -0
- package/src/features/annotations/api/annotations-api.ts +194 -0
- package/src/features/annotations/api/comments-api.ts +147 -0
- package/src/features/annotations/api/index.ts +71 -0
- package/src/features/annotations/api/save-annotation.ts +150 -0
- package/src/features/annotations/api/schemas.ts +142 -0
- package/src/features/annotations/components/annotated-attachment-view.tsx +576 -0
- package/src/features/annotations/components/annotation-action-sheet.tsx +140 -0
- package/src/features/annotations/components/annotation-annotations-panel.tsx +213 -0
- package/src/features/annotations/components/annotation-box.tsx +539 -0
- package/src/features/annotations/components/annotation-canvas.tsx +534 -0
- package/src/features/annotations/components/annotation-comment-input.tsx +145 -0
- package/src/features/annotations/components/annotation-context-menu.tsx +164 -0
- package/src/features/annotations/components/annotation-drawer.tsx +231 -0
- package/src/features/annotations/components/annotation-layer.tsx +271 -0
- package/src/features/annotations/components/annotation-pin.tsx +318 -0
- package/src/features/annotations/components/annotation-popover.tsx +562 -0
- package/src/features/annotations/components/annotation-thread-panel.tsx +485 -0
- package/src/features/annotations/components/annotation-thread-preview.tsx +195 -0
- package/src/features/annotations/components/annotation-toolbar.tsx +244 -0
- package/src/features/annotations/components/keyboard-shortcuts-modal.tsx +79 -0
- package/src/features/annotations/docs/ANNOTATIONS_ARCHITECTURE.md +67 -0
- package/src/features/annotations/docs/ANNOTATION_SAVE_ARCHITECTURE.md +422 -0
- package/src/features/annotations/docs/ANNOTATION_SAVE_FEATURE.md +408 -0
- package/src/features/annotations/docs/BOX_ANNOTATION_GUIDE.md +542 -0
- package/src/features/annotations/docs/NEXTSTEP.md +28 -0
- package/src/features/annotations/docs/STALE_CLOSURE_FIX.md +344 -0
- package/src/features/annotations/docs/UNDO_REDO_QUICK_START.md +545 -0
- package/src/features/annotations/docs/local_first_canvas_autosave_architecture.md +674 -0
- package/src/features/annotations/examples/complete-example.tsx +266 -0
- package/src/features/annotations/examples/save-annotation-example.tsx +309 -0
- package/src/features/annotations/hooks/__tests__/use-annotation-permissions.property.test.tsx +493 -0
- package/src/features/annotations/hooks/index.ts +36 -0
- package/src/features/annotations/hooks/use-annotation-batch-save.ts +109 -0
- package/src/features/annotations/hooks/use-annotation-comments.ts +353 -0
- package/src/features/annotations/hooks/use-annotation-drafts.ts +137 -0
- package/src/features/annotations/hooks/use-annotation-edit-state.ts +99 -0
- package/src/features/annotations/hooks/use-annotation-history-tracker.ts +159 -0
- package/src/features/annotations/hooks/use-annotation-integration.ts +916 -0
- package/src/features/annotations/hooks/use-annotation-permissions.ts +210 -0
- package/src/features/annotations/hooks/use-annotation-popover.ts +175 -0
- package/src/features/annotations/hooks/use-annotation-save.ts +208 -0
- package/src/features/annotations/hooks/use-annotation-tools.ts +237 -0
- package/src/features/annotations/hooks/use-annotations-with-history.ts +332 -0
- package/src/features/annotations/hooks/use-auto-save.ts +94 -0
- package/src/features/annotations/index.ts +111 -0
- package/src/features/annotations/types/annotation.ts +201 -0
- package/src/features/annotations/types/index.ts +28 -0
- package/src/features/annotations/utils/history-manager.ts +73 -0
- package/src/features/annotations/utils/index.ts +2 -0
- package/src/features/annotations/utils/map-attachments-to-threads.ts +28 -0
- package/src/features/annotations/utils/position-comment-input.ts +136 -0
- package/src/features/annotations/utils/re-sequence-labels.ts +92 -0
- package/src/features/annotations/utils/validate-annotation-label.ts +120 -0
- package/src/features/auth/api/types.ts +101 -0
- package/src/features/auth/components/__tests__/role-gate.test.tsx +448 -0
- package/src/features/auth/components/__tests__/social-login-buttons.test.tsx +313 -0
- package/src/features/auth/components/auth-card.tsx +36 -0
- package/src/features/auth/components/forgot-password-form.tsx +115 -0
- package/src/features/auth/components/index.ts +14 -0
- package/src/features/auth/components/invite-code-input.tsx +155 -0
- package/src/features/auth/components/invited-user-form.tsx +309 -0
- package/src/features/auth/components/onboarding-form.tsx +195 -0
- package/src/features/auth/components/password-strength-indicator.tsx +113 -0
- package/src/features/auth/components/reset-password-form.tsx +138 -0
- package/src/features/auth/components/role-gate.tsx +124 -0
- package/src/features/auth/components/self-registration-choice.tsx +153 -0
- package/src/features/auth/components/sign-in-form.tsx +159 -0
- package/src/features/auth/components/sign-up-form.tsx +158 -0
- package/src/features/auth/components/social-login-buttons.tsx +219 -0
- package/src/features/auth/hooks/__tests__/use-onboarding.test.tsx +109 -0
- package/src/features/auth/hooks/__tests__/use-session.test.tsx +160 -0
- package/src/features/auth/hooks/index.ts +15 -0
- package/src/features/auth/hooks/use-accept-invitation.ts +194 -0
- package/src/features/auth/hooks/use-delete-account.ts +86 -0
- package/src/features/auth/hooks/use-force-verify.ts +89 -0
- package/src/features/auth/hooks/use-forgot-password.ts +144 -0
- package/src/features/auth/hooks/use-link-account.ts +78 -0
- package/src/features/auth/hooks/use-linked-accounts.ts +88 -0
- package/src/features/auth/hooks/use-onboarding.ts +159 -0
- package/src/features/auth/hooks/use-resend-verification.ts +139 -0
- package/src/features/auth/hooks/use-reset-password.ts +151 -0
- package/src/features/auth/hooks/use-reset-rate-limit.ts +56 -0
- package/src/features/auth/hooks/use-self-registration.ts +202 -0
- package/src/features/auth/hooks/use-session.ts +81 -0
- package/src/features/auth/hooks/use-sessions.ts +59 -0
- package/src/features/auth/hooks/use-sign-in.ts +234 -0
- package/src/features/auth/hooks/use-sign-out.ts +88 -0
- package/src/features/auth/hooks/use-sign-up.ts +194 -0
- package/src/features/auth/hooks/use-unlink-account.ts +100 -0
- package/src/features/auth/hooks/use-verify-email-token.ts +125 -0
- package/src/features/auth/index.ts +75 -0
- package/src/features/auth/screens/forgot-password-screen.tsx +33 -0
- package/src/features/auth/screens/index.ts +7 -0
- package/src/features/auth/screens/onboarding-screen.tsx +49 -0
- package/src/features/auth/screens/reset-password-screen.tsx +33 -0
- package/src/features/auth/screens/sign-in-screen.tsx +61 -0
- package/src/features/auth/screens/sign-up-screen.tsx +37 -0
- package/src/features/auth/screens/verify-email-confirm-screen.tsx +286 -0
- package/src/features/auth/screens/verify-email-screen.tsx +146 -0
- package/src/features/auth/types/index.ts +14 -0
- package/src/features/auth/utils/__tests__/validators.test.ts +331 -0
- package/src/features/auth/utils/password-strength.ts +129 -0
- package/src/features/auth/utils/validators.ts +124 -0
- package/src/features/email-preview/actions/render-email.ts +21 -0
- package/src/features/email-preview/screens/email-preview-screen.tsx +81 -0
- package/src/features/folder-scaffold-template/index.ts +0 -0
- package/src/features/instance-settings/components/index.ts +6 -0
- package/src/features/instance-settings/components/instance-settings-form.tsx +180 -0
- package/src/features/instance-settings/components/instance-status-display.tsx +158 -0
- package/src/features/instance-settings/index.ts +7 -0
- package/src/features/instance-settings/screens/index.ts +5 -0
- package/src/features/instance-settings/screens/instance-settings-screen.tsx +59 -0
- package/src/features/issues/README.md +330 -0
- package/src/features/issues/api/create-issue.ts +19 -0
- package/src/features/issues/api/delete-issue.ts +27 -0
- package/src/features/issues/api/get-issue-activities.ts +58 -0
- package/src/features/issues/api/get-issue-details.ts +25 -0
- package/src/features/issues/api/get-project-issues-server.ts +44 -0
- package/src/features/issues/api/get-project-issues.ts +21 -0
- package/src/features/issues/api/index.ts +44 -0
- package/src/features/issues/api/update-issue.ts +31 -0
- package/src/features/issues/api/upload-attachment.ts +81 -0
- package/src/features/issues/components/activity-timeline.tsx +440 -0
- package/src/features/issues/components/canvas-state-indicator.tsx +90 -0
- package/src/features/issues/components/centered-canvas-view.tsx +739 -0
- package/src/features/issues/components/image-selector.tsx +123 -0
- package/src/features/issues/components/image-upload-zone.tsx +262 -0
- package/src/features/issues/components/infinite-canvas-background.tsx +163 -0
- package/src/features/issues/components/inline-editable-select.tsx +173 -0
- package/src/features/issues/components/inline-editable-text.tsx +225 -0
- package/src/features/issues/components/inline-editable-textarea.tsx +219 -0
- package/src/features/issues/components/inline-editable-user-select.tsx +202 -0
- package/src/features/issues/components/issue-deletion-dialog.tsx +142 -0
- package/src/features/issues/components/issue-details-panel.tsx +101 -0
- package/src/features/issues/components/issues-create-dialog.tsx +578 -0
- package/src/features/issues/components/issues-list-filter.tsx +312 -0
- package/src/features/issues/components/issues-list.tsx +151 -0
- package/src/features/issues/components/issues-priority-badge.tsx +77 -0
- package/src/features/issues/components/issues-status-badge.tsx +100 -0
- package/src/features/issues/components/metadata-section.tsx +389 -0
- package/src/features/issues/components/optimized-attachment-view.tsx +528 -0
- package/src/features/issues/components/optimized-image.tsx +257 -0
- package/src/features/issues/components/panel-header.tsx +186 -0
- package/src/features/issues/components/preload.ts +31 -0
- package/src/features/issues/components/priority-selector.tsx +101 -0
- package/src/features/issues/components/responsive-issue-layout-skeleton.tsx +139 -0
- package/src/features/issues/components/responsive-issue-layout.tsx +617 -0
- package/src/features/issues/components/status-selector.tsx +320 -0
- package/src/features/issues/components/type-selector.tsx +102 -0
- package/src/features/issues/components/upload-progress-overlay.tsx +35 -0
- package/src/features/issues/components/uploaded-image-preview.tsx +173 -0
- package/src/features/issues/components/workflow-control.tsx +318 -0
- package/src/features/issues/components/zoom-controls.tsx +150 -0
- package/src/features/issues/config/index.ts +47 -0
- package/src/features/issues/config/options.ts +323 -0
- package/src/features/issues/config/workflow.ts +102 -0
- package/src/features/issues/docs/ARCHITECTURE_DIAGRAM.md +321 -0
- package/src/features/issues/docs/BACKEND_ARCHITECTURE.md +194 -0
- package/src/features/issues/docs/IMAGE_COMPONENTS_ARCHITECTURE.md +363 -0
- package/src/features/issues/docs/IMAGE_COMPONENTS_IMPORTS.md +412 -0
- package/src/features/issues/docs/IMPLEMENTATION_CHECKLIST.md +210 -0
- package/src/features/issues/docs/ROUTE_SETUP_COMPLETE.md +242 -0
- package/src/features/issues/hooks/index.ts +78 -0
- package/src/features/issues/hooks/use-canvas-transform.ts +255 -0
- package/src/features/issues/hooks/use-create-issue.ts +28 -0
- package/src/features/issues/hooks/use-elastic-scroll.ts +296 -0
- package/src/features/issues/hooks/use-issue-activities.ts +71 -0
- package/src/features/issues/hooks/use-issue-delete.ts +84 -0
- package/src/features/issues/hooks/use-issue-details.ts +70 -0
- package/src/features/issues/hooks/use-issue-filters.ts +50 -0
- package/src/features/issues/hooks/use-issue-update.ts +93 -0
- package/src/features/issues/hooks/use-keyboard-shortcuts.ts +104 -0
- package/src/features/issues/hooks/use-optimized-image.ts +228 -0
- package/src/features/issues/hooks/use-project-issues.ts +14 -0
- package/src/features/issues/index.ts +65 -0
- package/src/features/issues/screens/issue-details-screen.tsx +207 -0
- package/src/features/issues/screens/issue-details-skeletons.tsx +295 -0
- package/src/features/issues/screens/issue-share-screen.tsx +56 -0
- package/src/features/issues/types/index.ts +48 -0
- package/src/features/issues/types/issue.ts +291 -0
- package/src/features/issues/utils/filter-issues.ts +141 -0
- package/src/features/issues/utils/index.ts +14 -0
- package/src/features/legal/index.ts +1 -0
- package/src/features/legal/screens/privacy-policy-screen.tsx +307 -0
- package/src/features/notifications/api/get-notifications.ts +58 -0
- package/src/features/notifications/api/get-unread-count.ts +37 -0
- package/src/features/notifications/api/index.ts +35 -0
- package/src/features/notifications/api/mark-all-as-read.ts +37 -0
- package/src/features/notifications/api/mark-as-read.ts +41 -0
- package/src/features/notifications/api/types.ts +109 -0
- package/src/features/notifications/hooks/__tests__/use-notification-subscription.test.ts +206 -0
- package/src/features/notifications/hooks/index.ts +28 -0
- package/src/features/notifications/hooks/use-mark-all-as-read.ts +106 -0
- package/src/features/notifications/hooks/use-mark-as-read.ts +106 -0
- package/src/features/notifications/hooks/use-notification-subscription.ts +244 -0
- package/src/features/notifications/hooks/use-notification-toast.ts +161 -0
- package/src/features/notifications/hooks/use-notifications.ts +80 -0
- package/src/features/notifications/hooks/use-unread-count.ts +60 -0
- package/src/features/notifications/index.ts +48 -0
- package/src/features/notifications/utils/group-notifications.ts +152 -0
- package/src/features/notifications/utils/index.ts +9 -0
- package/src/features/projects/api/create-invitation.ts +45 -0
- package/src/features/projects/api/create-project.ts +64 -0
- package/src/features/projects/api/delete-project.ts +50 -0
- package/src/features/projects/api/get-project-activities.ts +43 -0
- package/src/features/projects/api/get-project-members.ts +53 -0
- package/src/features/projects/api/get-project.ts +49 -0
- package/src/features/projects/api/get-projects.ts +61 -0
- package/src/features/projects/api/index.ts +27 -0
- package/src/features/projects/api/join-project.ts +52 -0
- package/src/features/projects/api/leave-project.ts +51 -0
- package/src/features/projects/api/list-invitations.ts +36 -0
- package/src/features/projects/api/remove-member.ts +60 -0
- package/src/features/projects/api/resend-invitation.ts +36 -0
- package/src/features/projects/api/revoke-invitation.ts +36 -0
- package/src/features/projects/api/types.ts +286 -0
- package/src/features/projects/api/update-member-role.ts +70 -0
- package/src/features/projects/api/update-project.ts +69 -0
- package/src/features/projects/components/__tests__/project-detail-activity-feed.test.tsx +106 -0
- package/src/features/projects/components/__tests__/project-invitation-dialog.test.tsx +211 -0
- package/src/features/projects/components/__tests__/project-member-manager-dialog.test.tsx +254 -0
- package/src/features/projects/components/index.ts +21 -0
- package/src/features/projects/components/project-actions.tsx +248 -0
- package/src/features/projects/components/project-create-dialog.tsx +410 -0
- package/src/features/projects/components/project-detail-activity-feed.tsx +206 -0
- package/src/features/projects/components/project-detail-header.tsx +103 -0
- package/src/features/projects/components/project-detail-overview.tsx +128 -0
- package/src/features/projects/components/project-icon-selector.test.tsx +49 -0
- package/src/features/projects/components/project-icon-selector.tsx +76 -0
- package/src/features/projects/components/project-invitation-dialog.tsx +368 -0
- package/src/features/projects/components/project-issues.tsx +128 -0
- package/src/features/projects/components/project-leave-button.tsx +69 -0
- package/src/features/projects/components/project-list-card.tsx +246 -0
- package/src/features/projects/components/project-list-filters.tsx +320 -0
- package/src/features/projects/components/project-member-manager-dialog.tsx +419 -0
- package/src/features/projects/components/project-settings-dialog.tsx +204 -0
- package/src/features/projects/components/project-stats.tsx +46 -0
- package/src/features/projects/components/project-title-section.tsx +78 -0
- package/src/features/projects/config/icons.ts +91 -0
- package/src/features/projects/hooks/index.ts +28 -0
- package/src/features/projects/hooks/use-create-invitation.ts +83 -0
- package/src/features/projects/hooks/use-create-project.ts +77 -0
- package/src/features/projects/hooks/use-delete-project.ts +84 -0
- package/src/features/projects/hooks/use-join-project.ts +43 -0
- package/src/features/projects/hooks/use-leave-project.ts +84 -0
- package/src/features/projects/hooks/use-project-activities.ts +39 -0
- package/src/features/projects/hooks/use-project-filters.ts +86 -0
- package/src/features/projects/hooks/use-project-invitations.ts +66 -0
- package/src/features/projects/hooks/use-project-members.ts +57 -0
- package/src/features/projects/hooks/use-project.ts +67 -0
- package/src/features/projects/hooks/use-projects.ts +49 -0
- package/src/features/projects/hooks/use-recent-projects.ts +58 -0
- package/src/features/projects/hooks/use-remove-member.ts +89 -0
- package/src/features/projects/hooks/use-resend-invitation.ts +68 -0
- package/src/features/projects/hooks/use-revoke-invitation.ts +71 -0
- package/src/features/projects/hooks/use-team-member-suggestions.ts +133 -0
- package/src/features/projects/hooks/use-update-member-role.ts +92 -0
- package/src/features/projects/hooks/use-update-project.ts +88 -0
- package/src/features/projects/index.ts +91 -0
- package/src/features/projects/screens/index.ts +3 -0
- package/src/features/projects/screens/invitation-acceptance-screen.tsx +320 -0
- package/src/features/projects/screens/project-detail-screen-wrapper.tsx +47 -0
- package/src/features/projects/screens/project-detail-screen.tsx +661 -0
- package/src/features/projects/screens/projects-list-screen.tsx +161 -0
- package/src/features/projects/types/index.ts +59 -0
- package/src/features/projects/utils/format-helpers.ts +16 -0
- package/src/features/projects/utils/index.ts +2 -0
- package/src/features/projects/utils/role-helpers.ts +25 -0
- package/src/features/setup/api/complete-setup.ts +21 -0
- package/src/features/setup/api/create-admin.ts +21 -0
- package/src/features/setup/api/create-first-workspace.ts +21 -0
- package/src/features/setup/api/get-instance-status.ts +12 -0
- package/src/features/setup/api/get-service-health.ts +12 -0
- package/src/features/setup/api/index.ts +44 -0
- package/src/features/setup/api/save-instance-config.ts +21 -0
- package/src/features/setup/api/types.ts +122 -0
- package/src/features/setup/components/__tests__/setup-wizard-ui.test.tsx +362 -0
- package/src/features/setup/components/admin-account-step.tsx +205 -0
- package/src/features/setup/components/first-workspace-step.tsx +120 -0
- package/src/features/setup/components/index.ts +9 -0
- package/src/features/setup/components/instance-config-step.tsx +107 -0
- package/src/features/setup/components/mail-config-step.tsx +205 -0
- package/src/features/setup/components/sample-data-step.tsx +131 -0
- package/src/features/setup/components/service-health-step.tsx +180 -0
- package/src/features/setup/components/service-status-badge.tsx +50 -0
- package/src/features/setup/components/setup-progress.tsx +103 -0
- package/src/features/setup/components/setup-wizard.tsx +169 -0
- package/src/features/setup/hooks/index.ts +12 -0
- package/src/features/setup/hooks/use-complete-setup.ts +23 -0
- package/src/features/setup/hooks/use-create-admin.ts +25 -0
- package/src/features/setup/hooks/use-create-first-workspace.ts +24 -0
- package/src/features/setup/hooks/use-instance-status.ts +21 -0
- package/src/features/setup/hooks/use-save-instance-config.ts +23 -0
- package/src/features/setup/hooks/use-service-health.ts +21 -0
- package/src/features/setup/hooks/use-setup-wizard.ts +152 -0
- package/src/features/setup/hooks/use-workspace-mode.ts +19 -0
- package/src/features/setup/index.ts +30 -0
- package/src/features/setup/screens/index.ts +1 -0
- package/src/features/setup/screens/setup-screen.tsx +40 -0
- package/src/features/setup/types/index.ts +69 -0
- package/src/features/setup/utils/index.ts +78 -0
- package/src/features/team-settings/components/index.ts +39 -0
- package/src/features/team-settings/components/loading-states.tsx +296 -0
- package/src/features/team-settings/components/permission-guard.tsx +23 -0
- package/src/features/team-settings/components/settings-card.tsx +22 -0
- package/src/features/team-settings/components/settings-context-provider.tsx +51 -0
- package/src/features/team-settings/components/settings-error-boundary.tsx +366 -0
- package/src/features/team-settings/components/settings-navigation.tsx +87 -0
- package/src/features/team-settings/components/settings-section.tsx +23 -0
- package/src/features/team-settings/components/team-danger-zone.tsx +275 -0
- package/src/features/team-settings/components/team-information-form.tsx +116 -0
- package/src/features/team-settings/components/team-invitations-list.tsx +463 -0
- package/src/features/team-settings/components/team-members-list.tsx +342 -0
- package/src/features/team-settings/components/team-permission-guard.tsx +56 -0
- package/src/features/team-settings/components/team-setting-integrations.tsx +27 -0
- package/src/features/team-settings/components/team-setting-member.tsx +28 -0
- package/src/features/team-settings/components/team-settings-general.tsx +131 -0
- package/src/features/team-settings/components/transfer-ownership-modal.tsx +164 -0
- package/src/features/team-settings/components/unauthorized-access.tsx +52 -0
- package/src/features/team-settings/hooks/__tests__/use-team-settings.test.tsx +139 -0
- package/src/features/team-settings/hooks/index.ts +1 -0
- package/src/features/team-settings/hooks/use-team-settings.ts +148 -0
- package/src/features/team-settings/hooks/use-transfer-ownership.ts +45 -0
- package/src/features/team-settings/index.ts +25 -0
- package/src/features/team-settings/screens/index.ts +1 -0
- package/src/features/team-settings/screens/team-settings-screen.tsx +33 -0
- package/src/features/team-settings/types/index.ts +78 -0
- package/src/features/team-settings/utils/index.ts +6 -0
- package/src/features/team-settings/utils/mock-data.ts +40 -0
- package/src/features/teams/api/cancel-invitation.ts +25 -0
- package/src/features/teams/api/create-invitation.ts +28 -0
- package/src/features/teams/api/create-team.ts +14 -0
- package/src/features/teams/api/delete-team.ts +19 -0
- package/src/features/teams/api/get-invitations.ts +25 -0
- package/src/features/teams/api/get-team-members.ts +25 -0
- package/src/features/teams/api/get-team.ts +13 -0
- package/src/features/teams/api/get-teams.ts +19 -0
- package/src/features/teams/api/index.ts +49 -0
- package/src/features/teams/api/leave-team.ts +22 -0
- package/src/features/teams/api/remove-member.ts +25 -0
- package/src/features/teams/api/resend-invitation.ts +26 -0
- package/src/features/teams/api/switch-team.ts +13 -0
- package/src/features/teams/api/types.ts +122 -0
- package/src/features/teams/api/update-member-roles.ts +28 -0
- package/src/features/teams/api/update-team.ts +17 -0
- package/src/features/teams/components/create-team-dialog.tsx +105 -0
- package/src/features/teams/hooks/__tests__/cache-invalidation.property.test.tsx +268 -0
- package/src/features/teams/hooks/index.ts +35 -0
- package/src/features/teams/hooks/use-can-manage-members.ts +21 -0
- package/src/features/teams/hooks/use-can-manage-team.ts +21 -0
- package/src/features/teams/hooks/use-cancel-invitation.ts +52 -0
- package/src/features/teams/hooks/use-create-invitation.ts +59 -0
- package/src/features/teams/hooks/use-create-team.ts +38 -0
- package/src/features/teams/hooks/use-delete-team.ts +43 -0
- package/src/features/teams/hooks/use-invitations.ts +31 -0
- package/src/features/teams/hooks/use-leave-team.ts +43 -0
- package/src/features/teams/hooks/use-remove-member.ts +58 -0
- package/src/features/teams/hooks/use-resend-invitation.ts +52 -0
- package/src/features/teams/hooks/use-switch-team.ts +41 -0
- package/src/features/teams/hooks/use-team-members.ts +31 -0
- package/src/features/teams/hooks/use-team-permissions.ts +102 -0
- package/src/features/teams/hooks/use-team.ts +30 -0
- package/src/features/teams/hooks/use-teams.ts +26 -0
- package/src/features/teams/hooks/use-update-member-roles.ts +64 -0
- package/src/features/teams/hooks/use-update-team.ts +47 -0
- package/src/features/teams/index.ts +111 -0
- package/src/features/user-settings/actions/set-password.ts +63 -0
- package/src/features/user-settings/api/index.ts +16 -0
- package/src/features/user-settings/components/__tests__/security-settings.test.tsx +125 -0
- package/src/features/user-settings/components/delete-account-dialog.tsx +185 -0
- package/src/features/user-settings/components/index.ts +13 -0
- package/src/features/user-settings/components/integrations-list.tsx +152 -0
- package/src/features/user-settings/components/notification-preferences.tsx +112 -0
- package/src/features/user-settings/components/other-settings.tsx +126 -0
- package/src/features/user-settings/components/password-section.tsx +297 -0
- package/src/features/user-settings/components/security-settings.tsx +184 -0
- package/src/features/user-settings/components/user-preferences.tsx +146 -0
- package/src/features/user-settings/hooks/index.ts +8 -0
- package/src/features/user-settings/hooks/use-notification-preferences.ts +65 -0
- package/src/features/user-settings/hooks/use-user-preferences.ts +52 -0
- package/src/features/user-settings/index.ts +22 -0
- package/src/features/user-settings/screens/index.ts +11 -0
- package/src/features/user-settings/screens/integrations-screen.tsx +24 -0
- package/src/features/user-settings/screens/notifications-screen.tsx +29 -0
- package/src/features/user-settings/screens/other-settings-screen.tsx +24 -0
- package/src/features/user-settings/screens/setting-preferences-screen.tsx +24 -0
- package/src/features/user-settings/screens/user-settings-screen.tsx +23 -0
- package/src/features/user-settings/types/index.ts +42 -0
- package/src/features/user-settings/utils/index.ts +8 -0
- package/src/hooks/use-long-press.ts +196 -0
- package/src/hooks/use-media-upload.ts +95 -0
- package/src/hooks/use-mobile.ts +19 -0
- package/src/hooks/use-team.ts +32 -0
- package/src/instrumentation.ts +14 -0
- package/src/lib/__tests__/auth-config.test.ts +166 -0
- package/src/lib/__tests__/config.test.ts +42 -0
- package/src/lib/__tests__/db.test.ts +101 -0
- package/src/lib/__tests__/env.property.test.ts +197 -0
- package/src/lib/__tests__/env.test.ts +177 -0
- package/src/lib/__tests__/health-check.test.ts +87 -0
- package/src/lib/__tests__/oauth-errors.test.ts +184 -0
- package/src/lib/__tests__/oauth-redirect.test.ts +224 -0
- package/src/lib/__tests__/oauth-scopes.test.ts +268 -0
- package/src/lib/__tests__/storage.test.ts +58 -0
- package/src/lib/__tests__/url-validator.test.ts +232 -0
- package/src/lib/api-client.ts +93 -0
- package/src/lib/auth-client.ts +5 -0
- package/src/lib/auth-config.ts +146 -0
- package/src/lib/auth.ts +209 -0
- package/src/lib/config.ts +228 -0
- package/src/lib/cors.ts +96 -0
- package/src/lib/date.ts +16 -0
- package/src/lib/db.ts +88 -0
- package/src/lib/env.ts +489 -0
- package/src/lib/feedback.ts +29 -0
- package/src/lib/health-check.ts +229 -0
- package/src/lib/logger.ts +204 -0
- package/src/lib/oauth-errors.ts +138 -0
- package/src/lib/performance.ts +367 -0
- package/src/lib/query-server.ts +35 -0
- package/src/lib/query.tsx +43 -0
- package/src/lib/resend.ts +36 -0
- package/src/lib/security-headers.ts +165 -0
- package/src/lib/setup-status.ts +34 -0
- package/src/lib/storage.ts +150 -0
- package/src/lib/supabase-client.ts +58 -0
- package/src/lib/testing/test-db.ts +75 -0
- package/src/lib/url-validator.ts +168 -0
- package/src/lib/utils.ts +6 -0
- package/src/mocks/README.md +42 -0
- package/src/mocks/activity.fixtures.ts +281 -0
- package/src/mocks/annotation.fixtures.ts +325 -0
- package/src/mocks/attachment.fixtures.ts +80 -0
- package/src/mocks/email.fixtures.ts +61 -0
- package/src/mocks/index.ts +33 -0
- package/src/mocks/issue.fixtures.ts +364 -0
- package/src/mocks/landing.fixtures.ts +118 -0
- package/src/mocks/notification.fixtures.ts +111 -0
- package/src/mocks/project-activity.fixtures.ts +69 -0
- package/src/mocks/project-invitation.fixtures.ts +95 -0
- package/src/mocks/project-member.fixtures.ts +93 -0
- package/src/mocks/project.fixtures.ts +249 -0
- package/src/mocks/settings.fixtures.ts +56 -0
- package/src/mocks/share.fixtures.ts +48 -0
- package/src/mocks/team-member.fixtures.ts +147 -0
- package/src/mocks/team.fixtures.ts +35 -0
- package/src/mocks/user-settings.fixtures.ts +77 -0
- package/src/mocks/user.fixtures.ts +21 -0
- package/src/providers/theme-provider.tsx +11 -0
- package/src/proxy/__tests__/proxy-setup-gate.test.ts +43 -0
- package/src/proxy.ts +169 -0
- package/src/server/annotations/__tests__/annotation-limit.property.test.ts +291 -0
- package/src/server/annotations/__tests__/attachment-deletion-cascade.property.test.ts +385 -0
- package/src/server/annotations/__tests__/comment-delete-authorization.property.test.ts +419 -0
- package/src/server/annotations/__tests__/sanitize.property.test.ts +302 -0
- package/src/server/annotations/annotation-service.ts +305 -0
- package/src/server/annotations/comment-service.ts +288 -0
- package/src/server/annotations/index.ts +61 -0
- package/src/server/annotations/permission-utils.ts +125 -0
- package/src/server/annotations/sanitize.ts +134 -0
- package/src/server/annotations/types.ts +161 -0
- package/src/server/audit/audit-service.ts +85 -0
- package/src/server/audit/index.ts +11 -0
- package/src/server/audit/types.ts +75 -0
- package/src/server/auth/__tests__/README.md +368 -0
- package/src/server/auth/__tests__/account-linking.integration.test.ts +410 -0
- package/src/server/auth/__tests__/auth-integration.test.ts +811 -0
- package/src/server/auth/__tests__/cookies.test.ts +337 -0
- package/src/server/auth/__tests__/login.property.test.ts +428 -0
- package/src/server/auth/__tests__/oauth-integration.test.ts +555 -0
- package/src/server/auth/__tests__/password.test.ts +194 -0
- package/src/server/auth/__tests__/rate-limiter.test.ts +450 -0
- package/src/server/auth/__tests__/rbac.test.ts +474 -0
- package/src/server/auth/__tests__/session.test.ts +599 -0
- package/src/server/auth/__tests__/signup.property.test.ts +224 -0
- package/src/server/auth/__tests__/token-encryption.test.ts +171 -0
- package/src/server/auth/__tests__/tokens.test.ts +476 -0
- package/src/server/auth/__tests__/verify-email.property.test.ts +372 -0
- package/src/server/auth/cookies.ts +184 -0
- package/src/server/auth/password.ts +94 -0
- package/src/server/auth/rate-limiter.ts +257 -0
- package/src/server/auth/rbac.ts +1168 -0
- package/src/server/auth/session.ts +392 -0
- package/src/server/auth/token-encryption.ts +201 -0
- package/src/server/auth/tokens.ts +397 -0
- package/src/server/db/schema/account.ts +21 -0
- package/src/server/db/schema/annotation-read-status.ts +57 -0
- package/src/server/db/schema/better-auth-verifications.ts +27 -0
- package/src/server/db/schema/email-jobs.ts +24 -0
- package/src/server/db/schema/index.ts +20 -0
- package/src/server/db/schema/instance-settings.ts +42 -0
- package/src/server/db/schema/issue-activities.ts +97 -0
- package/src/server/db/schema/issue-attachments.ts +101 -0
- package/src/server/db/schema/issues.ts +139 -0
- package/src/server/db/schema/notifications.ts +119 -0
- package/src/server/db/schema/project-activities.ts +116 -0
- package/src/server/db/schema/project-invitations.ts +34 -0
- package/src/server/db/schema/project-members.ts +29 -0
- package/src/server/db/schema/projects.ts +46 -0
- package/src/server/db/schema/sessions.ts +17 -0
- package/src/server/db/schema/team-invitations.ts +22 -0
- package/src/server/db/schema/team-members.ts +18 -0
- package/src/server/db/schema/teams.ts +15 -0
- package/src/server/db/schema/user-roles.ts +14 -0
- package/src/server/db/schema/users.ts +17 -0
- package/src/server/db/schema/verification-tokens.ts +15 -0
- package/src/server/email/README.md +258 -0
- package/src/server/email/__tests__/client.property.test.ts +218 -0
- package/src/server/email/__tests__/payload.property.test.ts +205 -0
- package/src/server/email/__tests__/queue.test.ts +407 -0
- package/src/server/email/__tests__/render-template.test.tsx +172 -0
- package/src/server/email/client.ts +70 -0
- package/src/server/email/index.ts +20 -0
- package/src/server/email/providers/console-provider.ts +43 -0
- package/src/server/email/providers/index.ts +5 -0
- package/src/server/email/providers/resend-provider.ts +59 -0
- package/src/server/email/providers/smtp-provider.ts +65 -0
- package/src/server/email/queue.ts +365 -0
- package/src/server/email/render-template.tsx +117 -0
- package/src/server/email/templates/layout.tsx +66 -0
- package/src/server/email/templates/ownership-transfer-email.tsx +75 -0
- package/src/server/email/templates/password-reset-email.tsx +72 -0
- package/src/server/email/templates/project-invitation-email.tsx +70 -0
- package/src/server/email/templates/security-alert-email.tsx +161 -0
- package/src/server/email/templates/team-invitation-email.tsx +68 -0
- package/src/server/email/templates/verification-email.tsx +61 -0
- package/src/server/email/templates/welcome-email.tsx +60 -0
- package/src/server/email/worker.ts +182 -0
- package/src/server/issues/activity-service.ts +422 -0
- package/src/server/issues/attachment-service.ts +379 -0
- package/src/server/issues/index.ts +68 -0
- package/src/server/issues/issue-service.ts +569 -0
- package/src/server/issues/types.ts +233 -0
- package/src/server/notifications/__tests__/notification-service.integration.test.ts +405 -0
- package/src/server/notifications/index.ts +13 -0
- package/src/server/notifications/notification-service.ts +526 -0
- package/src/server/notifications/types.ts +234 -0
- package/src/server/projects/__tests__/activity-logging.integration.test.ts +319 -0
- package/src/server/projects/__tests__/invitation-email.integration.test.ts +258 -0
- package/src/server/projects/__tests__/invitation-service.integration.test.ts +651 -0
- package/src/server/projects/__tests__/member-service.property.test.ts +397 -0
- package/src/server/projects/__tests__/project-service.property.test.ts +116 -0
- package/src/server/projects/activity-service.ts +548 -0
- package/src/server/projects/index.ts +11 -0
- package/src/server/projects/invitation-service.ts +773 -0
- package/src/server/projects/member-service.ts +458 -0
- package/src/server/projects/project-service.ts +491 -0
- package/src/server/projects/schemas.ts +310 -0
- package/src/server/projects/types.ts +166 -0
- package/src/server/projects/utils.ts +128 -0
- package/src/server/setup/__tests__/health-check.property.test.ts +70 -0
- package/src/server/setup/__tests__/sample-data.property.test.ts +82 -0
- package/src/server/setup/__tests__/setup.property.test.ts +95 -0
- package/src/server/setup/health-check-service.ts +294 -0
- package/src/server/setup/index.ts +35 -0
- package/src/server/setup/sample-data-service.ts +233 -0
- package/src/server/setup/setup-service.ts +229 -0
- package/src/server/setup/types.ts +96 -0
- package/src/server/teams/__tests__/export.property.test.ts +542 -0
- package/src/server/teams/__tests__/get-members.integration.test.ts +105 -0
- package/src/server/teams/__tests__/invitation-flow.integration.test.ts +402 -0
- package/src/server/teams/__tests__/invitations.property.test.ts +235 -0
- package/src/server/teams/__tests__/member-management-flow.integration.test.ts +306 -0
- package/src/server/teams/__tests__/members.property.test.ts +180 -0
- package/src/server/teams/__tests__/ownership-transfer.property.test.ts +173 -0
- package/src/server/teams/__tests__/resource-limits.property.test.ts +382 -0
- package/src/server/teams/__tests__/team-context-management.integration.test.ts +396 -0
- package/src/server/teams/__tests__/team-context.property.test.ts +854 -0
- package/src/server/teams/__tests__/team-creation-flow.integration.test.ts +310 -0
- package/src/server/teams/__tests__/team-creation.property.test.ts +280 -0
- package/src/server/teams/errors.ts +396 -0
- package/src/server/teams/export-service.ts +383 -0
- package/src/server/teams/index.ts +10 -0
- package/src/server/teams/invitation-service.ts +708 -0
- package/src/server/teams/member-service.ts +334 -0
- package/src/server/teams/resource-limits.ts +211 -0
- package/src/server/teams/slug.ts +58 -0
- package/src/server/teams/team-context.ts +648 -0
- package/src/server/teams/team-service.ts +660 -0
- package/src/server/teams/types.ts +81 -0
- package/src/server/teams/validation.ts +209 -0
- package/src/styles/globals.css +160 -0
- package/src/types/deployment.ts +39 -0
- package/supabase/config.toml +357 -0
- package/supabase/seed.sql +480 -0
- package/tests/e2e/.gitkeep +0 -0
- package/tests/e2e/QUICK_START.md +98 -0
- package/tests/e2e/README.md +301 -0
- package/tests/e2e/auth.spec.ts +583 -0
- package/tests/e2e/global-setup.ts +23 -0
- package/tests/e2e/global-teardown.ts +23 -0
- package/tests/e2e/helpers/auth-helpers.ts +310 -0
- package/tests/e2e/helpers/test-fixtures.ts +286 -0
- package/tests/e2e/smoke-test.spec.ts +330 -0
- package/tsconfig.json +48 -0
- package/vitest.config.ts +50 -0
- package/vitest.setup.ts +56 -0
- package/dist/index.js +0 -778
|
@@ -0,0 +1,1080 @@
|
|
|
1
|
+
# Database Migration Rollback Guide
|
|
2
|
+
|
|
3
|
+
This guide provides comprehensive procedures for rolling back database migrations safely and effectively.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 📋 Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Understanding Rollbacks](#understanding-rollbacks)
|
|
10
|
+
- [Rollback Strategies](#rollback-strategies)
|
|
11
|
+
- [Manual Rollback Procedures](#manual-rollback-procedures)
|
|
12
|
+
- [Rollback Migration Templates](#rollback-migration-templates)
|
|
13
|
+
- [Common Rollback Scenarios](#common-rollback-scenarios)
|
|
14
|
+
- [Database Backup and Restore](#database-backup-and-restore)
|
|
15
|
+
- [Emergency Procedures](#emergency-procedures)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🎯 Understanding Rollbacks
|
|
20
|
+
|
|
21
|
+
### What is a Rollback?
|
|
22
|
+
|
|
23
|
+
A rollback is the process of reverting database schema changes to a previous state. This is necessary when:
|
|
24
|
+
- A migration causes application errors
|
|
25
|
+
- Data integrity issues are discovered
|
|
26
|
+
- Performance problems arise
|
|
27
|
+
- Business requirements change
|
|
28
|
+
|
|
29
|
+
### Automatic vs Manual Rollbacks
|
|
30
|
+
|
|
31
|
+
**Automatic Rollback (Per-Migration Transaction):**
|
|
32
|
+
- Drizzle ORM wraps each migration in a PostgreSQL transaction
|
|
33
|
+
- If a migration fails, changes are automatically rolled back
|
|
34
|
+
- Database returns to pre-migration state
|
|
35
|
+
- Tracking table is NOT updated for failed migration
|
|
36
|
+
- **Scope:** Single migration only
|
|
37
|
+
|
|
38
|
+
**Manual Rollback (Reverting Applied Migrations):**
|
|
39
|
+
- Required when a migration succeeds but causes problems later
|
|
40
|
+
- Must be performed manually by creating a new "rollback migration"
|
|
41
|
+
- Can revert one or multiple migrations
|
|
42
|
+
- **Scope:** Any previously applied migration(s)
|
|
43
|
+
|
|
44
|
+
### Important Principles
|
|
45
|
+
|
|
46
|
+
1. **Never edit applied migrations** - They're already in the tracking table
|
|
47
|
+
2. **Always create forward migrations** - Even for rollbacks
|
|
48
|
+
3. **Test rollbacks locally first** - Before applying to production
|
|
49
|
+
4. **Coordinate with team** - Rollbacks may affect other developers
|
|
50
|
+
5. **Document the reason** - Why the rollback was necessary
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 🔄 Rollback Strategies
|
|
55
|
+
|
|
56
|
+
### Strategy 1: Rollback Migration (Recommended)
|
|
57
|
+
|
|
58
|
+
Create a new migration that undoes the changes:
|
|
59
|
+
|
|
60
|
+
**Pros:**
|
|
61
|
+
- Maintains migration history
|
|
62
|
+
- Can be reviewed and tested
|
|
63
|
+
- Works with CI/CD pipeline
|
|
64
|
+
- Trackable in version control
|
|
65
|
+
|
|
66
|
+
**Cons:**
|
|
67
|
+
- Requires creating new migration file
|
|
68
|
+
- Takes time to deploy through CI/CD
|
|
69
|
+
|
|
70
|
+
**When to use:**
|
|
71
|
+
- Non-urgent rollbacks
|
|
72
|
+
- When you want to maintain history
|
|
73
|
+
- When changes need review
|
|
74
|
+
|
|
75
|
+
### Strategy 2: Manual Database Fix + Skip Migration
|
|
76
|
+
|
|
77
|
+
Fix the database manually and mark migration as applied:
|
|
78
|
+
|
|
79
|
+
**Pros:**
|
|
80
|
+
- Immediate fix
|
|
81
|
+
- Useful for emergency situations
|
|
82
|
+
- Can fix complex issues
|
|
83
|
+
|
|
84
|
+
**Cons:**
|
|
85
|
+
- Bypasses version control
|
|
86
|
+
- Not reproducible
|
|
87
|
+
- Can cause inconsistencies across environments
|
|
88
|
+
|
|
89
|
+
**When to use:**
|
|
90
|
+
- Emergency production issues
|
|
91
|
+
- Complex data fixes
|
|
92
|
+
- One-off corrections
|
|
93
|
+
|
|
94
|
+
### Strategy 3: Git Revert + Redeploy
|
|
95
|
+
|
|
96
|
+
Revert the commit and redeploy:
|
|
97
|
+
|
|
98
|
+
**Pros:**
|
|
99
|
+
- Clean git history
|
|
100
|
+
- Removes problematic code
|
|
101
|
+
- Automatic through CI/CD
|
|
102
|
+
|
|
103
|
+
**Cons:**
|
|
104
|
+
- Migration may already be applied
|
|
105
|
+
- Doesn't remove database changes
|
|
106
|
+
- May require additional cleanup
|
|
107
|
+
|
|
108
|
+
**When to use:**
|
|
109
|
+
- Migration hasn't been applied yet
|
|
110
|
+
- Code and migration both need reverting
|
|
111
|
+
- Early in deployment process
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 🛠️ Manual Rollback Procedures
|
|
116
|
+
|
|
117
|
+
### Procedure 1: Simple Rollback Migration
|
|
118
|
+
|
|
119
|
+
**Use case:** Revert a single, straightforward migration
|
|
120
|
+
|
|
121
|
+
**Steps:**
|
|
122
|
+
|
|
123
|
+
1. **Identify the migration to rollback**
|
|
124
|
+
```bash
|
|
125
|
+
# List recent migrations
|
|
126
|
+
ls -la drizzle/ | tail -5
|
|
127
|
+
|
|
128
|
+
# View the migration content
|
|
129
|
+
cat drizzle/0010_add_user_bio.sql
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
2. **Create rollback migration**
|
|
133
|
+
```bash
|
|
134
|
+
# Generate timestamp
|
|
135
|
+
TIMESTAMP=$(date +%s)
|
|
136
|
+
|
|
137
|
+
# Create rollback file
|
|
138
|
+
cat > drizzle/${TIMESTAMP}_rollback_user_bio.sql << 'EOF'
|
|
139
|
+
-- Rollback: Remove user bio column
|
|
140
|
+
-- Reverts: 0010_add_user_bio.sql
|
|
141
|
+
|
|
142
|
+
ALTER TABLE users DROP COLUMN IF EXISTS bio;
|
|
143
|
+
DROP INDEX IF EXISTS users_bio_idx;
|
|
144
|
+
EOF
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
3. **Test locally**
|
|
148
|
+
```bash
|
|
149
|
+
# Apply rollback
|
|
150
|
+
bun run db:migrate
|
|
151
|
+
|
|
152
|
+
# Verify in Drizzle Studio
|
|
153
|
+
bun run db:studio
|
|
154
|
+
|
|
155
|
+
# Check table structure
|
|
156
|
+
# Verify bio column is removed
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
4. **Deploy**
|
|
160
|
+
```bash
|
|
161
|
+
git add drizzle/
|
|
162
|
+
git commit -m "rollback: remove user bio column"
|
|
163
|
+
git push
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Procedure 2: Multi-Step Rollback
|
|
167
|
+
|
|
168
|
+
**Use case:** Rollback requires multiple steps or data migration
|
|
169
|
+
|
|
170
|
+
**Steps:**
|
|
171
|
+
|
|
172
|
+
1. **Plan the rollback**
|
|
173
|
+
```
|
|
174
|
+
Original migration added:
|
|
175
|
+
- New column: users.bio
|
|
176
|
+
- Index: users_bio_idx
|
|
177
|
+
- Data: Populated bio from profile table
|
|
178
|
+
|
|
179
|
+
Rollback needs to:
|
|
180
|
+
- Remove index
|
|
181
|
+
- Remove column
|
|
182
|
+
- (Data is lost, acceptable)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
2. **Create rollback migration**
|
|
186
|
+
```bash
|
|
187
|
+
TIMESTAMP=$(date +%s)
|
|
188
|
+
cat > drizzle/${TIMESTAMP}_rollback_user_bio_complete.sql << 'EOF'
|
|
189
|
+
-- Rollback: Complete removal of user bio feature
|
|
190
|
+
-- Reverts: 0010_add_user_bio.sql, 0011_populate_user_bio.sql
|
|
191
|
+
|
|
192
|
+
-- Step 1: Remove index
|
|
193
|
+
DROP INDEX IF EXISTS users_bio_idx;
|
|
194
|
+
|
|
195
|
+
-- Step 2: Remove column (data will be lost)
|
|
196
|
+
ALTER TABLE users DROP COLUMN IF EXISTS bio;
|
|
197
|
+
|
|
198
|
+
-- Note: Original data from profile table is preserved
|
|
199
|
+
EOF
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
3. **Test and deploy** (same as Procedure 1)
|
|
203
|
+
|
|
204
|
+
### Procedure 3: Rollback with Data Preservation
|
|
205
|
+
|
|
206
|
+
**Use case:** Need to rollback but preserve data
|
|
207
|
+
|
|
208
|
+
**Steps:**
|
|
209
|
+
|
|
210
|
+
1. **Create backup table**
|
|
211
|
+
```sql
|
|
212
|
+
-- Create backup before rollback
|
|
213
|
+
CREATE TABLE users_bio_backup AS
|
|
214
|
+
SELECT id, bio, updated_at
|
|
215
|
+
FROM users
|
|
216
|
+
WHERE bio IS NOT NULL;
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
2. **Create rollback migration**
|
|
220
|
+
```bash
|
|
221
|
+
TIMESTAMP=$(date +%s)
|
|
222
|
+
cat > drizzle/${TIMESTAMP}_rollback_user_bio_with_backup.sql << 'EOF'
|
|
223
|
+
-- Rollback: Remove user bio with data backup
|
|
224
|
+
-- Reverts: 0010_add_user_bio.sql
|
|
225
|
+
|
|
226
|
+
-- Step 1: Backup existing data
|
|
227
|
+
CREATE TABLE IF NOT EXISTS users_bio_backup AS
|
|
228
|
+
SELECT id, bio, updated_at
|
|
229
|
+
FROM users
|
|
230
|
+
WHERE bio IS NOT NULL;
|
|
231
|
+
|
|
232
|
+
-- Step 2: Remove index
|
|
233
|
+
DROP INDEX IF EXISTS users_bio_idx;
|
|
234
|
+
|
|
235
|
+
-- Step 3: Remove column
|
|
236
|
+
ALTER TABLE users DROP COLUMN IF EXISTS bio;
|
|
237
|
+
|
|
238
|
+
-- Note: Data preserved in users_bio_backup table
|
|
239
|
+
-- Can be restored later if needed
|
|
240
|
+
EOF
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
3. **Document backup location**
|
|
244
|
+
```bash
|
|
245
|
+
# Add comment to commit
|
|
246
|
+
git commit -m "rollback: remove user bio (data backed up to users_bio_backup)"
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Procedure 4: Emergency Manual Rollback
|
|
250
|
+
|
|
251
|
+
**Use case:** Production is broken, need immediate fix
|
|
252
|
+
|
|
253
|
+
**Steps:**
|
|
254
|
+
|
|
255
|
+
1. **Access Supabase SQL Editor**
|
|
256
|
+
```
|
|
257
|
+
https://supabase.com/dashboard/project/PROJECT_ID/sql/new
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
2. **Execute rollback SQL**
|
|
261
|
+
```sql
|
|
262
|
+
-- Emergency rollback: Remove problematic column
|
|
263
|
+
BEGIN;
|
|
264
|
+
|
|
265
|
+
-- Remove index
|
|
266
|
+
DROP INDEX IF EXISTS users_bio_idx;
|
|
267
|
+
|
|
268
|
+
-- Remove column
|
|
269
|
+
ALTER TABLE users DROP COLUMN IF EXISTS bio;
|
|
270
|
+
|
|
271
|
+
-- Verify
|
|
272
|
+
SELECT column_name
|
|
273
|
+
FROM information_schema.columns
|
|
274
|
+
WHERE table_name = 'users';
|
|
275
|
+
|
|
276
|
+
COMMIT;
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
3. **Mark migration as "rolled back" in tracking**
|
|
280
|
+
```sql
|
|
281
|
+
-- Add comment to tracking table
|
|
282
|
+
COMMENT ON TABLE drizzle.__drizzle_migrations IS
|
|
283
|
+
'Migration 0010_add_user_bio manually rolled back on 2024-01-15';
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
4. **Create rollback migration for other environments**
|
|
287
|
+
```bash
|
|
288
|
+
# Still create migration file for dev/staging
|
|
289
|
+
TIMESTAMP=$(date +%s)
|
|
290
|
+
cat > drizzle/${TIMESTAMP}_rollback_user_bio.sql << 'EOF'
|
|
291
|
+
-- Rollback: Remove user bio column
|
|
292
|
+
-- Already applied manually to production on 2024-01-15
|
|
293
|
+
|
|
294
|
+
ALTER TABLE users DROP COLUMN IF EXISTS bio;
|
|
295
|
+
DROP INDEX IF EXISTS users_bio_idx;
|
|
296
|
+
EOF
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
5. **Document the emergency action**
|
|
300
|
+
```bash
|
|
301
|
+
# Create incident report
|
|
302
|
+
cat > docs/incidents/2024-01-15-bio-rollback.md << 'EOF'
|
|
303
|
+
# Emergency Rollback: User Bio Column
|
|
304
|
+
|
|
305
|
+
**Date:** 2024-01-15
|
|
306
|
+
**Environment:** Production
|
|
307
|
+
**Action:** Manual rollback via SQL Editor
|
|
308
|
+
|
|
309
|
+
## Issue
|
|
310
|
+
User bio column causing application errors
|
|
311
|
+
|
|
312
|
+
## Action Taken
|
|
313
|
+
- Manually dropped bio column and index
|
|
314
|
+
- Created rollback migration for other environments
|
|
315
|
+
|
|
316
|
+
## Follow-up
|
|
317
|
+
- [ ] Apply rollback migration to dev/staging
|
|
318
|
+
- [ ] Investigate root cause
|
|
319
|
+
- [ ] Update tests to catch similar issues
|
|
320
|
+
EOF
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 📝 Rollback Migration Templates
|
|
326
|
+
|
|
327
|
+
### Template 1: Drop Column
|
|
328
|
+
|
|
329
|
+
```sql
|
|
330
|
+
-- Rollback: Remove [column_name] column
|
|
331
|
+
-- Reverts: [original_migration_file]
|
|
332
|
+
-- Reason: [why rollback is needed]
|
|
333
|
+
|
|
334
|
+
-- Remove any indexes on the column
|
|
335
|
+
DROP INDEX IF EXISTS [table]_[column]_idx;
|
|
336
|
+
|
|
337
|
+
-- Remove the column
|
|
338
|
+
ALTER TABLE [table] DROP COLUMN IF EXISTS [column];
|
|
339
|
+
|
|
340
|
+
-- Verify
|
|
341
|
+
-- SELECT column_name FROM information_schema.columns
|
|
342
|
+
-- WHERE table_name = '[table]';
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Example:**
|
|
346
|
+
```sql
|
|
347
|
+
-- Rollback: Remove user bio column
|
|
348
|
+
-- Reverts: 0010_add_user_bio.sql
|
|
349
|
+
-- Reason: Performance issues with full-text search
|
|
350
|
+
|
|
351
|
+
DROP INDEX IF EXISTS users_bio_idx;
|
|
352
|
+
ALTER TABLE users DROP COLUMN IF EXISTS bio;
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Template 2: Drop Table
|
|
356
|
+
|
|
357
|
+
```sql
|
|
358
|
+
-- Rollback: Remove [table_name] table
|
|
359
|
+
-- Reverts: [original_migration_file]
|
|
360
|
+
-- Reason: [why rollback is needed]
|
|
361
|
+
-- WARNING: This will delete all data in the table
|
|
362
|
+
|
|
363
|
+
-- Remove dependent foreign keys first (if any)
|
|
364
|
+
ALTER TABLE [dependent_table]
|
|
365
|
+
DROP CONSTRAINT IF EXISTS [fk_constraint_name];
|
|
366
|
+
|
|
367
|
+
-- Drop indexes
|
|
368
|
+
DROP INDEX IF EXISTS [table]_[column]_idx;
|
|
369
|
+
|
|
370
|
+
-- Drop the table
|
|
371
|
+
DROP TABLE IF EXISTS [table] CASCADE;
|
|
372
|
+
|
|
373
|
+
-- Verify
|
|
374
|
+
-- SELECT tablename FROM pg_tables
|
|
375
|
+
-- WHERE schemaname = 'public';
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
**Example:**
|
|
379
|
+
```sql
|
|
380
|
+
-- Rollback: Remove comments table
|
|
381
|
+
-- Reverts: 0015_create_comments.sql
|
|
382
|
+
-- Reason: Feature postponed to next sprint
|
|
383
|
+
-- WARNING: This will delete all comment data
|
|
384
|
+
|
|
385
|
+
DROP INDEX IF EXISTS comments_user_id_idx;
|
|
386
|
+
DROP INDEX IF EXISTS comments_post_id_idx;
|
|
387
|
+
DROP TABLE IF EXISTS comments CASCADE;
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Template 3: Revert Column Modification
|
|
391
|
+
|
|
392
|
+
```sql
|
|
393
|
+
-- Rollback: Revert [column_name] changes
|
|
394
|
+
-- Reverts: [original_migration_file]
|
|
395
|
+
-- Reason: [why rollback is needed]
|
|
396
|
+
|
|
397
|
+
-- Revert data type change
|
|
398
|
+
ALTER TABLE [table]
|
|
399
|
+
ALTER COLUMN [column] TYPE [original_type];
|
|
400
|
+
|
|
401
|
+
-- Revert constraint changes
|
|
402
|
+
ALTER TABLE [table]
|
|
403
|
+
ALTER COLUMN [column] DROP NOT NULL; -- or SET NOT NULL
|
|
404
|
+
|
|
405
|
+
-- Revert default value
|
|
406
|
+
ALTER TABLE [table]
|
|
407
|
+
ALTER COLUMN [column] SET DEFAULT [original_default]; -- or DROP DEFAULT
|
|
408
|
+
|
|
409
|
+
-- Verify
|
|
410
|
+
-- SELECT column_name, data_type, is_nullable, column_default
|
|
411
|
+
-- FROM information_schema.columns
|
|
412
|
+
-- WHERE table_name = '[table]' AND column_name = '[column]';
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**Example:**
|
|
416
|
+
```sql
|
|
417
|
+
-- Rollback: Revert email column changes
|
|
418
|
+
-- Reverts: 0012_make_email_required.sql
|
|
419
|
+
-- Reason: Breaks existing user import process
|
|
420
|
+
|
|
421
|
+
ALTER TABLE users
|
|
422
|
+
ALTER COLUMN email DROP NOT NULL;
|
|
423
|
+
|
|
424
|
+
ALTER TABLE users
|
|
425
|
+
DROP CONSTRAINT IF EXISTS users_email_unique;
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### Template 4: Remove Foreign Key
|
|
429
|
+
|
|
430
|
+
```sql
|
|
431
|
+
-- Rollback: Remove foreign key constraint
|
|
432
|
+
-- Reverts: [original_migration_file]
|
|
433
|
+
-- Reason: [why rollback is needed]
|
|
434
|
+
|
|
435
|
+
-- Remove foreign key constraint
|
|
436
|
+
ALTER TABLE [table]
|
|
437
|
+
DROP CONSTRAINT IF EXISTS [fk_constraint_name];
|
|
438
|
+
|
|
439
|
+
-- Remove index on foreign key column
|
|
440
|
+
DROP INDEX IF EXISTS [table]_[column]_idx;
|
|
441
|
+
|
|
442
|
+
-- Optionally remove the column
|
|
443
|
+
-- ALTER TABLE [table] DROP COLUMN IF EXISTS [column];
|
|
444
|
+
|
|
445
|
+
-- Verify
|
|
446
|
+
-- SELECT conname, contype
|
|
447
|
+
-- FROM pg_constraint
|
|
448
|
+
-- WHERE conrelid = '[table]'::regclass;
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**Example:**
|
|
452
|
+
```sql
|
|
453
|
+
-- Rollback: Remove project owner foreign key
|
|
454
|
+
-- Reverts: 0015_add_project_owner.sql
|
|
455
|
+
-- Reason: Owner relationship needs redesign
|
|
456
|
+
|
|
457
|
+
ALTER TABLE projects
|
|
458
|
+
DROP CONSTRAINT IF EXISTS projects_owner_id_fkey;
|
|
459
|
+
|
|
460
|
+
DROP INDEX IF EXISTS projects_owner_id_idx;
|
|
461
|
+
|
|
462
|
+
-- Keep column but make nullable
|
|
463
|
+
ALTER TABLE projects
|
|
464
|
+
ALTER COLUMN owner_id DROP NOT NULL;
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Template 5: Remove Enum Type
|
|
468
|
+
|
|
469
|
+
```sql
|
|
470
|
+
-- Rollback: Remove enum type
|
|
471
|
+
-- Reverts: [original_migration_file]
|
|
472
|
+
-- Reason: [why rollback is needed]
|
|
473
|
+
|
|
474
|
+
-- First, remove column using the enum
|
|
475
|
+
ALTER TABLE [table] DROP COLUMN IF EXISTS [column];
|
|
476
|
+
|
|
477
|
+
-- Then drop the enum type
|
|
478
|
+
DROP TYPE IF EXISTS [enum_name];
|
|
479
|
+
|
|
480
|
+
-- Verify
|
|
481
|
+
-- SELECT typname FROM pg_type WHERE typtype = 'e';
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Example:**
|
|
485
|
+
```sql
|
|
486
|
+
-- Rollback: Remove user status enum
|
|
487
|
+
-- Reverts: 0014_add_user_status_enum.sql
|
|
488
|
+
-- Reason: Status model needs to be more flexible
|
|
489
|
+
|
|
490
|
+
DROP INDEX IF EXISTS users_status_idx;
|
|
491
|
+
ALTER TABLE users DROP COLUMN IF EXISTS status;
|
|
492
|
+
DROP TYPE IF EXISTS user_status;
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Template 6: Rollback with Data Backup
|
|
496
|
+
|
|
497
|
+
```sql
|
|
498
|
+
-- Rollback: Remove [feature] with data backup
|
|
499
|
+
-- Reverts: [original_migration_file]
|
|
500
|
+
-- Reason: [why rollback is needed]
|
|
501
|
+
-- Note: Data backed up to [backup_table]
|
|
502
|
+
|
|
503
|
+
-- Step 1: Create backup table
|
|
504
|
+
CREATE TABLE IF NOT EXISTS [backup_table] AS
|
|
505
|
+
SELECT [columns]
|
|
506
|
+
FROM [table]
|
|
507
|
+
WHERE [condition];
|
|
508
|
+
|
|
509
|
+
-- Step 2: Remove indexes
|
|
510
|
+
DROP INDEX IF EXISTS [table]_[column]_idx;
|
|
511
|
+
|
|
512
|
+
-- Step 3: Remove column/table
|
|
513
|
+
ALTER TABLE [table] DROP COLUMN IF EXISTS [column];
|
|
514
|
+
-- OR: DROP TABLE IF EXISTS [table];
|
|
515
|
+
|
|
516
|
+
-- Step 4: Add comment for future reference
|
|
517
|
+
COMMENT ON TABLE [backup_table] IS
|
|
518
|
+
'Backup created during rollback on [date]. Contains data from [table].[column]';
|
|
519
|
+
|
|
520
|
+
-- Verify backup
|
|
521
|
+
-- SELECT COUNT(*) FROM [backup_table];
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
**Example:**
|
|
525
|
+
```sql
|
|
526
|
+
-- Rollback: Remove user preferences with backup
|
|
527
|
+
-- Reverts: 0020_add_user_preferences.sql
|
|
528
|
+
-- Reason: Preferences system being redesigned
|
|
529
|
+
-- Note: Data backed up to user_preferences_backup
|
|
530
|
+
|
|
531
|
+
CREATE TABLE IF NOT EXISTS user_preferences_backup AS
|
|
532
|
+
SELECT user_id, preferences, updated_at
|
|
533
|
+
FROM users
|
|
534
|
+
WHERE preferences IS NOT NULL;
|
|
535
|
+
|
|
536
|
+
DROP INDEX IF EXISTS users_preferences_idx;
|
|
537
|
+
ALTER TABLE users DROP COLUMN IF EXISTS preferences;
|
|
538
|
+
|
|
539
|
+
COMMENT ON TABLE user_preferences_backup IS
|
|
540
|
+
'Backup created during rollback on 2024-01-15. Contains user preferences data.';
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
## 🎯 Common Rollback Scenarios
|
|
546
|
+
|
|
547
|
+
### Scenario 1: Rollback Column Addition
|
|
548
|
+
|
|
549
|
+
**Original Migration:**
|
|
550
|
+
```sql
|
|
551
|
+
-- 0010_add_user_bio.sql
|
|
552
|
+
ALTER TABLE users ADD COLUMN bio TEXT;
|
|
553
|
+
CREATE INDEX users_bio_idx ON users(bio);
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
**Rollback Migration:**
|
|
557
|
+
```sql
|
|
558
|
+
-- 0011_rollback_user_bio.sql
|
|
559
|
+
DROP INDEX IF EXISTS users_bio_idx;
|
|
560
|
+
ALTER TABLE users DROP COLUMN IF EXISTS bio;
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
**Testing:**
|
|
564
|
+
```bash
|
|
565
|
+
# Apply original
|
|
566
|
+
bun run db:migrate
|
|
567
|
+
|
|
568
|
+
# Verify column exists
|
|
569
|
+
bun run db:studio
|
|
570
|
+
|
|
571
|
+
# Apply rollback
|
|
572
|
+
bun run db:migrate
|
|
573
|
+
|
|
574
|
+
# Verify column removed
|
|
575
|
+
bun run db:studio
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Scenario 2: Rollback Table Creation
|
|
579
|
+
|
|
580
|
+
**Original Migration:**
|
|
581
|
+
```sql
|
|
582
|
+
-- 0015_create_comments.sql
|
|
583
|
+
CREATE TABLE comments (
|
|
584
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
585
|
+
user_id UUID NOT NULL REFERENCES users(id),
|
|
586
|
+
content TEXT NOT NULL,
|
|
587
|
+
created_at TIMESTAMP DEFAULT NOW()
|
|
588
|
+
);
|
|
589
|
+
|
|
590
|
+
CREATE INDEX comments_user_id_idx ON comments(user_id);
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
**Rollback Migration:**
|
|
594
|
+
```sql
|
|
595
|
+
-- 0016_rollback_comments.sql
|
|
596
|
+
DROP INDEX IF EXISTS comments_user_id_idx;
|
|
597
|
+
DROP TABLE IF EXISTS comments CASCADE;
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Scenario 3: Rollback Column Type Change
|
|
601
|
+
|
|
602
|
+
**Original Migration:**
|
|
603
|
+
```sql
|
|
604
|
+
-- 0020_change_email_length.sql
|
|
605
|
+
ALTER TABLE users
|
|
606
|
+
ALTER COLUMN email TYPE VARCHAR(500);
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
**Rollback Migration:**
|
|
610
|
+
```sql
|
|
611
|
+
-- 0021_rollback_email_length.sql
|
|
612
|
+
-- Revert email column to original length
|
|
613
|
+
-- Note: Will fail if any emails exceed 255 characters
|
|
614
|
+
|
|
615
|
+
-- Check for long emails first
|
|
616
|
+
DO $$
|
|
617
|
+
BEGIN
|
|
618
|
+
IF EXISTS (
|
|
619
|
+
SELECT 1 FROM users WHERE LENGTH(email) > 255
|
|
620
|
+
) THEN
|
|
621
|
+
RAISE EXCEPTION 'Cannot rollback: Some emails exceed 255 characters';
|
|
622
|
+
END IF;
|
|
623
|
+
END $$;
|
|
624
|
+
|
|
625
|
+
-- Revert type change
|
|
626
|
+
ALTER TABLE users
|
|
627
|
+
ALTER COLUMN email TYPE VARCHAR(255);
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Scenario 4: Rollback NOT NULL Constraint
|
|
631
|
+
|
|
632
|
+
**Original Migration:**
|
|
633
|
+
```sql
|
|
634
|
+
-- 0025_make_bio_required.sql
|
|
635
|
+
UPDATE users SET bio = '' WHERE bio IS NULL;
|
|
636
|
+
ALTER TABLE users ALTER COLUMN bio SET NOT NULL;
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
**Rollback Migration:**
|
|
640
|
+
```sql
|
|
641
|
+
-- 0026_rollback_bio_required.sql
|
|
642
|
+
ALTER TABLE users ALTER COLUMN bio DROP NOT NULL;
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
### Scenario 5: Rollback Foreign Key Addition
|
|
646
|
+
|
|
647
|
+
**Original Migration:**
|
|
648
|
+
```sql
|
|
649
|
+
-- 0030_add_project_owner.sql
|
|
650
|
+
ALTER TABLE projects ADD COLUMN owner_id UUID;
|
|
651
|
+
UPDATE projects SET owner_id = (SELECT id FROM users LIMIT 1);
|
|
652
|
+
ALTER TABLE projects ALTER COLUMN owner_id SET NOT NULL;
|
|
653
|
+
ALTER TABLE projects
|
|
654
|
+
ADD CONSTRAINT projects_owner_id_fkey
|
|
655
|
+
FOREIGN KEY (owner_id) REFERENCES users(id);
|
|
656
|
+
CREATE INDEX projects_owner_id_idx ON projects(owner_id);
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
**Rollback Migration:**
|
|
660
|
+
```sql
|
|
661
|
+
-- 0031_rollback_project_owner.sql
|
|
662
|
+
DROP INDEX IF EXISTS projects_owner_id_idx;
|
|
663
|
+
ALTER TABLE projects DROP CONSTRAINT IF EXISTS projects_owner_id_fkey;
|
|
664
|
+
ALTER TABLE projects DROP COLUMN IF EXISTS owner_id;
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
### Scenario 6: Rollback with Data Migration
|
|
668
|
+
|
|
669
|
+
**Original Migration:**
|
|
670
|
+
```sql
|
|
671
|
+
-- 0035_split_user_name.sql
|
|
672
|
+
ALTER TABLE users ADD COLUMN first_name VARCHAR(100);
|
|
673
|
+
ALTER TABLE users ADD COLUMN last_name VARCHAR(100);
|
|
674
|
+
|
|
675
|
+
UPDATE users
|
|
676
|
+
SET
|
|
677
|
+
first_name = SPLIT_PART(name, ' ', 1),
|
|
678
|
+
last_name = SPLIT_PART(name, ' ', 2)
|
|
679
|
+
WHERE name IS NOT NULL;
|
|
680
|
+
|
|
681
|
+
ALTER TABLE users DROP COLUMN name;
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
**Rollback Migration:**
|
|
685
|
+
```sql
|
|
686
|
+
-- 0036_rollback_split_user_name.sql
|
|
687
|
+
-- Restore original name column from split names
|
|
688
|
+
|
|
689
|
+
ALTER TABLE users ADD COLUMN name VARCHAR(200);
|
|
690
|
+
|
|
691
|
+
UPDATE users
|
|
692
|
+
SET name = CONCAT(first_name, ' ', last_name)
|
|
693
|
+
WHERE first_name IS NOT NULL OR last_name IS NOT NULL;
|
|
694
|
+
|
|
695
|
+
ALTER TABLE users DROP COLUMN IF EXISTS first_name;
|
|
696
|
+
ALTER TABLE users DROP COLUMN IF EXISTS last_name;
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### Scenario 7: Rollback Index Addition
|
|
700
|
+
|
|
701
|
+
**Original Migration:**
|
|
702
|
+
```sql
|
|
703
|
+
-- 0040_add_search_indexes.sql
|
|
704
|
+
CREATE INDEX users_email_idx ON users(email);
|
|
705
|
+
CREATE INDEX users_name_idx ON users(name);
|
|
706
|
+
CREATE INDEX projects_name_idx ON projects(name);
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
**Rollback Migration:**
|
|
710
|
+
```sql
|
|
711
|
+
-- 0041_rollback_search_indexes.sql
|
|
712
|
+
DROP INDEX IF EXISTS users_email_idx;
|
|
713
|
+
DROP INDEX IF EXISTS users_name_idx;
|
|
714
|
+
DROP INDEX IF EXISTS projects_name_idx;
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### Scenario 8: Rollback Enum Addition
|
|
718
|
+
|
|
719
|
+
**Original Migration:**
|
|
720
|
+
```sql
|
|
721
|
+
-- 0045_add_priority_enum.sql
|
|
722
|
+
CREATE TYPE issue_priority AS ENUM ('low', 'medium', 'high', 'urgent');
|
|
723
|
+
|
|
724
|
+
ALTER TABLE issues
|
|
725
|
+
ADD COLUMN priority issue_priority DEFAULT 'medium' NOT NULL;
|
|
726
|
+
|
|
727
|
+
CREATE INDEX issues_priority_idx ON issues(priority);
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
**Rollback Migration:**
|
|
731
|
+
```sql
|
|
732
|
+
-- 0046_rollback_priority_enum.sql
|
|
733
|
+
DROP INDEX IF EXISTS issues_priority_idx;
|
|
734
|
+
ALTER TABLE issues DROP COLUMN IF EXISTS priority;
|
|
735
|
+
DROP TYPE IF EXISTS issue_priority;
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
---
|
|
739
|
+
|
|
740
|
+
## 💾 Database Backup and Restore
|
|
741
|
+
|
|
742
|
+
### Backup Strategies
|
|
743
|
+
|
|
744
|
+
#### Strategy 1: Supabase Dashboard Backup
|
|
745
|
+
|
|
746
|
+
**Use case:** Regular backups, point-in-time recovery
|
|
747
|
+
|
|
748
|
+
**Steps:**
|
|
749
|
+
1. Navigate to Supabase Dashboard
|
|
750
|
+
2. Go to Database → Backups
|
|
751
|
+
3. Click "Create Backup"
|
|
752
|
+
4. Wait for backup to complete
|
|
753
|
+
5. Download backup if needed
|
|
754
|
+
|
|
755
|
+
**Pros:**
|
|
756
|
+
- Easy to use
|
|
757
|
+
- Automatic daily backups (Pro plan)
|
|
758
|
+
- Point-in-time recovery available
|
|
759
|
+
- No CLI required
|
|
760
|
+
|
|
761
|
+
**Cons:**
|
|
762
|
+
- Requires dashboard access
|
|
763
|
+
- May take time for large databases
|
|
764
|
+
- Limited to Supabase features
|
|
765
|
+
|
|
766
|
+
#### Strategy 2: pg_dump Backup
|
|
767
|
+
|
|
768
|
+
**Use case:** Manual backups, migration between environments
|
|
769
|
+
|
|
770
|
+
**Full Database Backup:**
|
|
771
|
+
```bash
|
|
772
|
+
# Backup entire database
|
|
773
|
+
pg_dump "$DIRECT_URL" > backup_$(date +%Y%m%d_%H%M%S).sql
|
|
774
|
+
|
|
775
|
+
# Backup with compression
|
|
776
|
+
pg_dump "$DIRECT_URL" | gzip > backup_$(date +%Y%m%d_%H%M%S).sql.gz
|
|
777
|
+
|
|
778
|
+
# Backup specific schema
|
|
779
|
+
pg_dump "$DIRECT_URL" --schema=public > backup_public_$(date +%Y%m%d_%H%M%S).sql
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
**Table-Specific Backup:**
|
|
783
|
+
```bash
|
|
784
|
+
# Backup single table
|
|
785
|
+
pg_dump "$DIRECT_URL" --table=users > backup_users_$(date +%Y%m%d_%H%M%S).sql
|
|
786
|
+
|
|
787
|
+
# Backup multiple tables
|
|
788
|
+
pg_dump "$DIRECT_URL" --table=users --table=projects > backup_tables_$(date +%Y%m%d_%H%M%S).sql
|
|
789
|
+
|
|
790
|
+
# Backup data only (no schema)
|
|
791
|
+
pg_dump "$DIRECT_URL" --data-only --table=users > backup_users_data_$(date +%Y%m%d_%H%M%S).sql
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
**Schema-Only Backup:**
|
|
795
|
+
```bash
|
|
796
|
+
# Backup schema structure only
|
|
797
|
+
pg_dump "$DIRECT_URL" --schema-only > backup_schema_$(date +%Y%m%d_%H%M%S).sql
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
#### Strategy 3: Selective Data Backup
|
|
801
|
+
|
|
802
|
+
**Use case:** Backup specific data before risky migration
|
|
803
|
+
|
|
804
|
+
**SQL Backup:**
|
|
805
|
+
```sql
|
|
806
|
+
-- Create backup table
|
|
807
|
+
CREATE TABLE users_backup_20240115 AS
|
|
808
|
+
SELECT * FROM users;
|
|
809
|
+
|
|
810
|
+
-- Backup with timestamp
|
|
811
|
+
CREATE TABLE users_backup AS
|
|
812
|
+
SELECT *, NOW() as backup_created_at
|
|
813
|
+
FROM users;
|
|
814
|
+
|
|
815
|
+
-- Backup specific columns
|
|
816
|
+
CREATE TABLE users_email_backup AS
|
|
817
|
+
SELECT id, email, updated_at
|
|
818
|
+
FROM users;
|
|
819
|
+
|
|
820
|
+
-- Backup with condition
|
|
821
|
+
CREATE TABLE users_active_backup AS
|
|
822
|
+
SELECT * FROM users
|
|
823
|
+
WHERE status = 'active';
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
### Restore Procedures
|
|
827
|
+
|
|
828
|
+
#### Restore from pg_dump
|
|
829
|
+
|
|
830
|
+
**Full Database Restore:**
|
|
831
|
+
```bash
|
|
832
|
+
# Restore from uncompressed backup
|
|
833
|
+
psql "$DIRECT_URL" < backup_20240115_120000.sql
|
|
834
|
+
|
|
835
|
+
# Restore from compressed backup
|
|
836
|
+
gunzip -c backup_20240115_120000.sql.gz | psql "$DIRECT_URL"
|
|
837
|
+
|
|
838
|
+
# Restore with transaction (safer)
|
|
839
|
+
psql "$DIRECT_URL" --single-transaction < backup_20240115_120000.sql
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
**Table-Specific Restore:**
|
|
843
|
+
```bash
|
|
844
|
+
# Restore single table
|
|
845
|
+
psql "$DIRECT_URL" < backup_users_20240115_120000.sql
|
|
846
|
+
|
|
847
|
+
# Restore with drop existing table
|
|
848
|
+
psql "$DIRECT_URL" << 'EOF'
|
|
849
|
+
DROP TABLE IF EXISTS users CASCADE;
|
|
850
|
+
\i backup_users_20240115_120000.sql
|
|
851
|
+
EOF
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
#### Restore from Backup Table
|
|
855
|
+
|
|
856
|
+
**SQL Restore:**
|
|
857
|
+
```sql
|
|
858
|
+
-- Restore from backup table
|
|
859
|
+
BEGIN;
|
|
860
|
+
|
|
861
|
+
-- Drop current table
|
|
862
|
+
DROP TABLE users CASCADE;
|
|
863
|
+
|
|
864
|
+
-- Recreate from backup
|
|
865
|
+
CREATE TABLE users AS
|
|
866
|
+
SELECT * FROM users_backup_20240115;
|
|
867
|
+
|
|
868
|
+
-- Recreate constraints and indexes
|
|
869
|
+
ALTER TABLE users ADD PRIMARY KEY (id);
|
|
870
|
+
CREATE INDEX users_email_idx ON users(email);
|
|
871
|
+
-- ... other constraints
|
|
872
|
+
|
|
873
|
+
COMMIT;
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
**Selective Restore:**
|
|
877
|
+
```sql
|
|
878
|
+
-- Restore specific rows
|
|
879
|
+
BEGIN;
|
|
880
|
+
|
|
881
|
+
-- Restore deleted users
|
|
882
|
+
INSERT INTO users
|
|
883
|
+
SELECT * FROM users_backup_20240115
|
|
884
|
+
WHERE id NOT IN (SELECT id FROM users);
|
|
885
|
+
|
|
886
|
+
COMMIT;
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
#### Restore from Supabase Backup
|
|
890
|
+
|
|
891
|
+
**Steps:**
|
|
892
|
+
1. Navigate to Supabase Dashboard
|
|
893
|
+
2. Go to Database → Backups
|
|
894
|
+
3. Find the backup to restore
|
|
895
|
+
4. Click "Restore"
|
|
896
|
+
5. Confirm restoration
|
|
897
|
+
6. Wait for process to complete
|
|
898
|
+
|
|
899
|
+
**Note:** This will replace the entire database!
|
|
900
|
+
|
|
901
|
+
### Backup Best Practices
|
|
902
|
+
|
|
903
|
+
**Before Risky Migrations:**
|
|
904
|
+
```bash
|
|
905
|
+
# 1. Create backup
|
|
906
|
+
pg_dump "$DIRECT_URL" | gzip > pre_migration_backup_$(date +%Y%m%d_%H%M%S).sql.gz
|
|
907
|
+
|
|
908
|
+
# 2. Verify backup
|
|
909
|
+
gunzip -c pre_migration_backup_*.sql.gz | head -n 20
|
|
910
|
+
|
|
911
|
+
# 3. Store backup securely
|
|
912
|
+
# Upload to S3, Google Drive, or secure storage
|
|
913
|
+
|
|
914
|
+
# 4. Run migration
|
|
915
|
+
bun run db:migrate
|
|
916
|
+
|
|
917
|
+
# 5. Verify migration
|
|
918
|
+
bun run db:studio
|
|
919
|
+
|
|
920
|
+
# 6. Keep backup for 30 days
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
**Automated Backup Script:**
|
|
924
|
+
```bash
|
|
925
|
+
#!/bin/bash
|
|
926
|
+
# scripts/backup-db.sh
|
|
927
|
+
|
|
928
|
+
set -e
|
|
929
|
+
|
|
930
|
+
BACKUP_DIR="./backups"
|
|
931
|
+
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
932
|
+
BACKUP_FILE="$BACKUP_DIR/backup_$TIMESTAMP.sql.gz"
|
|
933
|
+
|
|
934
|
+
# Create backup directory
|
|
935
|
+
mkdir -p "$BACKUP_DIR"
|
|
936
|
+
|
|
937
|
+
# Create backup
|
|
938
|
+
echo "Creating backup..."
|
|
939
|
+
pg_dump "$DIRECT_URL" | gzip > "$BACKUP_FILE"
|
|
940
|
+
|
|
941
|
+
# Verify backup
|
|
942
|
+
if [ -f "$BACKUP_FILE" ]; then
|
|
943
|
+
SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
|
|
944
|
+
echo "✅ Backup created: $BACKUP_FILE ($SIZE)"
|
|
945
|
+
else
|
|
946
|
+
echo "❌ Backup failed"
|
|
947
|
+
exit 1
|
|
948
|
+
fi
|
|
949
|
+
|
|
950
|
+
# Clean old backups (keep last 30 days)
|
|
951
|
+
find "$BACKUP_DIR" -name "backup_*.sql.gz" -mtime +30 -delete
|
|
952
|
+
|
|
953
|
+
echo "✅ Backup complete"
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
---
|
|
957
|
+
|
|
958
|
+
## 🚨 Emergency Procedures
|
|
959
|
+
|
|
960
|
+
### Emergency Rollback Checklist
|
|
961
|
+
|
|
962
|
+
**When production is broken:**
|
|
963
|
+
|
|
964
|
+
1. **Assess the situation** (2 minutes)
|
|
965
|
+
- [ ] Identify the problematic migration
|
|
966
|
+
- [ ] Determine impact (users affected, data at risk)
|
|
967
|
+
- [ ] Check if automatic rollback occurred
|
|
968
|
+
- [ ] Review error logs
|
|
969
|
+
|
|
970
|
+
2. **Communicate** (1 minute)
|
|
971
|
+
- [ ] Notify team in Slack/Discord
|
|
972
|
+
- [ ] Update status page if applicable
|
|
973
|
+
- [ ] Assign incident commander
|
|
974
|
+
|
|
975
|
+
3. **Execute emergency rollback** (5-10 minutes)
|
|
976
|
+
- [ ] Access Supabase SQL Editor
|
|
977
|
+
- [ ] Execute rollback SQL
|
|
978
|
+
- [ ] Verify changes
|
|
979
|
+
- [ ] Test critical functionality
|
|
980
|
+
|
|
981
|
+
4. **Verify fix** (2 minutes)
|
|
982
|
+
- [ ] Check application is working
|
|
983
|
+
- [ ] Verify no data loss
|
|
984
|
+
- [ ] Monitor error rates
|
|
985
|
+
|
|
986
|
+
5. **Document** (5 minutes)
|
|
987
|
+
- [ ] Create incident report
|
|
988
|
+
- [ ] Document actions taken
|
|
989
|
+
- [ ] Create rollback migration for other environments
|
|
990
|
+
|
|
991
|
+
6. **Follow-up** (next day)
|
|
992
|
+
- [ ] Root cause analysis
|
|
993
|
+
- [ ] Update tests
|
|
994
|
+
- [ ] Improve migration process
|
|
995
|
+
|
|
996
|
+
### Emergency Rollback SQL Template
|
|
997
|
+
|
|
998
|
+
```sql
|
|
999
|
+
-- EMERGENCY ROLLBACK
|
|
1000
|
+
-- Date: [YYYY-MM-DD HH:MM]
|
|
1001
|
+
-- Incident: [Brief description]
|
|
1002
|
+
-- Migration: [migration file name]
|
|
1003
|
+
-- Executed by: [Your name]
|
|
1004
|
+
|
|
1005
|
+
BEGIN;
|
|
1006
|
+
|
|
1007
|
+
-- Backup current state (if possible)
|
|
1008
|
+
CREATE TABLE emergency_backup_[timestamp] AS
|
|
1009
|
+
SELECT * FROM [affected_table];
|
|
1010
|
+
|
|
1011
|
+
-- Execute rollback
|
|
1012
|
+
[ROLLBACK SQL HERE]
|
|
1013
|
+
|
|
1014
|
+
-- Verify
|
|
1015
|
+
SELECT COUNT(*) FROM [affected_table];
|
|
1016
|
+
|
|
1017
|
+
-- If everything looks good, commit
|
|
1018
|
+
COMMIT;
|
|
1019
|
+
-- If something is wrong, ROLLBACK;
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
### Emergency Contacts
|
|
1023
|
+
|
|
1024
|
+
**Before emergency:**
|
|
1025
|
+
- Document who has production database access
|
|
1026
|
+
- Set up alerting for migration failures
|
|
1027
|
+
- Create runbook for common issues
|
|
1028
|
+
- Test emergency procedures
|
|
1029
|
+
|
|
1030
|
+
**During emergency:**
|
|
1031
|
+
- Follow the checklist above
|
|
1032
|
+
- Don't panic - transactions protect you
|
|
1033
|
+
- Document everything
|
|
1034
|
+
- Communicate clearly
|
|
1035
|
+
|
|
1036
|
+
**After emergency:**
|
|
1037
|
+
- Conduct blameless postmortem
|
|
1038
|
+
- Update procedures
|
|
1039
|
+
- Improve monitoring
|
|
1040
|
+
- Add tests to prevent recurrence
|
|
1041
|
+
|
|
1042
|
+
---
|
|
1043
|
+
|
|
1044
|
+
## 📚 Additional Resources
|
|
1045
|
+
|
|
1046
|
+
- [Migration Troubleshooting Guide](./MIGRATION_TROUBLESHOOTING.md) - Error resolution
|
|
1047
|
+
- [Migration Best Practices](./MIGRATION_BEST_PRACTICES.md) - Prevention strategies
|
|
1048
|
+
- [CI/CD Setup Guide](../ci-cd/CI_CD_SETUP.md) - Deployment workflow
|
|
1049
|
+
- [PostgreSQL Backup Documentation](https://www.postgresql.org/docs/current/backup.html) - Official backup guide
|
|
1050
|
+
|
|
1051
|
+
---
|
|
1052
|
+
|
|
1053
|
+
## ✅ Rollback Checklist
|
|
1054
|
+
|
|
1055
|
+
**Before Rollback:**
|
|
1056
|
+
- [ ] Identify migration to rollback
|
|
1057
|
+
- [ ] Understand what changes were made
|
|
1058
|
+
- [ ] Create backup of current state
|
|
1059
|
+
- [ ] Test rollback locally
|
|
1060
|
+
- [ ] Notify team of planned rollback
|
|
1061
|
+
- [ ] Document reason for rollback
|
|
1062
|
+
|
|
1063
|
+
**During Rollback:**
|
|
1064
|
+
- [ ] Execute rollback migration
|
|
1065
|
+
- [ ] Monitor for errors
|
|
1066
|
+
- [ ] Verify database state
|
|
1067
|
+
- [ ] Test application functionality
|
|
1068
|
+
- [ ] Check for data integrity issues
|
|
1069
|
+
|
|
1070
|
+
**After Rollback:**
|
|
1071
|
+
- [ ] Verify rollback success
|
|
1072
|
+
- [ ] Update other environments
|
|
1073
|
+
- [ ] Document the incident
|
|
1074
|
+
- [ ] Analyze root cause
|
|
1075
|
+
- [ ] Update tests/procedures
|
|
1076
|
+
- [ ] Communicate resolution
|
|
1077
|
+
|
|
1078
|
+
---
|
|
1079
|
+
|
|
1080
|
+
**Remember:** Rollbacks are a normal part of database management. Having clear procedures and practicing them regularly will make emergency situations much less stressful!
|