대상 구현물: screen_02_dashboard_v1.html — 자동 시뮬레이션 기대 발전량과 사용자 실측 발전량을 월별로 비교해 누적 손실량·환산 손실액을 추적하고, AI 손실 원인 추정 및 정밀 진단 전환(퍼널 3단계)으로 유도하는 발전소 오너용 대시보드. 본 문서는 실제 렌더 화면을 기준(source of truth)으로 한 요구사항과 검증용 테스트케이스를 정의한다.
무엇을, 어디까지 검증하는가
| 항목 | 내용 |
|---|---|
| 목적 | 발전소 오너가 시뮬 기대치 대비 실측 발전량의 괴리(손실)를 한눈에 인지하고, 놓친 수익을 금액으로 체감하여 ‘정밀 진단(3단계)’으로 전환하도록 유도. |
| 범위(In) | 놓친 수익 히어로 · KPI 4종(시뮬/실측/달성률/오차율) · 월별 시뮬vs실측 비교 차트(12개월) · 누적 합계행(sumrow) · AI 손실 원인 추정(3건) · 퍼널 내비게이션 · 진단 전환 CTA · DS 토큰/타이포 준수. |
| 범위 외(Out) | 실측 입력 폼(별도 화면), 인버터 연동/스트링 히트맵(3단계), 솔루션 견적(4단계), 발전소 다중 선택 실데이터, 기간 세그먼트(6/12/전체) 동적 재계산, 데이터 내보내기 백엔드, 서버 저장. |
| 가정 | 프로토타입 데모 데이터는 정적(하드코딩). 千葉 山武 192kW · FIT ¥18/kWh · 2019 가동 단일 발전소 기준. 산출은 누적 합계 기반 간이 손실 모델이며 정밀 진단 결과가 아님. |
화면에 표시된 값의 무결성(계산 일관성) 근거 — 데모 상수와 일치
누적 손실(kWh) = 실측 − 시뮬 = 170,240 − 212,800 = −42,560
오차율(%) = 손실 ÷ 시뮬 = −42,560 ÷ 212,800 = −20.0%
시뮬 달성률(%) = 실측 ÷ 시뮬 = 170,240 ÷ 212,800 = 80.0%
환산 손실액(¥) = |손실| × FIT단가 = 42,560 × 18 = ¥766,080
월별 컬럼 = 12개 (1월~12월), 각 막대 = 실측(act) + 손실분(gap)
핵심 불변식(invariant) — 212,800 − 170,240 = 42,560, 42,560 × 18 = 766,080, 170,240 ÷ 212,800 = 0.80. 이 세 항등식이 어긋나면 히어로·KPI·합계행 간 표시값이 불일치한다(데이터 무결성 결함).
우선순위: MUST SHOULD COULD
| ID | 요구사항 | 우선순위 |
|---|---|---|
| FR-01 | 놓친 수익 히어로 — 과거 12개월 놓친 예상 수익을 ¥766,080으로 강조 표시하고, 시뮬 212,800 kWh 대비 실측 170,240 kWh, 손실 −42,560 kWh (−20.0%)를 부가 설명한다. | MUST |
| FR-02 | KPI 4종 — 시뮬 기대 발전량 212,800, 실측 발전량 170,240, 시뮬 달성률 80.0%, 평균 오차율 −20.0%를 카드로 노출한다. | MUST |
| FR-03 | 월별 비교 차트 — 시뮬 기대치 대비 실측 발전량을 월별 막대로 표시한다. 컬럼(.col)은 정확히 12개(1월~12월)이며 각 막대는 실측분과 손실분으로 구성된다. | MUST |
| FR-04 | 누적 합계행 — 차트 하단 합계행(.sumrow)에 누적 시뮬 212,800 kWh, 누적 실측 170,240 kWh, 누적 손실 −42,560 kWh, 환산 손실액 ¥766,080 4칸을 표시한다. | MUST |
| FR-05 | 데이터 무결성 — 히어로·KPI·합계행에 흩어진 동일 지표는 단일 데이터 모델(2절)에서 파생되어 항상 일치한다: 시뮬−실측=손실, |손실|×FIT=손실액, 실측÷시뮬=달성률. | MUST |
| FR-06 | AI 손실 원인 추정 — 실측 패턴 기반 1차 가설을 3건(.diag-item: 음영 미스매치/패널 오염·열화/피크 컷) 위험도 배지와 함께 제시한다. | SHOULD |
| FR-07 | 임계치 경고 — 평균 오차율이 임계치(15%)를 초과하면 페이지 헤더에 ‘진단 권장’ 경고 배지를 노출한다(현재 −20.0% → 초과). | SHOULD |
| FR-08 | 퍼널 내비게이션 — 사이드바: 대시보드 active(screen_02), 정밀 진단 → screen_03_diagnosis_v1.html, 솔루션 제안 → screen_04_solution_v1.html, 로고 → index.html. | MUST |
| FR-09 | 진단 전환 CTA — ‘손실 원인 진단하기’ 및 ‘정밀 진단 시작 →’ 버튼 클릭 시 정밀 진단 화면(screen_03)으로 이동한다. | MUST |
| FR-10 | 숫자 포맷 — 모든 발전량은 천단위 콤마(212,800), 손실은 부호(−) 접두, 수익은 ¥ 접두, 비율은 소수 1자리(%)로 표기한다. | COULD |
| FR-11 | 인버터 연동 안내 — AI 추정 카드 하단에 인버터 연동 시 스트링별 히트맵으로 원인 확정이 가능함을 안내(잠금 노트)한다. | COULD |
| FR-12 | 기간 세그먼트 컨트롤 — 상단 `.seg` 버튼(6개월/12개월/전체) 클릭 시: ① 클릭된 버튼에 .on 클래스 이동. ② 차트 컬럼(.col) 표시 필터 — 6개월=마지막 6개만 표시(앞 6개 display:none), 12개월/전체=전체 12개 표시. DOM 제거 금지(총 .col 수 항상 12 유지). ③ 차트 부제 캡션(#chartPeriod) 텍스트 갱신. KPI·히어로·합계행 수치는 연간 기준선이므로 변경하지 않는다. | MUST |
품질 속성
| ID | 요구사항 | 분류 |
|---|---|---|
| NFR-01 | 데이터 일관성 — 동일 지표가 여러 위치(히어로/KPI/합계행)에 중복 표시되더라도 단일 산출 모델에서 도출되어 모순이 없어야 한다(2절 불변식). | Integrity |
| NFR-02 | 디자인 일관성 — Byteworx DS v1.0.4 시맨틱 토큰(--bw-*)·Pretendard·컴포넌트 규약 준수(하드코딩 색 최소화). | Design |
| NFR-03 | 접근성 — 손실/경고는 색(빨강)에만 의존하지 않고 부호·텍스트·아이콘을 병기한다. | A11y |
| NFR-04 | 성능 — 정적 렌더(런타임 데이터 페치 없음)로 즉시 표시. 차트는 순수 CSS 막대(외부 차트 라이브러리 미사용). | Perf |
| NFR-05 | 호환성 — 최신 Chrome/Edge/Safari/Firefox 데스크탑에서 레이아웃 동일. (모바일/협폭은 향후 과제) | Compat |
전제조건 · 절차 · 기대결과 · 연결 요구사항 — tests/dashboard.spec.js 와 매핑
| TC | 절차 | 기대결과 | FR |
|---|---|---|---|
| TC-A1 | 대시보드 접속 후 놓친 수익 히어로 확인 | 금액 ¥766,080 노출. 보조 설명에 시뮬 212,800, 실측 170,240, −42,560, −20.0% 표시. | FR-01 |
| TC-A2 | KPI 카드 4장 값 확인 | 시뮬 212,800 · 실측 170,240 · 달성률 80.0% · 오차율 −20.0%. | FR-02 |
| TC-A3 | 월별 비교 차트 컬럼 개수 확인 | .col 요소가 정확히 12개. | FR-03 |
| TC-A4 | 차트 하단 합계행 4칸 확인 | 212,800 / 170,240 / −42,560 / ¥766,080. | FR-04 |
| TC-A5 | AI 손실 원인 카드 항목 수 확인 | .diag-item 항목이 정확히 3개(높음/중간/낮음). | FR-06 |
| TC | 절차 | 기대결과 | FR |
|---|---|---|---|
| TC-B1 | DOM에서 시뮬·실측 숫자 파싱 후 차 계산 | 212800 − 170240 === 42560 (누적 손실 일치). | FR-05 |
| TC-B2 | 손실량 × FIT단가(18) 계산 | 42560 × 18 === 766080 (환산 손실액 일치). | FR-05 |
| TC-B3 | 실측 ÷ 시뮬 달성률 계산 | 170240 ÷ 212800 === 0.80 (달성률 80.0% 일치). | FR-05 |
| TC | 절차 | 기대결과 | FR |
|---|---|---|---|
| TC-C1 | 사이드바 ‘정밀 진단’ 링크 href 확인 | screen_03_diagnosis_v1.html 을 가리킴. | FR-08 |
| TC-C2 | 사이드바 ‘솔루션 제안’ 링크 href 확인 | screen_04_solution_v1.html 을 가리킴. | FR-08 |
| TC-C3 | ‘대시보드’ 항목 활성 상태 확인 | .nav-item.active 이며 href는 screen_02_dashboard_v1.html. | FR-08 |
| TC-C4 | ‘손실 원인 진단하기’ CTA 클릭 | URL이 screen_03_diagnosis_v1.html 로 전환. | FR-09 |
| TC | 절차 | 기대결과 | FR |
|---|---|---|---|
| TC-G1 | 페이지 최초 진입, 기본 상태 확인 | 12개월 버튼에 .on. 보이는 .col == 12. | FR-12 |
| TC-G2 | 6개월 버튼 클릭 | 6개월 버튼에 .on. 보이는 .col == 6. #chartPeriod에 "6" 포함. | FR-12 |
| TC-G3 | 6개월 선택 후 전체 클릭 | 보이는 .col == 12로 복귀. | FR-12 |
| TC-G4 | 6개월 선택 후 .col 총 개수(숨김 포함) 확인 | DOM 내 .col 총 수 여전히 12 (DOM 제거 없음). | FR-12·FR-03 |
| TC-G5 | 6개월 선택 후 KPI·히어로 수치 확인 | ¥766,080·212,800·170,240 불변 (연간 기준선 유지). | FR-12·FR-05 |
| TC | 절차 | 기대결과 | FR/NFR |
|---|---|---|---|
| TC-D1 | getComputedStyle(body) DS 토큰 점검 | --bw-text-primary 토큰 존재, font-family에 Pretendard 포함. | NFR-02 |
현재 구현의 한계와 후속 과제
| ID | 내용 |
|---|---|
| LIM-1 | 데모 데이터는 정적 하드코딩 — 발전소 선택 변경 시 차트·KPI가 동적 재계산되지 않는다(프로토타입). 기간 세그먼트(6/12/전체)는 차트 컬럼 표시 필터로 구현되며, KPI·히어로·합계행은 연간 기준선으로 고정된다. 실데이터 연동은 후속. |
| LIM-2 | 월별 막대는 시각적 비율(CSS height %)이며 각 컬럼의 정확한 수치는 DOM에 노출되지 않는다. 무결성 검증은 누적 합계(212,800/170,240) 기준으로만 가능하다. |
| LIM-3 | AI 손실 원인은 실측 패턴 기반 1차 가설이며 스트링 단위 확정이 아니다 — 인버터 연동(3단계)에서 히트맵으로 확정. |
| LIM-4 | ‘내 발전소/실측 입력/리포트/설정’ 사이드바 항목은 본 화면에서 비활성(href 없음). 해당 화면은 범위 외. |
| LIM-5 | 모바일(<1180px)에서 2열 레이아웃이 1열로 접히나, 협폭 미세 최적화는 후속 과제. |
본 명세는 v1 구현 시점 기준이다. 구현 변경 시 본 문서와 테스트 기대값을 함께 갱신할 것. 이 HTML이 리뷰용 source이며, 필요 시 여기서 MD/YAML 테스트 스펙을 추출한다.