Skip to content

chore: Flyway 도입 — DB 스키마 버전 관리 체계 구축#87

Open
hodoon wants to merge 4 commits into
devfrom
infra/ALT-222
Open

chore: Flyway 도입 — DB 스키마 버전 관리 체계 구축#87
hodoon wants to merge 4 commits into
devfrom
infra/ALT-222

Conversation

@hodoon
Copy link
Copy Markdown
Contributor

@hodoon hodoon commented May 23, 2026

관련 문서

https://www.notion.so/BE-DB-36086553162880308932e28abb3179af?v=3288655316288071b53d000c67f996d3&source=copy_link

Summary by CodeRabbit

릴리스 노트

  • Documentation

    • Flyway 데이터베이스 마이그레이션 운영 가이드 문서가 추가되었습니다.
  • Chores

    • 데이터베이스 마이그레이션 도구가 추가되었습니다.
    • 초기 데이터베이스 스키마 및 마이그레이션 스크립트가 구성되었습니다.
    • 관련 설정이 적용되었습니다.

Review Change Stack

@hodoon hodoon requested review from juny0955 and ysw789 May 23, 2026 09:20
@hodoon hodoon self-assigned this May 23, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

Warning

Review limit reached

@hodoon, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 8 minutes and 37 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 717673c3-0970-49b8-aa58-cd14f3c97b08

📥 Commits

Reviewing files that changed from the base of the PR and between 018af30 and f08fa33.

📒 Files selected for processing (4)
  • .github/workflows/cicd.yml
  • FLYWAY_MIGRATION.md
  • src/main/resources/db/migration/V1__init_schema.sql
  • src/main/resources/db/migration/V3__set_workspace_request_id_not_null.sql
📝 Walkthrough

워크스루

PR은 Flyway 데이터베이스 마이그레이션 프레임워크를 도입하여 PostgreSQL 스키마를 초기화하고 버전 관리하며, 마이그레이션 설정, 초기 스키마 정의(2900+ 줄), V2 스키마 확장 마이그레이션, 운영 가이드를 추가합니다.

변경 사항

Flyway 프레임워크 도입

계층 / 파일 요약
Flyway 의존성 및 설정
build.gradle, src/main/resources/application.yml, src/test/resources/application.yml
Flyway 핵심 라이브러리(flyway-core)와 PostgreSQL 드라이버(flyway-database-postgresql)를 의존성에 추가하고, 프로덕션 환경에서는 마이그레이션을 활성화(environment 변수 기반), 테스트 환경에서는 비활성화하도록 spring.flyway 설정을 구성합니다.
PostgreSQL 초기 스키마 정의
src/main/resources/db/migration/V1__init_schema.sql
공개 스키마의 사용자, 워크스페이스, 워크스페이스 워커, 포스팅, 채팅방, 채팅 메시지, 공지사항, 평판, 대체근무 요청, 약관 및 동의 등 16개 핵심 도메인 테이블을 생성하고, 각 테이블의 시퀀스 기반 기본값, PRIMARY KEY/UNIQUE 제약조건, 조건부 인덱스를 포함한 다수 인덱스, 그리고 ON DELETE CASCADE가 적용된 외래키 관계를 정의합니다.
스키마 마이그레이션 V2
src/main/resources/db/migration/V2__add_user_id_and_comment_owner_to_workspace_reason_comments.sql
workspace_reasons 테이블에 workspace_request_id 외래키를 추가하고, workspace_reason_comments 테이블에 user_idcomment_owner 컬럼을 추가하여 기존 NULL 값을 'USER'로 채운 후 NOT NULL 제약조건을 적용하며, user_id에 대한 외래키 제약조건을 추가합니다.
운영 가이드 및 빌드 설정
FLYWAY_MIGRATION.md, .gitignore
Flyway 초기 설정(기존/신규 환경 구분), 마이그레이션 스크립트 작성 규칙(네이밍, 불변성, 위치), 환경 변수(FLYWAY_ENABLED, FLYWAY_BASELINE_ON_MIGRATE 등) 설명을 문서화하고, 생성된 Spring 메타데이터 JSON 파일을 .gitignore에 추가합니다.

코드 리뷰 예상 시간

🎯 3 (중간) | ⏱️ ~20 분

제안 레이블

