Commit Graph

9 Commits

Author SHA1 Message Date
Hyungi Ahn e8c348ab21 feat(dashboard): Day 4 튜닝 — 임계치 재조정 + deep_summary 안정성 카드
3일 telemetry (599 triage / 555 deep) 기반 임계치 재평가:

1. 에스컬레이션 비율 — 임계치 의미 reframe
   - 기존: >20% 적색 (튜닝 필요) → 항상 적색 (운영 패턴 97%)
   - 신규: <80% 적색 (정책 매칭 실패 증가)
   - 메시지: "safety 정책상 95~100% 가 정상" 보조 표시
   - safety_reference 99.7%, generic 100% (fallback risk_flag), msds 46.2%
     → 운영 정상 패턴 확인

2. Deep summary 안정성 — 신규 카드 추가
   - mode='summary_deep' 의 error_code IS NOT NULL 비율
   - 현재 5.2% (call_failed 21 + parse:ValidationError 8)
   - >5% 적색 임계
   - MLX 호출 timeout / JSON 파싱 실패 모니터

3. triage JSON 건강도, Backlog Suppression — 임계치 유지
   - 현재 0%, 1% — 매우 안정. 보수적 임계 유효.

Backend: TierHealthStack 에 deep_total / deep_err_total 추가
Frontend: 카드 그리드 3열 → 4열 (lg), Day 4 신규 카드.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 08:29:53 +09:00
Hyungi Ahn 04f9eb6582 feat(ui): B-3 정보창 tier 자동 표시 + 대시보드 3종 카드
정보창 (AnalysisPanel):
- doc prop 추가. doc.ai_tldr / ai_bullets / ai_detail_summary / ai_inconsistencies
  있으면 버튼 없이 자동 렌더 (Section A).
- tier 배지 (triage=흰 / deep=파랑) + tldr + bullets + detail 계층 카드.
- inconsistencies kind 별 아이콘: version_drift=Calendar / procedure_conflict=
  GitBranch / source_conflict=Quote / missing_basis=HelpCircle. warning 톤.
- 기존 "고급 분석" 버튼 (/documents/{id}/analyze 4층 응답) 은 Section B 로 유지.

AIClassificationEditor:
- 제목 옆 tier 배지 ("깊이" accent / "짧음" neutral) — ai_analysis_tier 값 기준.

대시보드 (B-3 3종 카드):
- "에스컬레이션 비율 (24h)": escalated_to_26b / triage_total. 20% 초과 적색,
  1% 미만 회색 (false negative 신호). reason 상위 4개 뱃지.
- "triage JSON 건강도 (24h)": error_code='triage_json_invalid' / triage_total.
  5% 초과 적색 (프롬프트/모델 이슈).
- "Backlog Suppression (24h)": suppressed_reason IS NOT NULL / triage_total.
  10% 초과 주황 (임계치 재조정 신호).

Backend:
- dashboard.py 에 TierHealthStack 모델 + analyze_events 24h 집계 쿼리.
- escalation_by_reason (unnest(escalation_reasons)) + escalation_by_domain
  (subject_domain) 서브 집계.

Frontend types:
- stores/system.ts DashboardSummary 에 tier_health 옵셔널 필드 추가.

UI 는 PR-A shadow 기간에도 tier_health.triage_total > 0 조건으로 조건부 표시 —
데이터가 없으면 카드 자체가 숨겨져 첫 삽입 시 UX 충격 0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 10:38:53 +09:00
Hyungi Ahn e88640d3d8 feat(category): law 카테고리 분리 — enum + backfill + classify skip
- migrations/152: ALTER TYPE doc_category ADD VALUE 'law' (DDL only; PG16 단일-트랜잭션 제약상 backfill 은 별도)
- models/document.py: Enum 에 'law' 추가 (7 활성 + 3 유보)
- workers/law_monitor.py: Document(..., category='law') — 신규 유입부터 세팅
- workers/classify_worker.py: source_channel='law_monitor' early-return + 최소 필드 (ai_domain='법령', ai_tags=['법령'], importance='medium'). AI classify skip — 법령 구조 고정/외부 source of truth/자동 재수집
- scripts/backfill_category.py: law 분기 + WHERE re-target ((source_channel='law_monitor' AND category='document')) + VERIFY cat_law/law_source_count + fail 조건
- api/documents.py: default 목록 제외에 law_monitor 추가 (news 와 동일 패턴)
- api/dashboard.py: documents count FILTER 에 law_monitor 제외 (category_counts.law 는 기존 GROUP BY category 로 자동 노출)
- frontend/Sidebar.svelte: '법령 알림' 버튼 ?source=law_monitor → ?category=law (explicit category 경로가 default exclusion 을 skip)

plan: ~/.claude/plans/stateless-churning-raccoon.md
axis 원칙: category=UI 축, policy/telemetry=source_channel+ai_domain 축 (feedback_category_vs_ai_domain_axis.md)

