피처 플래그 통합 구현 계획 (TPM)
작성일: 2026-07-04 · 베이스 워크트리: /Users/biuea/sports-app-feature-flag (feat/feature-flag, origin/dev=V40 기준) · senior-pm PASS 후 구현 단계.
통합 DAG (도메인 간)
flowchart LR
subgraph Infra["인프라 wave (선행)"]
DB01["DB-01 V41 2테이블"]
REDIS01["REDIS-01 키·채널 계약"]
end
subgraph BE["BE wave 1~5"]
BE01["BE-01 도메인 코어"]
BErest["BE-02~12"]
end
subgraph FE["FE wave 1~4"]
FE01["FE-01 zod 스키마"]
FErest["FE-02~11"]
end
DB01 --> GateInfra{"infra-reviewer 게이트"}
REDIS01 --> GateInfra
GateInfra --> BE01
BE01 --> BErest
TDD["TDD API 계약 (확정)"] --> FE01
FE01 --> FErest
BErest -.->|런타임 아님·계약뿐| FErest
인프라 → BE 는 경성 게이트(infra-reviewer APPROVED/COMMENT 후 BE-01 착수).
FE 는 BE 런타임에 의존하지 않고 TDD API 계약만으로 착수 — 인프라·BE와 병렬. 유일한 BE↔FE 계약(감사 로그 페이징 응답)은 아래 계약 정합에서 고정.
도메인 간 게이트
게이트 조건 개방 대상 G0 인프라 DB-01(V41)+REDIS-01 산출 → private-infra-reviewer APPROVED/COMMENT BE wave 1 G-BE(각 wave) 변경 티켓 테스트 exit 0 + private-code-reviewer APPROVED/COMMENT 다음 BE wave G-FE(각 wave) 변경 티켓 테스트+tsc+lint exit 0 + private-code-reviewer APPROVED/COMMENT 다음 FE wave
BE wave 계획 (너비 1→3→3→4→1)
wave 티켓 선행 파일 교집합 1 BE-01 없음(+G0) 단독 2 BE-02, BE-03, BE-04 BE-01 mysql/ · redis/ · domainservice — ∅ 3 BE-05, BE-06, BE-07 BE-04 / BE-01·02·03 / BE-04 application/ · infra eval / presentation listener — ∅ 4 BE-08, BE-09, BE-11, BE-12 BE-05 / BE-06 / BE-02·04 / BE-03·06 controller · featuredemo slice · scheduler · metrics binder — ∅ 5 BE-10 BE-08·09·12 SecurityConfig.kt 단독(Single Writer 통합 티켓)
FE wave 계획 (너비 2→4→4→1)
wave 티켓 선행 파일 교집합 1 FE-01, FE-02 없음 schemas.ts · globals.css/tailwind — ∅ 2 FE-03, FE-04, FE-05, FE-06 FE-01 / FE-01 / FE-01·02 / FE-01·02 api routes · lib api/hooks · _components 배지 · _components StrategyForm — ∅ 3 FE-07, FE-08, FE-09, FE-10 FE-04·05 / FE-04·06 / FE-04·05·06 / FE-04·05 page.tsx · new/ · [key]/page · [key]/audit-logs — ∅ 4 FE-11 FE-07~10 AdminSidebar.tsx 단독
계약 정합 (BE↔FE)
계약 BE FE 결과 감사 로그 페이징 BE-05/08 ListFeatureFlagAuditLogsResponse{content,totalElements,totalPages,pageNumber,pageSize} FE-01 wire 스키마 파싱 → FE-04 toAuditLogPageView 1곳에서 canonical {logs,total,page,size,totalPages} 정규화 정합 — wire 필드명 = pageNumber/pageSize 로 고정 지시 목록 List<FeatureFlagResponse> 배열 직반환FE-04 배열 흡수 정규화 정합 strategy 판별 GLOBAL_TOGGLE/PERCENTAGE_ROLLOUT/ATTRIBUTE_MATCH/VARIANT_BUCKETING FE-01 discriminatedUnion 1:1 정합 관리 API 경로 /admin/feature-flags + archive/activate/audit-logsFE-03 BFF 7종 프록시 정합 데모 게이팅 GET /feature-demo/hello X-User-IdFE 소비 없음(운영자 화면만) 계약 없음
구현 규율 (전 implementer 공통)
TDD 강제(RED→GREEN→REFACTOR), BE=Kotest(JUnit 금지) 전 레이어, 실 DB Mock-only 금지.
private-be-code-convention 금지 패턴 전수(@Query/@Lob/LocalDateTime·Clock/시간인자/!!/Optional/ConsumerRecord<String,String>/Repo in UseCase/infra import in domain·application/Anemic Entity/생성자 기본값). 시간 ZonedDateTime, 캡슐화 메서드 내부 now().
FE=private-fe-convention(no-any·no-direct-fetch·no-hardcoded-color·라이트+다크 둘 다·훅 경유). 레포 정착 스택(Next.js App Router+BFF, TanStack Query 미사용).
테스트명에 티켓ID 금지. Testcontainers reuse 끔. qa-/doodlin- 컨테이너 삭제 금지.
wave 종료 게이트: 변경 티켓 테스트 exit 0(raw 근거) + code-reviewer APPROVED/COMMENT. REQUEST_CHANGES면 수정 후 재리뷰 통과 전 wave 안 닫음.
워크트리 규율
모든 티켓은 feat/feature-flag 로 수렴. 통합 브랜치(pipeline-base) 만들지 않음. 최종 PR 1개(dev)는 사용자 Step 4.
병렬 implementer는 feat/feature-flag 최신 HEAD에서 뜬 전용 worktree(구버전 로컬 HEAD 금지) → 게이트 통과 후 feat/feature-flag 로 머지.