RoadmapKnown Gaps

Known Gaps (현재 누락)

기준 BE v0.144.0 / FE v0.201.0 — 2026-08-05 전면 재작성(2026-08-12 SPEC #180 반영).

이 페이지는 실제로 아직 없는 것만 담는다. 코드를 직접 대조해 검증했고, 근거 파일을 함께 적는다.

⚠️ 2026-08-05 전면 재작성: 종전 페이지는 2026-05~06 시점에 멈춰 있어 이미 구현된 것이 gap 으로 남아 있었다(음원 카탈로그·CS 티켓·페이지네이션·약관 재동의 API 등). 낡은 gap 목록은 “아직 못 한 일”을 과대평가해 우선순위 판단을 오염시킨다 → §해소된 항목에 기록만 남기고 본문에서 제거했다.

관련: 구현 현황 (권위 소스) · Pending Features · 워크스페이스 docs/planning/31-alignment-ledger.md(기획-코드 정합) · docs/planning/40-cost-model.md(원가·용량)


Backend gaps

Gap영향근거
정산·협약 도메인 (ContractPlan·BillingKey·Invoice·TaxInvoice)의도적 제외 — 무료 MVP + 초기 과금은 세금계산서 수기 발급. 협약 단가도 시스템 밖 수기 관리엔티티 부재 · 22-policy-tenant §6-0
청구 근거 산출수기 청구에 필요한 “본사별 과금 대상 매장 수”가 없다. storeCount 는 status·폐점 무필터 전체 집계라 그대로 쓰면 과청구. 월 스냅샷도 없어 지난달 근거 재현 불가HqQueryService.countGroupedByHqIdIn
영업시간(businessHours) 도메인컬럼·API 전무. 다섯 기능이 여기 묶여 있다 — 재생 준수율 리포트(#172 FU-1)·마감 안내/음악·LLM 슬롯 회피·offline 판정 정확도(문 닫음 vs 장애)·야간 폴링 완화Store 엔티티
LLM 자동멘트 호출 인프라Hq 에 설정 필드(llmAutomentEnabled·llmKeywords·llmMaxPerHour)만 있고 호출·가드레일·슬롯 분배 전부 없음. 정책 설계는 20-policy-broadcast §5-3 에 보존Hq.kt
신탁 곡 식별 메타 (ISRC·아티스트·앨범·저작자·신탁단체 귀속)music 은 제목·URL·재생시간·musicSource 만 보유. play_log 는 music_id 참조뿐이라 CSV 를 뽑아도 “제목 + 재생시간”만 나온다 → 분배 근거로 부족. musicSource 가 AI/TRUST 2값뿐이라 단체별 구분 불가V15__create_music.sql · 21-policy-music §6-4
play_log 파기 배치3년 보존 정책이 있으나 스케줄러가 없어 무기한 적재. 100매장·24h 기준 연 1,750만 행V55 · 40-cost-model §2-3
정산 완료 메모 기록 필드21-policy-music §6-1 4번이 요구하나 필드·화면 없음—
매장 status 자동 전환 (90일 INACTIVE)스케줄러 없음. @Scheduled 는 송출 디스패처 2개뿐HqDispatchScheduler · RecurringDispatchScheduler
Hq.status 자동 전환 (UNPAID 등)정산 도메인 의존 — 수동 전이만 가능
사업자번호 체크섬 검증형식(NNN-NN-NNNNN) 정규식만. 유효성·중복 검증 없음Hq.kt:100
회수된 계정의 이메일 해제 수단회수는 status 만 WITHDRAWN 으로 바꾸고 행을 남기며 uq_operator_account_email 은 status 무관 전역 UNIQUE 라, 회수한 주소는 영구히 다시 쓸 수 없다. 본인 변경은 로그인이 필요하고 관리자 정정 경로도 없어 DB 수기 조치 외에 되찾을 방법이 없다. 2026-09-30 본사 계정 주소 변경 요청을 회수 후 재발급으로 우회하다 본사 로그인이 끊긴 사고의 직접 원인StoreManagerManagementService.revoke · V3
본사 관리자 추가 발급 endpoint본사 관리자 계정은 본사 온보딩 시점에만 생긴다. 기존 본사에 관리자를 더하는 경로가 없어, 유일 계정이 잠기면(회수·분실) 복구 수단이 없다. 회수는 v0.143.0 부터 마지막 활성 계정을 막지만 이미 잠긴 본사를 풀지는 못한다HqManagerController
admin 경로의 계정 상태 재검증/api/v1/admin/** 은 JWT claim 만 보고 계정 상태를 다시 확인하지 않는다. 정지·회수된 운영자의 access token 이 만료까지(최대 30분) 관리자 권한을 유지한다(refresh 만 막힌다)JwtAuthenticationFilter · SecurityConfig
알림(Notification) 도메인이메일 인프라(Azure ACS)는 구현됨(계정·인증 메일). 그러나 장애·운영 알림에 연결돼 있지 않고 per-item read 를 가진 notification 도메인은 없다EmailSender
서버 device-check(환경점검)클라 best-effort 만. RAM/해상도/이력 서버 기록 없음 → 본사 “환경 위반 배지” 불가
매장 목록의 “재생 설정 없음” 술어활성 PL 도 본사 기본 PL 도 없어 무음이 되는 매장을 목록에서 색출할 수 없다. AdminListStoresParams 에 그 필터가 없고 StoreAdminListItem 에 활성 PL 정보도 없어 client 필터로는 현재 페이지만 걸러 거짓 안심을 준다 → SPEC #185 D5 를 구현하지 않고 보류했다. 지금은 매장 상세를 하나씩 열어야 안다StoreAdminController · adminListStoresParams.ts
운영사용 기기 PL 조회기기별 지정 PL(store_device_playlist, #178)은 큐 해석 1순위인데 조회 endpoint 가 /api/v1/store/**(STORE_MANAGER 전용)뿐이다. 그래서 운영사 매장 상세의 재생 설정 섹션은 출처를 ACTIVE/DEFAULT/NONE 까지만 확정하고 DEVICE 는 “확인 불가” 로 안내만 한다(#185 D1)SecurityConfig /api/v1/store/** · StoreDeviceController

access token 즉시 무효화 (정확한 현황): 계정 정지·비밀번호 재설정·회수 시 refresh token 은 즉시 revoke 된다(revokeActiveByAccountIds — 본사/매장/운영자 관리 서비스 7곳). 정지 계정은 로그인도 차단된다(AccountSuspendedException). 다만 이미 발급된 access token 은 만료(30분)까지 유효하다 — 이는 JWT 무상태 설계의 트레이드오프이며 gap 이 아니라 알려진 특성이다.


Frontend gaps

Gap영향근거
서비스워커 / 오프라인 재생manifest.ts(설치 아이콘)만 존재. 음원 캐시 계층·예약 방송 사전 캐싱 없음 → 회선이 수십 분 끊기면 음악이 멈춘다. 일시적 끊김 자가복구는 2026-07 감사로 확보(실패 트랙 스킵·backoff·stall 워치독)apps/space/src/app/manifest.ts
운영사 매장 재생 상태 뷰재생 상태 카드·드릴다운이 본사 화면에만 있다. 무인 매장 장애를 먼저 알아야 할 운영사가 offline 을 못 본다apps/space/src/app/admin/playback-status-card.tsx
온보딩 입력 sessionStorage 임시 저장새로고침 시 state 소실
passwordMustChange middleware 단계 가드server-side 강제 redirect 는 (protected)/layout.tsx 에 있고, BE 차단(PasswordChangeEnforcementFilter 403)도 있다 → 보안 공백 아님. middleware 가드는 UX 최적화 잔여SPEC #022
HQ 정렬 UI (컬럼 헤더 클릭)기본 정렬만. 검색·필터·페이지네이션은 구현됨
본사 일괄작업 (약관 재발송·공지·결제일 변경)진입점만 존재
잔존 “준비 중” placeholdersettings/llm-ments · settings/system-policies 2곳. (정산·전역검색·장애벨은 SPEC #165·#166 으로 제거됨 — 동작하지 않는 UI 를 남기지 않는 정직성 원칙)

디자인 시스템

Gap영향
Surface 11 layer (surface-store-hq.css)미작성 — surface-admin.css 만 존재
Surface 12 layer (surface-store.css)미작성
Table primitivepackages/ui 에 없음. 각 목록이 수기 테이블

Toast·DropdownMenu·ErrorState·ListToolbar·StatusPill·ScheduleGridEditor 등은 packages/ui 에 존재하므로 gap 이 아니다. 운영사 하단 고정 미리듣기 플레이어도 구현됨(종전 “미리듣기 Player 미도입” 은 stale — 제거).


인프라 / DevOps ⚠️

가장 시급한 그룹. 24/7 무인 매장 재생 서비스인데 관측·복구 수단이 비어 있다.

Gap영향
Sentry / 에러 트래킹 (FE·BE 둘 다)미도입. 점장은 “소리가 안 나요”라고만 전화하고 재현 근거가 남지 않는다
장애 알림 채널이메일·Slack·외부 헬스체크(UptimeRobot) 전부 미도입. 30-TRD §9 에 L0~L3 매트릭스가 설계돼 있으나 하나도 이행되지 않았다
staging 환경없음. develop = 통합 브랜치이고 main 머지가 prod 직행 — 매장이 재생 중일 때 회귀가 바로 나간다
IaC (render.yaml)없음. 인스턴스 사양·수·env·DB 플랜이 대시보드 수기 설정 → 재현·복구 절차 부재
DB 백업·복구 리허설설정 여부 미확인 · 복구 리허설 기록 없음. “복구해본 적 없는 백업”은 백업이 아니다
사용량 알림 임계치Vercel·Render·Azure·DB 용량 알림 미설정 → 과금·용량 사고를 사후에 안다
Cache-Control 미설정음원 blob 에 캐시 헤더가 없어 대역폭 원가가 자릿수 단위로 흔들린다. CDN 도 미도입
e2e Playwright 커버리지2개 — 풀스택 happy-path.spec.ts(compose 필요 · e2e.yml 논블로킹) + 브라우저 단독 회귀 browser/audio-cache-http-cache-poisoning.spec.ts(서버 불필요 · ci.yml browser-regression job 이 항상 실행). 단위 테스트는 충실(BE 115 · FE 183 파일)
Visual regression (Chromatic 등)미도입

OpenAPI CI drift 검증은 구현됨 — ci.yml api-drift 잡이 커밋된 openapi.json 으로 typed client 를 재생성해 diff 를 검사한다. docs 정합 CI(docs-lint) 도 앵커·baseline 을 자동 검사한다. (종전 “작성자 의무로만”·“docs 자동 deploy 신설 필요” 는 stale — 제거)


Test coverage 측정

Gap
backend line coverage 측정 없음 (target 70%)
frontend coverage 측정 없음
mutation testing 미도입

해소된 항목 (기록 — 더 이상 gap 아님)

종전 페이지에 gap 으로 남아 있었으나 이미 구현됐다. 재조사를 막기 위해 근거와 함께 남긴다.

종전 gap 기재실제
”음원 카탈로그(Track·Library·Playlist) 전부 미도입”✅ SPEC #041·#052~#058 — 2계층 음악 도메인 완비 + 시간표(#171)
“CS 티켓 entity 미도입”✅ Ticket·TicketComment — 3 페르소나 end-to-end (#027·#086·#112·#173)
“약관 재동의 INSERT API 없음”✅ SPEC #040 POST /api/v1/legal/{terms,privacy}/agree
”본사 상세 endpoint 없음(목록만)”✅ SPEC #020 GET /api/v1/admin/hq/{id}
”TenantAuditLog 자동 기록 없음”✅ 임퍼소네이션·운영자·본사·매장 audit 4종 + CSV 5종
”가맹 매장 등록 endpoint 없음”✅ SPEC #011 + 본사 위임 등록·CSV 일괄(#106·#111)
“STORE_MANAGER 계정 발급 흐름 없음”✅ SPEC #021·#029 (발급·관리 5 endpoint)
“독립(INDEPENDENT) 매장은 PL 을 배정할 수단이 제품에 0” (감사 R2·OP-F1 — 점장 화면 영구 NO_ACTIVE_PLAYLIST)✅ SPEC #185 — listHqs?includeIndependent=true(BE) + PL 생성·목록에서 가상 본사 노출·“독립 매장” 표시 매핑(FE)
“매장별 PL 지정 화면 부재 — BE·BFF 완비인데 UI 호출부 0건” (감사 R1·OP-F2)✅ SPEC #185 D1 — 운영사 매장 상세 [재생 설정] 섹션(지정·해제 + 해석 출처 표시)
“본사가 PL 을 못 바꾸는데 안내도 대안 경로도 없음” (감사 HQ-C7·O14)✅ SPEC #185 D4 — 본사 매장 상세 역할 경계 안내 + /admin/support/new 프리필 CTA (권한은 #170 유지)
“Hq.status 전이 규칙·관리 UI 미구현”✅ SPEC #018·#024 (정지/복구 + 사유 + 세션 무효화)
“HQ / 매장 페이지네이션 없음”✅ SPEC #043·#044·#045 서버사이드 검색·필터·페이지네이션
”환영 이메일 / 알림 인프라 미도입”⚠️ 부분 — 이메일 인프라는 ✅(#145 Azure ACS · 계정·인증 메일 4종). 장애 알림 연결·notification 도메인은 여전히 gap
”검색 활성화(탑바) placeholder” · “알림(탑바) placeholder”✅ 제거됨 — 동작하지 않는 UI 를 두지 않는 정직성 원칙(SPEC #165·#166)
“임퍼소네이션 카운트다운 배너 정밀화 필요”✅ SPEC #157 — 만료 종착 통일(middleware 앞단 차단)
“대시보드 stats — 장애·CS·방송 지표 없음”⚠️ 부분 — CS·방송·audit 지표는 ✅(#017·#035·#126). 장애 지표만 도메인 부재로 잔여
”미리듣기 Player 미도입(Surface 11)”✅ 운영사 하단 고정 커스텀 플레이어 구현
”OpenAPI CI drift 검증 없음”✅ ci.yml api-drift 잡
”60분 비활동 idle 자동 로그아웃 없음”— 의도적 부재(일반 서비스 관례). idle 강제는 임퍼소네이션 60분 한정

References

  • 각 SPEC 2-N 의도적 비포함 섹션
  • 워크스페이스 docs/planning/31-alignment-ledger.md — 기획 문서 ↔ 코드 정합 레지스터
  • 워크스페이스 docs/planning/40-cost-model.md — 원가·용량(캐시·폴링·DB 적재)
  • 워크스페이스 docs/planning/product-review-2026-08.md — 전반 리뷰·우선순위