배포 순서: push → GPU pull → compose up --build fastapi frontend → backfill --dry-run → --apply.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 09:14:56 +09:00
Hyungi Ahn cec464ae2d fix(media): §3 ship-readiness — stt preload + healthcheck + queue enum + dashboard queue_lag
stt:
- services/stt/server.py: lazy → eager preload in FastAPI lifespan.
  STT_PRELOAD=0 으로 lazy 강제 가능 (개발/테스트). preload 실패해도
  프로세스는 살아 있고 /ready false 로 남아 healthcheck 가 unhealthy 처리.
- docker-compose.yml: healthcheck /health → /ready. /health 는 단순
  liveness 라 모델 미적재 상태도 healthy 로 잡혀 운영 신호 부적합.

queue ORM:
- app/models/queue.py: process_stage enum 에 'stt'/'thumbnail' 추가 +
  create_type=False (migration 150/151 가 DB enum 확장 담당). 이게
  없으면 stt_worker INSERT 시 SQLAlchemy 가 enum value 를 거부.

dashboard 강화 (§4 선제, §3 신규 stage 까지 자동 커버):
- app/api/dashboard.py: category_counts + library_pending_suggestions +
  queue_lag (stage 별 pending/processing/failed + oldest_pending_age_sec).
- frontend/src/lib/stores/system.ts: QueueLag 타입 + DashboardSummary 확장.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 07:04:52 +09:00
Hyungi Ahn 2b5a6d410b refactor(dashboard): 상황판 재설계 — 사용자 지시서 기반 구현
대시보드를 통계판에서 상황판으로 전환:
- 헤더 + 시스템 상태 인라인 (비클릭)
- 핀 메모 최상단 조건부 (컴팩트 띠, 최대 3개)
- 카드 4개 (문서함/메모/뉴스/승인대기) 모바일 2×2
- 최근 활동 전체 너비 7건, 2줄 스캔형 + 법령 배지
- 파이프라인 details 접힘 (실패 시 자동 open)
- 제거: 도메인 분포, 법령/시스템 별도 카드, 8:4 분할

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 14:42:15 +09:00
Hyungi Ahn fa0175058a feat(dashboard): 카운트 분리 — 문서함/메모/뉴스/승인대기
전체 문서 1개 카드를 6개로 분리: 문서함, 메모, 뉴스, 승인대기,
법령알림, 시스템. 단일 FILTER 쿼리로 효율적 카운트.
각 카드 클릭 시 해당 페이지로 이동.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 09:19:00 +09:00
Hyungi Ahn 24142ea605 fix: Codex 리뷰 5건 수정 (critical 1 + high 4)
1. [critical] config.yaml → settings 객체에서 taxonomy 로드 (import crash 방지)
2. [high] ODF 변환: file_path 유지, derived_path 별도 필드 (무한 중복 방지)
3. [high] 법령 분할: 첫 장 이전 조문을 "서문"으로 보존
4. [high] Inbox: review_status 필드 분리 (pending/approved/rejected)
5. [high] 삭제: soft-delete (deleted_at) + worker 방어 + active_documents 뷰
   - 모든 조회에 deleted_at IS NULL 일관 적용
   - queue_consumer: row 없으면 gracefully skip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 07:15:13 +09:00
Hyungi Ahn b54cc25650 fix: 미분류 판단 기준 변경 — file_path 기반 → ai_domain 없음 기준
파일을 물리적으로 이동하지 않으므로 file_path로 미분류 판단 불가.
ai_domain이 NULL 또는 빈 문자열인 문서를 미분류로 취급.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:05:41 +09:00
Hyungi Ahn cfa95ff031 feat: implement Phase 4 SvelteKit frontend + backend enhancements
Backend:
- Add dashboard API (today stats, inbox count, law alerts, pipeline status)
- Add /api/documents/tree endpoint for sidebar domain/sub_group tree
- Migrate auth to HttpOnly cookie for refresh token (XSS defense)
- Add /api/auth/logout endpoint (cookie cleanup)
- Register dashboard router in main.py

Frontend (SvelteKit + Tailwind CSS v4):
- api.ts: fetch wrapper with refresh queue pattern, 401 single retry,
  forced logout on refresh failure
- Auth store: login/logout/refresh with memory-based access token
- UI store: toast system, sidebar state
- Login page with TOTP support
- Dashboard with 4 stat widgets + recent documents
- Document list with hybrid search (debounce, URL query state, mode select)
- Document detail with format-aware viewer (markdown/PDF/HWP/Synology/fallback)
- Metadata panel (AI summary, tags, processing history)
- Inbox triage UI (batch select, confirm dialog, domain override)
- Settings page (password change, TOTP status)

Infrastructure:
- Enable frontend service in docker-compose
- Caddy path routing (/api/* → fastapi, / → frontend) + gzip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 06:46:19 +09:00