피처 플래그 통합 구현 계획 (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/COMMENTBE 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티켓선행파일 교집합
1BE-01없음(+G0)단독
2BE-02, BE-03, BE-04BE-01mysql/ · redis/ · domainservice — ∅
3BE-05, BE-06, BE-07BE-04 / BE-01·02·03 / BE-04application/ · infra eval / presentation listener — ∅
4BE-08, BE-09, BE-11, BE-12BE-05 / BE-06 / BE-02·04 / BE-03·06controller · featuredemo slice · scheduler · metrics binder — ∅
5BE-10BE-08·09·12SecurityConfig.kt 단독(Single Writer 통합 티켓)

FE wave 계획 (너비 2→4→4→1)

wave티켓선행파일 교집합
1FE-01, FE-02없음schemas.ts · globals.css/tailwind — ∅
2FE-03, FE-04, FE-05, FE-06FE-01 / FE-01 / FE-01·02 / FE-01·02api routes · lib api/hooks · _components 배지 · _components StrategyForm — ∅
3FE-07, FE-08, FE-09, FE-10FE-04·05 / FE-04·06 / FE-04·05·06 / FE-04·05page.tsx · new/ · [key]/page · [key]/audit-logs — ∅
4FE-11FE-07~10AdminSidebar.tsx 단독

계약 정합 (BE↔FE)

계약BEFE결과
감사 로그 페이징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_BUCKETINGFE-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 로 머지.