P2 셀프서비스 리포트 — 기간 일반화·템플릿 관리·자동생성 스케줄·EU레인지 클린범위 #2

Merged
windpacer merged 6 commits from feat/p0-selfservice-report into main 2026-06-18 08:51:08 +09:00
Owner

P2 (A·B·C·D) + 부가

  • A 토큰 파서 일반화: period=DAILY|MONTHLY|YEARLY 윈도 분기(엔진/토큰/요약 UI). 오타 period는 명시적 error.
  • B 템플릿 관리 UI: 저장 템플릿 목록/선택/삭제 + 등록·생성 분리(매번 재업로드 제거).
  • C 템플릿별 자동생성 스케줄러: 멱등 catchup BackgroundService(report_template 스케줄 컬럼, dedup 중복0·다운타임 복구).
  • D 클린범위 자동도출: tag_metadata EU레인지(eulo/euhi) 우선, 없으면 역할 기본값 폴백(947태그 적재 확인).
  • 생성본 과거 다운로드: report_run.out_blob 이력 조회/다운로드(스케줄 자동생성본 회수).
  • docs: P1 전환 후 죽은코드 점검 결과 정리.

🤖 Generated with Claude Code

## P2 (A·B·C·D) + 부가 - **A** 토큰 파서 일반화: `period=DAILY|MONTHLY|YEARLY` 윈도 분기(엔진/토큰/요약 UI). 오타 period는 명시적 error. - **B** 템플릿 관리 UI: 저장 템플릿 목록/선택/삭제 + 등록·생성 분리(매번 재업로드 제거). - **C** 템플릿별 자동생성 스케줄러: 멱등 catchup BackgroundService(`report_template` 스케줄 컬럼, dedup 중복0·다운타임 복구). - **D** 클린범위 자동도출: `tag_metadata` EU레인지(eulo/euhi) 우선, 없으면 역할 기본값 폴백(947태그 적재 확인). - 생성본 과거 다운로드: `report_run.out_blob` 이력 조회/다운로드(스케줄 자동생성본 회수). - docs: P1 전환 후 죽은코드 점검 결과 정리. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
windpacer added 6 commits 2026-06-18 08:50:19 +09:00
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- MetricRequest/Result에 Period 추가, ReportMetricService.PeriodWindowUtc로
  선택일이 속한 일/월/연 [from,to)를 KST→UTC 변환(DAILY는 기존 동작 동일).
- 오타 period는 daily 묵인 대신 명시적 error(결정론 게이트).
- ReportFillService 토큰 period= 파싱 + 셀주석/cells_json 박제.
- summary 엔드포인트 period 파라미터, 웹 바로보기 기간 드롭다운 + 치트시트.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- IReportTemplateStore.ListAsync(생성이력 집계 LEFT JOIN)/DeleteAsync(report_run CASCADE).
- GET /api/report/templates, DELETE /api/report/template/{id}.
- 엑셀폼 패널: 매번 재업로드 → 등록(1회) → 저장 목록에서 라디오 선택 → 생성.
  생성횟수·최근시각 표시, 삭제 버튼, 생성 후 목록 자동 갱신.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- report_template에 schedule_enabled/period/hour/source 컬럼(ALTER IF NOT EXISTS,
  p0_report.sql + 서비스 EnsureSchema 멱등).
- Hc900ReportScheduleService: 매 N초 활성 템플릿마다 완료된 기간(anchor)을
  lookback 내 산출 → report_run 성공기록 없으면 FillAsync 생성·기록.
  중복 0(HasSuccessfulRun dedup)·다운타임 자동복구. 윈도는 셀 토큰 period=가 결정.
- IReportTemplateStore.UpdateSchedule/HasSuccessfulRun, ListAsync에 스케줄 컬럼.
- PUT /api/report/template/{id}/schedule (period/hour 검증).
- UI: 목록에 스케줄 상태 표시 + 선택 템플릿 스케줄 편집기.
- appsettings Report:Schedule (간격·catchup) 추가.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- EuRangeProvider: tag_metadata의 eulo/euhi를 base_tag별 1회 캐시(thread-safe),
  미존재/로드실패 시 역할 기본값 폴백. ComputeAsync에서 선로딩(동기 조회 대비).
- ReportColumnMap.Tag(): 클린범위(스파이크/드롭아웃 BETWEEN 경계) = EU레인지 우선.
  energy_efficiency/yield/control_residual의 하드코딩 TEMP/STEAM/FLOW 제거.
- 검증: hc900.tag_metadata에 947태그 eulo/euhi 적재 확인(리포트 태그 전부 포함).
  운전모드 제외는 별개(cleaning 마스크); EU레인지는 계기 물리유효범위만 담당.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- IReportTemplateStore.ListRunsAsync/GetRunBlobAsync (+ ReportRunInfo DTO).
- GET /api/report/template/{id}/runs (최신순), GET /api/report/run/{runId}/download.
- UI: 선택 템플릿 '생성 이력' expander — 기간/소스/상태/시각 + 과거본 다운로드 링크.
  스케줄 자동생성본도 여기서 회수(기존엔 생성·기록만 되고 조회 불가).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
windpacer merged commit 5ce09480b6 into main 2026-06-18 08:51:08 +09:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: windpacer/HC900-Crawler#2