상품·주문 공유 상위 컨텍스트 PRD
Background
20260708-전체시스템-architecture.md(아키텍처 진단, 진단 커밋 808d2101)의 1단계(지금) 권고를 제품 요구사항으로 정리한다. 진단 문서는 병목 B4로 “상품/주문 공유 추상 부재 — 신규 상품 유형 추가 시 goods/ticketing/facility/payment 4곳 수정”을 지목했고, §4-1 도메인 경계 정합 매트릭스는 “상품(Product) 상위 개념”·“주문(Order) 상위 개념”이 코드에 앵커 없이 각 도메인에 분산돼 있음을 실측했다(§4-1 “누락” 판정 2건).
같은 문제를 다룬 선행 문서 20260706-사용자정의-도메인경계-갭분석-architecture.md §4 “문제 A/B”는 반대로 통합 aggregate 신설을 “미채택” 판정했다 — 중고(단건 C2C)·브랜드(SKU 재고)·티켓(좌석재고+공연)·한정판(시간게이트)·시설상품(슬롯)의 라이프사이클 이질성이 한 aggregate에 밀어넣으면 God-aggregate·다형 필드 폭증을 유발한다는 이유다. 대신 “조건부 채택 — 교차 타입 검색·통합 주문 이력 화면이 실제 스펙에 잡힐 때”만 읽기 전용 조회 파사드를 권고했다(A-3/B-3, catalog·order-query).
두 문서의 상충은 이 PRD에서 다음과 같이 해소한다: 상위 컨텍스트를 쓰기 aggregate 통합이 아닌 읽기 전용 통합 조회 파사드로 도입한다. 각 도메인(goods·ticketing·facility·recruitment)의 쓰기 테이블·로직·API는 그대로 두고, catalog(상품 조회)·order(주문 조회) 상위 컨텍스트는 이들을 조합해 보여주는 계층만 신설한다. 이는 20260706의 God-aggregate 우려를 원천 회피하면서, 20260708이 “지금” 필요하다고 판단한 이유(신규 상품 유형 추가 시 4곳 수정)를 “조회 진입점 1곳 추가”로 완화한다. 또한 사용자 확인 결과 이번 과제로 최종 사용자가 체감하는 통합 검색·통합 주문내역 화면이 나오므로, 20260706이 조건부 채택의 전제로 걸었던 “실제 스펙 요구”가 이 과제로 충족된다.
AS-IS 정정 고지 (필수 — 진단 문서의 grep 결과가 이 PRD 작성 시점 기준 stale)
20260706 문서 §AS-IS “결정적 실측 1”은 grep -rni "recruit|모집|applicant" 결과 0건으로 모집(recruitment) 도메인 완전 부재를 실측했고, §4 A-4는 시설상품(facility program) 완전 부재를 실측했다. 이 결과는 2026-07-06 진단 시점 기준으로는 사실이었으나, 이후 커밋 5089cb65f/4f786c073/d1e6791c5(BE-51·BE-52)와 Program.kt(BE-59)로 두 도메인 모두 이미 완전 구현됐다 — 두 진단 문서가 공통 근거로 삼은 진단 커밋 808d2101(본 PRD 작성 시점의 HEAD와 동일, git rev-parse HEAD = 808d2101f3fdc034684e1fe71d78c1b808bd065d)에 이미 포함돼 있다. 실측 근거:
domain/recruitment/entity/Recruitment.kt(모집 공고, capacity·feeAmount·activityAt·applicationDeadline),domain/recruitment/entity/Application.kt(신청, recruitmentId·applicantUserId·paymentId),domain/recruitment/policy/TieredCancellationPolicy.kt(마감 잔여일 기준 0%/5%/10% 취소 수수료 — 20260706 §4 “문제 D 취소정책 하드코딩”이 미채택으로 유보했던 정책 객체가 이미 구현됨),presentation/recruitment/worker/RecruitmentPaymentEventWorker.kt(OrderType.RECRUITMENT구독, 결제 배선 완료)domain/facility/entity/Program.kt(“BE-59, TDD Detail Design ‘Program’” 주석 — facility 산하 PT·클래스 상품, 예약은 bookingSlot의programId참조 재사용),domain/facility/service/ProgramDomainService.kt,domain/facility/repository/ProgramRepository.kt
이 PRD는 정정된 AS-IS를 기준으로 작성한다 — recruitment·facility program을 “미존재 → enum 자리만 예약”이 아니라 이미 존재하는 실제 판매/주문 대상으로 catalog·order 읽기 파사드에 포함한다. 두 아키텍처 문서의 해당 판정 갱신은 Open Questions에 남긴다.
Problem Definition
- 상품(판매 대상) 공유 상위 추상 부재: 판매 대상이 5곳에 분산돼 있다 —
goods/entity/Product.kt(중고/브랜드),goods/entity/LimitedDrop.kt(한정판,productId참조),ticketing/entity/Event.kt(티켓),facility/entity/Program.kt(시설상품),recruitment/entity/Recruitment.kt(모집 공고). 이를 아우르는 조회 지점이 없어 “요가 매트도 사고 싶고 요가 클래스도 찾고 싶은” 사용자가 5개 화면을 따로 검색해야 한다. - 주문(구매/신청 행위) 공유 상위 추상 부재: 주문 개념이 4곳에 분산돼 있다 —
booking/entity/Booking.kt,goods/entity/GoodsOrder.kt,ticketing/entity/TicketOrder.kt,recruitment/entity/Application.kt. 유일한 통합 지점은payment/vo/OrderType.kt(enum: BOOKING/TICKETING/GOODS/RECRUITMENT) + 각 컨텍스트의*PaymentEventWorker.kt(예:GoodsPaymentEventWorker.kt#consume)뿐이라 결제 확정에만 쓰이고, 사용자가 자신의 전체 구매/신청 이력을 한 화면에서 볼 방법이 없다. - 판매자 유형(b2c/b2b) 판별 부재:
Product.kt:20-42는category(ProductCategory— EQUIPMENT/APPAREL/FOOTWEAR/ACCESSORY, 물리 카테고리)와ownerId만 보유한다. 중고(개인 b2c 등록)와 브랜드(파트너 b2b 등록)를 구분하는 필드가 없어, 통합 검색에서 “브랜드 상품만 보기” 같은 필터를 제공할 수 없고 수수료·정산 정책도 상품 단위로 분기할 수 없다. ADR-007(B2B 등록 경유 = 인증 계층 pass-through) 결정에 따라 b2c 일반 등록과 b2b 파트너 등록은 별도 엔드포인트·UseCase가 아니라 동일한GoodsSellerApiController(POST /api/goods-seller/products) →CreateMyProductUseCase.execute를 통과한다 —PartnerApiKeyAuthenticationFilter#injectSecurityContext가 API Key 검증 후 파트너 연동 User(roles: GOODS_SELLER)를 SecurityContext에 주입할 뿐이고,CreateMyProductUseCase는ownershipGuard.authUserId()만 조회하므로 이 값만으로는 요청이 파트너 경로를 거쳤는지 구분할 신호가 현재 없다.
Goals / Non-Goals
Goals
- catalog 읽기 전용 통합 조회 컨텍스트를 신설한다.
goods.Product(+LimitedDrop)·ticketing.Event·facility.Program·recruitment.Recruitment5개 도메인의 판매 대상을 단일 검색 API로 조회한다. 각 도메인의 쓰기 테이블·로직·기존 조회 API는 변경하지 않는다. - order 읽기 전용 통합 조회 컨텍스트를 신설한다.
booking.Booking·goods.GoodsOrder·ticketing.TicketOrder·recruitment.Application4개 도메인의 주문/신청 이력을 로그인 사용자 기준 단일 API로 조회한다. payment/vo/OrderType.kt의 소유권(패키지 위치)을 order 상위 컨텍스트로 이관한다. 값 구성·동작(Kafka 이벤트 발행/구독, 각 컨텍스트별orderType필터링)은 변경하지 않는다.Product에 sellerType(B2C/B2B) 판별 필드를 추가한다. 판별 기준은 B2B 파트너 API Key 인증 경유 여부이며(등록 경로 자체는 b2c·b2b가 동일한CreateMyProductUseCase를 공유하므로, 판별 신호는 인증 컨텍스트다), 사용자가 값을 직접 선택하지 않는다.- FE가 소비할 통합 검색 API·통합 주문내역 API 계약을 정의한다. 최종 사용자가 체감하는 통합 검색 화면·통합 주문내역 화면 출시까지가 이 로드맵의 목표이며, 화면 구현 자체는 후속 design-fe 트랙에서 진행한다.
- sellerType 자동 판별 도입으로
CreateMyProductCommand시그니처가 바뀌므로,도메인 경계 재설계/ADR-003(제공 UseCase 시그니처 동결)의 갱신 필요성을 이 과제 범위에서 명시한다.
Non-Goals
- 통합 쓰기 aggregate(단일 SellableItem/Order 테이블) 신설 — 20260706 §4 “문제 A/B”의 God-aggregate 우려를 그대로 수용해 미채택. catalog/order는 읽기 조합 계층일 뿐, 각 도메인이 자기 데이터의 쓰기 소유권을 그대로 유지한다.
- ticketing·facility·recruitment 패키지를 goods 하위로 재배치(패키지 이동) — 독립 최상위 도메인 위치를 유지한다.
도메인 경계 재설계 PRD의 Non-Goals(“코드 재배치 실행 제외”)와 정합. - MSA 물리 분리 — 모놀리스 구조를 유지한다.
- sellerType을 사용자가 직접 선택하는 UI/파라미터 제공 — 등록 경로로만 자동 판별한다. 값을 사용자 입력으로 받지 않는다.
- 기존 도메인별 개별 조회 API 제거·변경 —
GET /products,GET /events등 기존 엔드포인트는 하위 호환을 유지한다. 통합 조회는 추가 API다. - 검색 랭킹/추천 알고리즘 고도화 — 키워드 매칭 + 기본 정렬(최신순)만 제공한다. 개인화·랭킹 튜닝은 범위 밖이다.
- FE 화면의 디자인·컴포넌트 구현 — 이 PRD는 API 계약까지 정의한다. 실제 화면(레이아웃·인터랙션)은
design-fe-web/design-fe-appTDD에서 별도 설계·구현한다(= 이 PRD 문서 산출물 범위 밖(별도 design-fe-app.md 트랙에서 수행). 로드맵 목표에는 FE 화면 출시 포함 — 통합 검색·통합 주문내역 화면 2종은 Success Metrics·Milestone M4에 명시된 목표다). - recruitment.TieredCancellationPolicy·facility.Program의 신규 기능 개발 — 두 도메인은 이미 완전 구현돼 있으므로(AS-IS 정정 고지 참조) 이 과제는 기존 구현을 catalog/order 읽기 파사드에 편입하는 것이며, 두 도메인 자체의 신규 기능 추가는 범위 밖이다.
- sellerType 소급 재판별 — 향후 어떤 판매자가 b2c에서 b2b로 전환되더라도, 이미 등록된 과거 상품의 sellerType을 소급 변경하지 않는다(등록 시점 값 고정). 이 판단은 Open Questions에도 재확인용으로 남긴다.
User Scenarios
페르소나: ① 일반 사용자(구매자/신청자) ② 중고 판매자(b2c, 일반 등록 경로) ③ B2B 파트너(브랜드 판매자, API Key 경유 등록) ④ FE 개발자(통합 조회 API 소비자).
- 해피 패스 — 통합 검색: 사용자가 검색창에 “요가”를 입력하면, 중고 요가매트(
Product, sellerType=B2C)·브랜드 요가매트(Product, sellerType=B2B)·요가 클래스(Program)·요가 모임 모집(Recruitment)이 한 목록에 최신순으로 섞여 나온다. 각 항목을 누르면 원본 도메인의 상세 화면으로 이동한다. - 해피 패스 — 통합 주문내역: 로그인한 사용자가 “내 주문” 화면에서 지난달 결제한 시설 예약(
Booking)·중고 구매(GoodsOrder)·티켓 예매(TicketOrder)·모임 신청(Application)을 한 목록에서 최신순으로 확인한다. 각 항목에 결제 상태(paymentId연계)가 표시된다. - 해피 패스 — b2c 등록: 중고 판매자가 일반 JWT 인증으로
GoodsSellerApiController(CreateMyProductUseCase)를 호출해 상품을 등록하면, 파트너 API Key 인증 컨텍스트가 없으므로 sellerType이 자동으로 B2C로 저장된다. 판매자는 별도 선택을 하지 않는다. - 해피 패스 — b2b 등록: B2B 파트너가 API Key로 인증한 요청이
PartnerApiKeyAuthenticationFilter를 거쳐 동일한GoodsSellerApiController(CreateMyProductUseCase)를 호출하면, 파트너 인증 컨텍스트가 있으므로 sellerType이 자동으로 B2B로 저장되고, 통합 검색에서 “브랜드만 보기” 필터로 구분 노출된다. - 예외 — 검색 결과 없음: 검색어와 일치하는 항목이 5개 도메인 어디에도 없으면 빈 상태(empty state) 응답을 반환한다.
- 예외 — 원본 도메인 부분 실패: 통합 검색·통합 주문 조회 도중 특정 원본 도메인(예: ticketing) 조회가 타임아웃되면, 나머지 4개 도메인 결과는 정상 반환하고 응답 메타데이터에 실패한 도메인을 표기한다. 전체 요청을 실패시키지 않는다.
- 예외 — 미인증 사용자의 주문 조회: 로그인하지 않은 사용자가 통합 주문내역 API를 호출하면 인증 실패(401)를 반환한다.
- 경계값 — 백필 중 신규 등록 경합: sellerType 백필 마이그레이션이 실행되는 동안 신규 Product가 등록되면, 신규 등록 경로가 즉시 정확한 sellerType을 저장하고 백필 대상에서 제외한다(이미 값이 있는 행은 skip).
- 상태 보호 — 등록 경로 판별의 고정성: b2c로 등록된 상품은 이후 판매자가 B2B 파트너로 전환되더라도 sellerType이 소급 변경되지 않는다(Non-Goals 참조).
Benchmarking
| 제품명 | 카테고리 | 참조 패턴 | URL |
|---|---|---|---|
| 당근마켓 검색 플랫폼 | C2C 중고거래 + B2C 비즈프로필 통합 | 중고 게시글(C2C)과 비즈프로필 매물(B2C 사업자)이 하나의 Elasticsearch 기반 검색 인덱스·홈피드에서 함께 서빙된다(초당 평균 1K 검색, 2.7억+ 문서). 원본 도메인 데이터는 각자 소유하고 검색 인덱스만 통합 — 이 PRD의 “읽기 전용 파사드” 방향과 동일 | 당근마켓 검색 엔진, 쿠버네티스로 쉽게 운영하기 |
| Amazon Marketplace (1P/3P) | 종합 커머스, 자체 판매(1P) + 외부 셀러(3P) | 1P(Amazon 자체 벤더)와 3P(외부 셀러) 상품이 동일 상품 상세페이지·검색 결과에 노출되되, 판매자 유형은 리스팅 메타데이터로만 구분되고 재고·주문 처리 로직은 셀러 유형별로 분리 운영된다. 이 PRD의 sellerType 판별자(등록 경로 기반, 조회에만 노출) 설계와 동일한 패턴 | Amazon 1P vs 3P: Key Differences for Sellers |
Functional Requirements
| ID | 요구사항 | 우선순위 |
|---|---|---|
| FR-1 | catalog 통합 검색 API를 신설한다. goods.Product(활성 상태)·goods.LimitedDrop(판매 중/예정 회차)·ticketing.Event(공개 상태)·facility.Program(활성)·recruitment.Recruitment(모집 중) 5개 도메인 데이터를 단일 응답으로 조회한다. 각 항목은 itemType 판별자(PRODUCT/LIMITED_DROP/TICKET/PROGRAM/RECRUITMENT), 원본 도메인 ID, 제목/이름, 가격 또는 참가비, 원본 상세 조회 경로를 포함한다 | P0 |
| FR-2 | catalog 통합 검색은 키워드(제목/이름) 검색을 지원한다 | P0 |
| FR-3 | catalog 통합 검색의 PRODUCT 항목은 sellerType(B2C/B2B)을 함께 노출한다 | P0 |
| FR-4 | catalog 통합 검색은 itemType 필터, sellerType 필터(옵션 파라미터)를 지원한다 — “브랜드 상품만”, “모집만” 등 조합 조회 | P1 |
| FR-5 | order 통합 조회 API를 신설한다. 로그인 사용자의 booking.Booking·goods.GoodsOrder·ticketing.TicketOrder·recruitment.Application 4개 도메인 이력을 단일 응답으로 조회한다. 각 항목은 orderType 판별자(BOOKING/TICKETING/GOODS/RECRUITMENT), 원본 도메인 ID, 상태, 결제 연계(paymentId), 생성 시각을 포함한다 | P0 |
| FR-6 | payment/vo/OrderType.kt의 소유권(패키지 위치)을 신규 order 상위 컨텍스트로 이관한다. 값 구성과 기존 동작(Kafka event.payment.payment.v1 발행/구독, 각 *PaymentEventWorker의 orderType 필터링)은 변경하지 않는다 | P0 |
| FR-7 | order 통합 조회는 orderType 필터, 상태 필터를 지원한다 | P1 |
| FR-8 | goods.Product에 sellerType(B2C/B2B) 판별 필드를 추가한다. b2c 일반 등록과 b2b 파트너 등록은 동일한 엔드포인트·CreateMyProductUseCase를 공유하므로(별도 파트너 전용 UseCase 없음), 판별 신호는 등록 경로가 아니라 **PartnerApiKeyAuthenticationFilter 경유 인증 여부(파트너 API Key 인증 컨텍스트)**다 — 이 컨텍스트가 있으면 B2B, 없으면(일반 JWT 인증) B2C로 자동 설정하며 사용자가 값을 직접 입력하지 않는다. 판별 신호를 UseCase가 조회 가능하게 만드는 구체 방식(인증 principal에 파트너 연동 표식 추가, 또는 authUserId ↔ partner.linkedUserId 역조회 등)은 TDD에서 확정한다 | P0 |
| FR-9 | 기존 Product 레코드는 마이그레이션으로 전량 B2C로 백필한다. 백필 실행 중 등록되는 신규 레코드는 이미 값이 채워져 있으므로 백필 대상에서 제외한다 | P0 |
| FR-10 | sellerType 자동 판별 도입으로 CreateMyProductCommand 시그니처가 변경되므로, 도메인 경계 재설계/ADR-003(제공 UseCase 시그니처 동결)을 이 과제 범위에서 함께 갱신한다. ADR-003의 실제 회귀 감시 자산은 ProvidedInterfaceContractTest.kt:27-33(CreateMyProductUseCase.execute의 파라미터가 [CreateMyProductCommand], 반환이 ProductWithStock임을 리플렉션으로 동결)이므로, sellerType 필드 추가로 이 테스트가 RED가 되면 동결 계약을 의도적으로 갱신하는 커밋임을 테스트 자체에서 갱신해야 한다(무단 우회 금지) | P0 |
| FR-11 | catalog·order 통합 조회는 원본 도메인 중 일부가 조회 실패·타임아웃돼도 나머지 도메인 결과를 정상 반환한다(부분 실패 허용). 실패한 도메인은 응답 메타데이터에 표기한다 | P1 |
| FR-12 | catalog·order 통합 조회는 페이지네이션과 정렬(기본 최신순)을 지원한다 | P2 |
Non-Functional Requirements
- catalog 통합 검색 API 응답은 P95 500ms 이내여야 한다(5개 도메인 병렬 조회 합산, 로컬 개발 환경 기준).
- order 통합 조회 API 응답은 P95 500ms 이내여야 한다(4개 도메인 병렬 조회 합산, 로그인 사용자 기준).
- 원본 도메인 1곳의 응답이 300ms를 초과하면 해당 도메인은 결과에서 제외하고 나머지로 응답한다(FR-11의 타임아웃 기준치).
- 각 도메인의 기존 쓰기 테이블·API는 스키마·계약 변경이 없어야 한다(
Product의 sellerType 컬럼 추가는 예외적으로 허용되는 국소 변경, FR-8). - sellerType 백필 마이그레이션은 다운타임 없이 실행 가능해야 한다 — 컬럼을 nullable + 기본값으로 먼저 추가한 뒤 백필하고, 이후 NOT NULL로 전환한다(
private-db-schema-convention3단계 분리).
Operations
- 통합 검색·통합 주문 조회 API별로 도메인별 성공/실패/타임아웃 카운트를 로그로 남긴다 — 특정 원본 도메인이 상시 실패하면 알림.
- sellerType 자동판별 오류 감지: B2B 파트너 인증 경로로 등록됐는데 sellerType이 B2C로 저장되는(또는 그 반대) 불일치가 발생하면 감사 로그에 기록하고 알림을 발송한다.
- 백필 마이그레이션 완료 후 검증:
Product전체 건수와 sellerType이 NULL이 아닌 건수가 일치하는지 1회성 검증 쿼리로 확인한다.
Success Metrics
- catalog 통합 검색 응답이 5개 도메인(Product/LimitedDrop/Event/Program/Recruitment) 결과를 모두 포함한다 — 커버리지 5/5.
- order 통합 조회 응답이 4개 도메인(Booking/GoodsOrder/TicketOrder/Application) 결과를 모두 포함한다 — 커버리지 4/4.
- 기존
Product레코드 100%가 sellerType 값을 보유한다(NULL 0건, 백필 완료 검증 쿼리로 확인). - B2B 파트너 API Key 인증 경유로 등록된 신규 Product 시나리오 테스트에서 100% B2B로 자동 판별된다(
PartnerOnboardingScenarioTest계열에 회귀 케이스로 추가). ProvidedInterfaceContractTest.kt(ADR-003 동결 감시)가 sellerType 반영 후CreateMyProductUseCase.execute의 최신 시그니처(파라미터·반환 타입)로 갱신되어 GREEN 상태를 유지한다 — 갱신 없이 RED로 방치된 상태는 미완료로 간주한다.- FE가 통합 검색 화면·통합 주문내역 화면을 각 1개씩 출시해 이 PRD의 API 계약을 소비한다(후속 design-fe 트랙 완료 확인).
Milestones
- M1: catalog 읽기 파사드 API (FR-1~FR-4).
- M2: order 읽기 파사드 API + OrderType 소유권 이관 (FR-5~FR-7).
- M3: sellerType 도입 + ADR-003 갱신 + 백필 (FR-8~FR-10).
- M4 (후속, 범위 외): FE 통합 검색·통합 주문내역 화면 구현 —
design-fe-web/design-fe-appTDD에서 별도 진행.
Open Questions
- 아키텍처 진단 문서 갱신 필요:
20260706-사용자정의-도메인경계-갭분석-architecture.md§1 매트릭스(모집·시설상품 “누락” 판정)와 §4 “문제 D”(취소정책 미채택)는 이 PRD 작성 과정에서 확인한 정정 사실(recruitment·facility program 이미 구현 완료)을 반영해야 한다.20260708-전체시스템-architecture.md§4-1도 동일하게 갱신이 필요하다 — 별도 아키텍트 재검증을 권고한다. 도메인 경계 재설계/ADR-003의 실제 갱신(Command 시그니처 변경 반영)은 이 PRD 승인 후 TDD 단계에서 처리할지, 아키텍트/시니어 리뷰를 별도로 거칠지 확정이 필요하다.- sellerType 소급 재판별 정책(등록 시점 값 고정, 이후 판매자 유형 전환 시에도 과거 상품은 불변)이 실제 운영 요구와 맞는지 재확인이 필요하다 — 이번 PRD는 “고정” 원칙으로 초안했다.
- catalog 통합 검색 응답 스키마에서 도메인별로 다른 가격 단위(Product 판매가·Program 1회 수강료·Recruitment 참가비·LimitedDrop 판매가·Ticket 좌석가)를 어떻게 정규화할지는 TDD에서 확정한다.
- catalog·order 캐시 도입 여부(Redis look-aside 등)는 이번 범위에서 결정하지 않는다 — NFR의 P95 500ms 목표 달성 여부를 실측한 뒤 TDD에서 판단한다.
Document History
| 날짜 | 변경 내용 |
|---|---|
| 2026-07-08 | 최초 작성 — 20260708-전체시스템-architecture.md 1단계 권고 기반. AS-IS 정정(recruitment·facility program 기구현 확인)을 반영해 catalog 5개/order 4개 도메인으로 범위 확정. 읽기 전용 파사드로 20260706 문서의 God-aggregate 우려 해소, sellerType은 등록 경로 기반 국소 쓰기 변경으로 분리 |
| 2026-07-08 | v2 — prd-reviewer NEEDS_REVISION 반영: sellerType 판별 신호를 “등록 경로(별도 UseCase)“에서 “파트너 API Key 인증 컨텍스트 경유 여부”로 정정(ADR-007상 b2c/b2b가 CreateMyProductUseCase를 공유하는 실측 반영, Problem Definition·FR-8·User Scenario 3·4 수정). FR-10·Success Metrics에 ADR-003 동결 감시 자산(ProvidedInterfaceContractTest.kt) 갱신 요구 추가 |
| 2026-07-08 | v3 — senior-pm 검증 반영: Non-Goals “FE 화면의 디자인·컴포넌트 구현” 항목에 각주 보완 — “문서 산출물 범위 밖(별도 design-fe-app.md 트랙 수행)“과 “로드맵 목표에는 FE 화면 출시 포함”을 구분 명시해 오독 소지 제거(내용 변경 없음) |