CHORE

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 Flyway 도입과 DB 스키마 버전 관리 체계 구축이라는 주요 변경사항을 명확하게 요약하고 있으며, 변경사항 전체와 직접적으로 연관되어 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch infra/ALT-222

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@FLYWAY_MIGRATION.md`:
- Line 5: Markdown headers in FLYWAY_MIGRATION.md are triggering markdownlint
MD022 because there are no blank lines before/after the headers (notably the
"### Existing DB (production / development server)" header and the headers at
the other flagged spots). Fix by adding a single blank line above and below each
header (lines referenced in the comment: the header at "### Existing DB
(production / development server)" and the other headers flagged at the same
file) so each header is separated from surrounding content; follow the MD022
convention consistently throughout the file.

In `@src/main/resources/db/migration/V1__init_schema.sql`:
- Line 11: The migration contains a PostgreSQL‑17‑only directive "SET
transaction_timeout = 0;" in V1__init_schema.sql which will fail on PG <17;
remove that hard failure by either deleting that SET line or wrapping it with a
runtime guard that checks for the parameter's existence (e.g., via
current_setting(..., true)) and only applies the SET when present; update the
migration file V1__init_schema.sql (the SET transaction_timeout statement)
accordingly and consider adding/ documenting a Postgres version pin
(POSTGRES_VERSION or image tag) in CI/deployment configs to avoid environment
drift.

In
`@src/main/resources/db/migration/V2__add_user_id_and_comment_owner_to_workspace_reason_comments.sql`:
- Around line 8-13: The migration currently adds
workspace_reasons.workspace_request_id and a FK (fk_workspace_reasons_request)
but leaves the column nullable, which conflicts with the WorkspaceReason
entity's `@JoinColumn`(name = "workspace_request_id", nullable = false); update
the migration to (1) backfill workspace_request_id for existing rows (using a
safe SELECT/UPDATE strategy appropriate to your schema), (2) then ALTER TABLE
workspace_reasons ALTER COLUMN workspace_request_id SET NOT NULL, and (3) ensure
the FK constraint fk_workspace_reasons_request remains valid after backfill;
reference the workspace_reasons table, workspace_request_id column, and
fk_workspace_reasons_request when making changes.

In `@src/test/resources/application.yml`:
- Around line 20-25: The global test config disables Flyway via the line
"enabled: false", which will hide SQL migration regressions; add a CI-specific
path that runs Flyway migrations against a real Postgres (e.g., create a CI
profile or application-ci.yml that sets spring.flyway.enabled: true and points
to a Testcontainers Postgres using the same "locations:
classpath:db/migration"), and add a migration smoke test job that boots the app
(or directly invokes Flyway.migrate() in a test) against that Testcontainers
instance to fail CI on broken SQL; keep the default test profile unchanged and
scope the change to the CI/profile that runs in your pipeline.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 68e97bce-e37e-420e-b759-67ac0bc54530

📥 Commits

Reviewing files that changed from the base of the PR and between 6a81d82 and 018af30.

📒 Files selected for processing (8)
  • .gitignore
  • FLYWAY_MIGRATION.md
  • build.gradle
  • src/main/resources/application.yml
  • src/main/resources/db/migration/V1__add_substitute_reputation_consent_columns.sql
  • src/main/resources/db/migration/V1__init_schema.sql
  • src/main/resources/db/migration/V2__add_user_id_and_comment_owner_to_workspace_reason_comments.sql
  • src/test/resources/application.yml
💤 Files with no reviewable changes (1)
  • src/main/resources/db/migration/V1__add_substitute_reputation_consent_columns.sql

Comment thread FLYWAY_MIGRATION.md
Comment thread src/main/resources/db/migration/V1__init_schema.sql Outdated
Comment thread src/test/resources/application.yml
@@ -0,0 +1,2893 @@
--
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

삭제 권장.

현재 운영 모델(baseline-on-migrate=true)에서 이 파일은 prod에서는 baseline 마킹만 되고 실제 실행되지 않습니다. 유일한 실제 용도는 fresh DB(로컬/CI/신규 환경) 부트스트랩인데:

  • CI는 H2 사용 → 이 스크립트 무관
  • 로컬/신규 환경은 기존 환경 DB 스냅샷 복원으로 처리하는 것이 prod와의 sync 보장 측면에서 더 안전

또한 pg_dump 산물이라 SET search_path = '' 같은 세션 파라미터가 포함되어 있어 후속 V2/V3 실행 시 잠재적 영향 가능성이 있습니다.

db/migration/ 으로 시작하고 baseline만 마킹하는 모델이 가장 깔끔합니다.

@@ -0,0 +1,35 @@
-- V2: 엔티티에 추가됐지만 DB에 미반영된 컬럼 일괄 추가
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

삭제 + 콘솔 수동 적용으로 전환 권장.

결정된 운영 모델에 따라 V2/V3는 Flyway 도입 에 각 환경 콘솔에서 수동 적용 후 PR에서는 삭제합니다.

단, SQL 자체는 audit trail을 위해 docs/db/pre-flyway-manual-sql/ 또는 Notion 문서에 보존해 주세요. 6개월 뒤 "이 컬럼 언제 추가됐지?" 추적용.

@@ -0,0 +1,5 @@
-- V3: workspace_reasons.workspace_request_id NOT NULL 제약 추가
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

삭제 + 콘솔 수동 적용으로 전환 권장. 적용 시 백필 누락 주의.

현재 스크립트는 V2에서 nullable로 추가된 workspace_request_id 를 곧바로 NOT NULL 로 변경합니다. 기존 workspace_reasons 행이 1건이라도 있으면 실패합니다.

수동 적용 시 순서:

  1. ALTER TABLE workspace_reasons ADD COLUMN workspace_request_id BIGINT;
  2. 기존 행에 대해 적절한 workspace_request_id 값 백필 (도메인 로직 확인 필요)
  3. ALTER TABLE workspace_reasons ALTER COLUMN workspace_request_id SET NOT NULL;
  4. FK 제약 추가

백필 매핑 로직이 명확하지 않다면 적용 전에 도메인 담당자와 확인 필요.

host: ${REDIS_HOST}
port: ${REDIS_PORT}
flyway:
enabled: ${FLYWAY_ENABLED}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

env 디폴트값 박기 + ddl-auto 고정 권장.

flyway:
  enabled: ${FLYWAY_ENABLED:true}
  locations: classpath:db/migration
  baseline-on-migrate: ${FLYWAY_BASELINE_ON_MIGRATE:false}
  baseline-version: ${FLYWAY_BASELINE_VERSION:1}
  out-of-order: false
  validate-on-migrate: true
jpa:
  hibernate:
    ddl-auto: validate   # env 제거하고 고정

현재처럼 ${FLYWAY_ENABLED} 만 쓰면 env 누락 시 앱 부팅 실패. CICD secrets 미설정 시에도 동일. 디폴트가 박혀있으면 FLYWAY_MIGRATION.md 의 "Default in application.yml" 안내와도 일치.

ddl-auto 도 Flyway 도입 동기상 validate 로 박아두는 게 안전. env로 update/create 가 흘러들어올 여지 제거. 최소한 prod profile 에서는 강제 + Flyway 활성화 직전 일회성 검증 부팅으로 사용.

Comment thread FLYWAY_MIGRATION.md
@@ -0,0 +1,42 @@
# Flyway Migration Guide
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문서는 유지하되 슬림화.

사용 가이드로서 in-repo 보존은 유지. 다만 결정된 cutover 모델 기준으로 핵심 3가지만 남기는 것을 권장합니다:

  1. 파일 네이밍 규칙V{n}__{description}.sql, 정수 vs 타임스탬프 중 하나로 통일 권장 (현재 문서는 둘 다 예시로 보여줘서 혼선)
  2. 적용 정책 — "모든 스키마 변경은 Flyway 마이그레이션을 통해서만 (수동 ALTER 금지), 이미 머지된 스크립트는 절대 수정 금지"
  3. 세팅 구조application.ymlspring.flyway.* 키 설명과 환경변수 매핑

제거할 내용:

  • "Existing DB / Fresh DB" 분기 셋업 절차 → cutover는 이미 끝난 시점이므로 향후 운영 가이드에 불필요
  • FLYWAY_BASELINE_ON_MIGRATE 토글 안내 → 1회성이라 코드에 디폴트로 박히면 굳이 문서화 불필요

오타도 함께 수정 부탁드립니다: Default in applica일tion.ymlDefault in application.yml (Korean 끼어듦)

Comment thread .gitignore
.agents/*
AGENTS.md

src/main/resources/META-INF/additional-spring-configuration-metadata.json No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

본 작업과 무관하므로 제거 권장.

additional-spring-configuration-metadata.json 은 IntelliJ가 커스텀 @ConfigurationProperties 자동완성을 위해 생성하는 IDE 산물입니다. Flyway 도입과 직접 관련이 없습니다.

IDE 산물 ignore 정책이 필요하다면 별도 PR로 분리해서 처리하는 것이 PR scope 응집성 측면에서 좋습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants