Files
document-haness/docs/clean-architecture-backend-template/tech-log-studio/schema-ownership-and-capability-streams/concept/concept-independent-flyway-streams.md
T
DongHyeonkaandClaude Fable 5.1 b25357c48a docs(clean-architecture-backend-template): fold analysis into final and re-select one topic
- analysis/·source-index·state.json 을 final/document.md 제2부·제3부로 접었다. SSOT 는 하나다
- 파일럿 — commit-ambiguity-as-a-result 를 새 기준으로 재선별. 후보 14 → 글감 5
  (PROMOTE 5 · MERGE_INTO 3 · KEEP_IN_SSOT 4 · 보류 2). 기록 5건을 다시 썼고 그림 1개를
  techviz 로 만들었다
- 재선별이 잡은 것: 제1부 §6.2·§11.1 이 자기 §13.2 와 어긋나 있었다(레인을 안 돌렸다 vs
  돌렸다) — 정정. 이미 답이 나와 있던 Question 을 HEAD 재실행 질문으로 다시 세웠다.
  Concept 이 인용한 코드가 SSOT 에 없어 뺐다
- candidateScope·sourceRepository 기록. 나머지 43개 주제는 재선별 대기(PENDING 905)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 12:39:20 +09:00

5.9 KiB

kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, evidenceCapturedOn, assets, evidence, source
kind slug title topic project status sourceRevision rootTreeNode evidenceCapturedOn assets evidence source
CONCEPT independent-flyway-streams 독립 Flyway 스트림과 baseline version 0 schema-ownership-and-capability-streams clean-architecture-backend-template 게시 전 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 concept:independent-flyway-streams 2026-09-01
key file
independent-flyway-streams ../../../final/evidence/rendered/independent-flyway-streams.svg
../../../final/evidence/raw/independent-flyway-streams.txt
원본 분석 절은 final/document.md#4-1 · final/document.md#a05 §8.3 이다.

독립 Flyway 스트림과 baseline version 0

능력마다 자기 마이그레이션 위치와 자기 히스토리 테이블을 갖는다. 그래야 각 능력의 버전 계열이 독립적이고, 켜지 않은 능력은 테이블도 히스토리도 남기지 않는다.

관계

  • 두 트리가 다 V1부터 번호를 매겨 공유 history가 하나를 건너뛸 수 있었다 이 구조가 필요해진 사례다.
  • 마이그레이션 스트림은 자기 history 테이블을 갖는다 이 개념을 규칙으로 옮긴 것이다.
  • capability_schema_registry — 스키마 적용과 사용 승인의 분리 스트림이 설치되었다는 사실을 기록하는 쪽이다.

본문

이 저장소에 Flyway 스트림이 여덟 개이고 각각 자기 history 테이블을 갖는 이유의 설명이다. 뻔한 해법(디렉터리를 primary location 목록에 추가)이 틀린 이유는 두 트리가 다 V1부터 번호를 매기고 공유 history가 두 V1을 같은 버전으로 만들어 하나를 거부하거나 resolution 순서에 따라 건너뛰기 때문이다.

뻔한 해법이 틀린 이유

:::evidence key="independent-flyway-streams" alt="분석 문서 final/document.md 에서 이 기록의 근거 절을 그대로 잘라낸 18줄. 코드베이스를 측정한 것이 아니라 원본 판정이 무엇을 적었는지를 보여 준다." caption="final/document.md 발췌 — 18줄" zoom="true" :::

baselineOnMigrate 가 필요한 이유

core가 이미 채운 스키마 위에 자기 history를 만들어야 하므로, 없으면 Flyway가 "history 없는 비어있지 않은 스키마"라며 거부한다.

baseline이 0이어야 하는 이유

더 높은 baseline은 그 스트림의 마이그레이션을 건너뛴다 — 이 설정이 보통 두려워하는 실패 모드다.

:::note

마이그레이션 레인 미실행

:::

왜 위치만 더하면 안 되는가

/**
 * The notification schema as its own Flyway stream, with its own history table.
 *
 * <p>The migrations live in {@code db/migration/jpa/notification-platform} while the primary Flyway
 * location is {@code db/migration/postgresql}, so nothing applied them. The obvious fix — adding
 * the directory to the primary location list — is the wrong one: both trees number from V1, and a
 * shared history table would make {@code V1__notification_platform_core} and {@code
 * V1__initial_schema} the same version. Flyway would either refuse the second or, worse, record one
 * and skip the other depending on resolution order.
 */

두 트리가 각자 V1 부터 번호를 매긴다. 히스토리를 공유하면 두 개의 V1 이 같은 버전이 된다.

Flyway 의 반응이 두 가지인 것이 문제다. 거절하면 발견되지만, 해석 순서에 따라 하나를 기록하고 다른 하나를 건너뛰면 발견되지 않는다.

별도 스트림이 만드는 것

/**
 * <p>A separate stream with {@code flyway_jpa_notification_history} keeps the two version series
 * independent, which is what makes the capability genuinely optional: a deployment that never
 * enables notifications has no notification history table and no notification tables, and a
 * deployment that enables it later applies a stream that starts at its own V1.
 */
public static final String LOCATION = "classpath:db/migration/jpa/notification-platform";
public static final String HISTORY_TABLE = "flyway_jpa_notification_history";

능력을 켜지 않은 배포에는 그 능력의 히스토리 테이블도 없다. 나중에 켜면 자기 V1 부터 적용한다.

선택 가능성이 스키마 수준에서 성립한다

능력이 선택적이라는 말이 코드 수준에서만 참이면, 스키마에는 쓰지 않는 테이블이 남는다. 스트림이 독립적이면 그 테이블도 생기지 않는다.

:::tip

이 구조에서 "이 능력을 쓰지 않는다"는 것과 "이 능력의 스키마가 없다"는 것이 같은 사실이 된다. 두 사실이 갈라지면 나중에 어느 쪽이 진실인지 알 수 없다.

:::

버전 공간을 공유하는 경우

같은 Flyway 위치 목록에 병합되는 트리들은 하나의 버전 공간을 공유한다. 샘플 컴포지션이 두 위치를 병합하므로, 한쪽이 이미 쓴 번호를 다른 쪽이 쓸 수 없다.

-- Numbered V9, not V8 or V7. `db/migration/postgresql` and `db/sample-migration` are merged into
-- one Flyway location list by the sample composition root, so the two trees share a single version
-- space: the sample already owns V2, V7 and V8. A duplicate version is not a merge conflict Flyway
-- resolves — it refuses to start at all.

번호를 고를 때 다른 트리를 봐야 한다는 뜻이고, 그 사실이 마이그레이션 헤더에 적혀 있다.

두 위치가 같은 테이블을 만들 때

-- Both locations create capability_schema_registry, so both have to grow the column. A deployment
-- that migrated through only one of them would otherwise still reject a stream path over 32
-- characters, and the error would name the column rather than the reason.

한쪽만 고치면 그 경로로만 마이그레이션한 배포가 옛 제약을 유지한다. 그리고 그때의 오류 메시지는 컬럼 이름을 부르지 이유를 말하지 않는다.