Commit Graph

101 Commits

Author SHA1 Message Date
windpacer
1811e1fed7 docs: S7 기대값 정정(큰 음수 vloss→'물질수지 불일치') + override 엔진확장 라이브검증 기록
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 16:33:34 +09:00
windpacer
60946f3c47 feat: Sim Override를 FF 엔진까지 확장 (S7/§10/front 자율검증)
- FeedforwardSupervisor.BuildSnapshotAsync Sample/SampleExact: override 우선(신선) → /api/ff/advisory(엔진)도 override 반영
- 안전가드: _sim.Enabled 시 auto-write 억제(가짜 입력→실제 OPC 쓰기 방지)
- 해소: S7(mbState)·§10/front 자율검증 가능. 잔여: S6(override=fresh)·P4(FeedMoveThresholdPerMin=0)
- 작업지시서 WP0 한계 갱신

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 16:30:32 +09:00
windpacer
9065b19a0a docs: WP2 현행 FF 엔진 프로빙 결과
라이브 /api/ff/advisory 관찰(데모=SP+일정변동 반복). 확정: P1(LevelDriven B/D rec=K×feed 무클램프, P는 lag), P2(PCT 꺼짐 pct==raw), P3(pi-6111b 미사용), P5(mbState, 데모 비보존 아티팩트). 발견: 데모 temps 비물리(A>D>C>B)라 §10/front 물리검증·P4·S7은 운전원 DCS주입 필요(override는 엔진 미반영).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 16:29:01 +09:00
windpacer
54ca4d0d62 feat: 안전 피드램프 Advisor (WP0 Sim Override + WP1 매트릭스 + WP3 계산기)
WP3 — read-only Feed Ramp Advisor (쓰기 없음):
- FeedRampCalculator(순수함수): ceiling(밸브포화/flooding)·램프율(valveSlew/dynamic)·예상시간·binding·스팀(FIQ-6115 목표, a안 현열보정) 산출
- FeedRampModels(DTO+ISimOverrideStore), FeedRampAdvisorService(라이브+override), GET /api/ff/ramp-advisor
WP0 — Sim Override Layer:
- SimOverrideStore(ConcurrentDictionary+volatile), sim/override GET·POST·DELETE, Feedforward:SimOverrideEnabled 게이트
- 한계: ramp-advisor만 통합·엔진 미반영 → S6/S7 라이브는 override 불가(문서화)
WP1 — docs/안전피드램프-검증시나리오매트릭스.md (S0~S7)
검증: 단위 31/31, 라이브 스모크 S1~S5 기대치 일치(3.29 dynamic/60.8min/366.7, 31.58 valveSlew, 2105 clamp, 1018.8 flooding, 309 현열)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 16:22:11 +09:00
windpacer
d1927f2d22 docs: 안전 피드램프 advisory 설계 브레인스토밍 + 작업지시서
- docs/안전피드램프-한계치-브레인스토밍.md (§0~§10): C-6111 피드램프/듀티/드로우 advisory 설계 — 램프율·ceiling 공식, 자기조절 캐스케이드, 편차 trim 소스, 압력 서브시스템(pi-6111b/ΔP/PCT), tray 레이아웃(패킹 3구간), 온도 역전 판정 spec
- plans/안전피드램프-advisory-작업지시서.md: WP0 Sim Override + WP1 시나리오매트릭스 + WP2 현행엔진 프로빙 + WP3 FeedRampAdvisor 구현 지시 (다른 LLM 실행용)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 15:28:28 +09:00
windpacer
76fdce8b13 fix: Feedforward 버그 2건 — config ordinal off-by-one + front 부호 반전
- FeedforwardConfigStore: advisory_only를 GetBoolean(31)로 읽어 IndexOutOfRange (컬럼 31개=ordinal 0~30, advisory_only=30). 30으로 수정 → FF supervisor 루프 복구
- FeedforwardEngine.ApplyFront: front metric을 Delta(temps[0],temps[^1])=하단−상단으로 계산해 부호 반전(프론트 상승 시 trim 권고 역전). Delta(temps[^1],temps[0])=상단−하단으로 수정
- FeedforwardFrontTests: 엔진 경유 부호 회귀 테스트 2건 추가 (24/24 통과)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 15:28:21 +09:00
windpacer
7c26aa7361 feat: Phase II auto-write (WriteGuard, audit, auth) + WO-2~7 완료
Phase II:
- FfOperatorAction entity + ff_operator_action DDL/DbSet
- IFeedforwardWriteGuard + FeedforwardWriteGuard (SP bounds, grade C, transient, NaN)
- IFeedforwardAuditService + FeedforwardAuditService (raw ADO insert/query)
- FeedforwardSupervisor.AutoWriteAsync (per-stream OPC UA after Tick, rate-limited)
- FeedforwardConfigStore: advisory_only now read/writes DB, sp_node_id column
- FeedforwardController: auth (X-Kb-Token) on config/delete/write/audit;
  POST write/{id}/{key} manual SP write; GET audit; write results in MapColumn
- ff.js: token header, auto-write badge, per-stream write result, spNodeId, advisoryOnly
- ff.css: .ff-write-badge, .ff-write, .ff-write-err, .ff-wg-blocked
- Program.cs: register audit (Scoped) + write guard (Singleton)

WO-2~7 (build 0W/0E, test 22/22):
- PCT monitor, θ auto-tune, slow bias, front position indicator,
  total reflux recovery, config form expansion
2026-05-31 20:30:06 +09:00
windpacer
671d4ee1e5 docs: 운전원교육자료/브레인스토밍/knowledge 업데이트 + MCP config 2026-05-31 17:31:50 +09:00
windpacer
48a6b6be57 docs: 측류추출 통합유량설정공식 설계문서 (Phase I/II/III + 분석엔진) 2026-05-31 17:31:47 +09:00
windpacer
7f1965a678 test: xUnit test project for Feedforward blocks (DeadTimeBuffer/RateLimiter/FirstOrderLag) 2026-05-31 17:31:44 +09:00
windpacer
e3167807b4 feat: Feedforward Phase I — DDL 2테이블 + DI 등록 + Tab 18 frontend (ff.js/html/css) 2026-05-31 17:31:42 +09:00
windpacer
7688757b21 feat: Feedforward advisory engine Phase I — core C# models/blocks/engine/supervisor/store/controller 2026-05-31 17:31:39 +09:00
windpacer
b53a34c9db diagnosis-checklist: 진단 체크리스트 추가 2026-05-29 09:49:48 +09:00
windpacer
d8cae11c75 docs: P6-1 경비물 제거 공정 KB 문서 추가 2026-05-29 09:49:48 +09:00
windpacer
4eccb75193 plans: 새 작업 계획 문서들 추가 (OPUS-v2, P&ID bySonnet, TASK 문서) 2026-05-29 09:49:48 +09:00
windpacer
3fbca36719 opencode: vllm-36b → vllm-14b/35b 분리, baseURL 포트 변경 2026-05-29 09:49:43 +09:00
windpacer
a411441f4f OllamaController: find_tags 설명 업데이트 / opcserver_autostart: {} → false 2026-05-29 09:49:40 +09:00
windpacer
d8095d0c8d P&ID: export GetEquipmentAsync null 파라미터 추가 + 오래된 plan 문서 삭제 2026-05-29 09:49:36 +09:00
windpacer
c7da3f9735 nl2sql: sql_prompt.py 모듈 분리 + eval/training/verifier 파이프라인 2026-05-29 09:49:29 +09:00
windpacer
f972c66810 feat(pid-ui): 추출결과 pane 컬럼 추가 + 정렬 수정 + sub_area 편집
- FROM_at / TO_at / SUB_AREA 컬럼 추가 (헤더·행 렌더·추가행 입력란)
- SUB_AREA: tag_metadata upsert/delete로 직접 편집 가능 (빈 문자열 = 삭제)
- natural sort 수정: prefix 알파 → 숫자 정수값 → suffix 알파
  (기존 TagNo.Length 기준 그루핑 제거 → TI-9217 다음 TI-10103 올바르게 정렬)
- 매핑 완료 시 태그명 badge 제거 →  버튼만 표시
- colgroup 퍼센트 비율로 컬럼 폭 고정 (table-layout:fixed)
- pid-table td/th overflow:hidden + text-overflow:ellipsis 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 09:47:26 +09:00
windpacer
8f5dabbbc7 fix: tagDcs 수동 변경이 재시작 시 리셋되는 버그 수정 + PID 테이블 신규 레코드 추가 기능 + natural sort
- tagDcs backfill(Step-4)을 컬럼 존재 여부로 가드하여 최초 1회만 실행
- UpdatedAt EF 매핑 ValueGeneratedOnAddOrUpdate → ValueGeneratedOnAdd
- PropertyNameCaseInsensitive = true 추가
- PID 추출 결과 테이블에 '+ 추가' 버튼 및 빈 editable 행 (POST /api/pid)
- 태그번호 정렬: prefix → 길이 → case-insensitive natural sort
- 페이지네이션 표시 범위 ±3 → ±10
2026-05-28 16:24:16 +09:00
windpacer
543ce85af5 refactor: DCS 분류 로직 정리 — 죽은 코드 제거
## 변경 내용

### pid.js — PREFIX 행 DCS 체크박스 완전 제거
- 각 prefix 행의 DCS 체크박스/토글 제거
- 그룹 섹션(DCS 태그 / 현장 계기) 자체가 DCS 여부를 명확히 표현
- 그룹 이동 필요 시: 삭제 후 반대 그룹에서 추가
- pidUpdatePrefixRule: tagDcs = 그룹(vcat)에서 결정, 행 입력 불필요
- isInstr 변수 제거 (미사용)

### PidExtractorService.cs — ClassifyTagClass 파라미터 정리
- 시그니처: (tagNo, category, tagDcs, hasExperionLink) → (category, tagDcs)
  - tagNo: 새 로직에서 완전 미사용 → 제거
  - hasExperionLink: tag_dcs 도입으로 역할 소멸 → 제거
- 3개 호출부 모두 갱신
- 로직: category=instrument이면 tagDcs→system/field, 그 외 null (2줄로 단순화)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 15:56:33 +09:00
windpacer
300dfe65a4 feat(pid-ui): PREFIX 분류 정의 패널 — DCS 태그/현장 계기 섹션 분리
## 변경 내용

### CATEGORY_META
- instrument → instrument_dcs / instrument_field 가상 키로 분할
- 각 가상 키에 dbCat/tagDcs 메타 추가 (DB에는 여전히 category='instrument')
- instrument 키는 장비 목록 배지용으로 유지

### CATEGORY_ORDER
- 'instrument' 제거 → 'instrument_dcs', 'instrument_field' 두 섹션으로 분리

### pidRefreshPrefixRules
- 그룹핑 로직: r.category==='instrument' → tagDcs로 분기
- 그룹 div에 data-vcat 속성 저장 (인덱스 기반 취약한 방식 제거)
- 추가 입력행: 그룹이 tagDcs 결정 → 별도 DCS 체크박스 없음
  (placeholder도 그룹별 예시로 변경: FIC / FT / P-)
- 규칙 0건이어도 추가 입력행 항상 표시
- instrument 그룹 행: DCS 토글 표시 (체크 변경 후 수정 클릭 시 반대 그룹으로 이동)
- 비instrument 행: DCS 토글 없음

### pidResolveCat() 신규
- 가상 카테고리 키 → { category, tagDcs } 변환 헬퍼

### pidAddPrefixRule
- vcat 인자 사용, pidResolveCat()로 실제 DB 값 결정
- Add 행에 DCS 체크박스 없음 — 그룹이 결정

### pidUpdatePrefixRule
- data-vcat으로 그룹 인식 (기존 인덱스 기반 제거)
- instrument 행: DCS 토글 체크로 tagDcs 결정 (그룹 이동 가능)
- 비instrument 행: 그룹 기본값(false) 사용

## 결과
- DCS 태그 (FIC/TIC/PIC/LIC/FY/TY/PY/LY/FV/TV/PV/LV) 12건 별도 섹션
- 현장 계기 (FT/FCV/PSV/XV 등) 29건 별도 섹션
- 추가 시 자동으로 tagDcs 설정 — 혼동 없음

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 15:47:09 +09:00
windpacer
c1d228d1f6 feat: pid_equipment에 tag_dcs BOOLEAN 추가 — DCS 함수블록 vs 현장 계기 구별
## 변경 내용

### DB 스키마 (Boot DDL)
- pid_prefix_rules.tag_dcs BOOLEAN NOT NULL DEFAULT FALSE 추가
- DCS prefix 시드 마킹: FIC/TIC/PIC/LIC/FY/TY/PY/LY/FV/TV/PV/LV → tag_dcs=TRUE
- pid_equipment.tag_dcs BOOLEAN NOT NULL DEFAULT FALSE 추가
- 기존 행 backfill: instrument_type LIKE prefix% StartsWith 매칭 (FICQ/FICA 자동 포함)

### C# 도메인/서비스
- PidPrefixRule: TagDcs bool 프로퍼티 추가
- PidEquipment: TagDcs bool 프로퍼티 추가
- PidPrefixRuleDto (3개 record): TagDcs 추가
- PidExtractorService:
  - ResolveTagDcsAsync() 신규 — StartsWith 매칭, 가장 긴 prefix 우선
  - ClassifyTagClass() 재설계 — tagDcs 우선 (hasExperionLink 제거)
  - 추출 저장 시 TagDcs 채우기
  - ExportToExcelAsync() col18=DCS태그 추가 (col17=id 보호)
  - ImportFromExcelAsync() col18 읽기 (hasDcsCol 감지)
  - ApplyCategoriesToExistingAsync() 두 루프에 tag_dcs backfill 추가
  - CreatePrefixRuleAsync/UpdatePrefixRuleAsync TagDcs 저장

### Web Controller
- PidController.GetPrefixRules: tagDcs: r.TagDcs 추가

### Web UI (pid.js)
- PREFIX 그룹 각 행에 DCS/현장 배지 + 체크박스
- Add/Update body에 tagDcs 전송

### MCP/LLM
- server.py: _DCS_PREFIXES frozenset 추가
- _classify_pid_tag(): tag_dcs 반환 필드 추가
- _DB_SCHEMA: pid_equipment 테이블 설명 추가
- upsert_pid_connection: tag_dcs 파라미터 + UPDATE/INSERT SQL 수정
- sql_prompt.py: pid_equipment 테이블 추가
- prompts/plant_context.md: tag_dcs 설명 + 쿼리 예시 추가

## 설계 결정
- FT 전송기는 Experion 연결 여부와 무관하게 현장 계기 (tag_dcs=FALSE)
- tag_dcs=TRUE: prefix rule이 ground truth → system 확정
- hasExperionLink는 TagClass 결정에서 제거 (연결 정보는 ExperionTagId FK로 보존)
- compound prefix (FICQ/FICA): LIKE StartsWith 매칭으로 자동 커버

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:12:45 +09:00
windpacer
95ec160e98 docs: P&ID PREFIX 분류 tag_dcs 컬럼 도입 플랜 작성
plans/P&ID-추출-PREFIX-DB-수정플랜-byBigPickle.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 11:46:21 +09:00
windpacer
0eb598d411 fix: LLM 채팅 모델 선택 및 텍스트 도구 호출 파싱 수정
- Program.cs: vLLM 클라이언트 포트 8001 → 8000 (현재 구동 모델과 일치)
- llmchat.js:
  - paneInit에서 llm-type-select 초기값을 llmType(localStorage)으로 동기화 (HTML 기본값 ollama 보정)
  - llmLoadModels(): vLLM 타입 시 llm-model.json 모델을 항상 드롭다운에 추가·선택 (갱신 버튼 포함)
  - llmOnTypeChange(): async로 변경, await llmLoadModels() 후 llmLoadConfigToUI() 호출
- OllamaController.cs:
  - 텍스트 도구 호출 감지: "params" 키 추가 (기존 parameters/arguments 에 params/args 병용)
  - 배열 포맷 [{tool,params},{...}] 지원 — ExtractFirstJsonArray() 신규, 원소별 순차 실행 후 합산 결과 전달
  - ExtractBalanced() 공통 메서드로 Object/Array 추출 로직 통합

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 09:46:22 +09:00
windpacer
3926a33418 chore: opencode vllm 모델정의 갱신 — 36b 키 + 컨텍스트 확장
- vllm-35b → vllm-36b 키명 정정
- context 131072 → 262144, output 8192 → 32768

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 09:57:21 +09:00
windpacer
01ed4527d3 refactor: 트렌드 듀얼커서를 graphic 수동배치 → 레이어(markLine/markPoint)로 재구현
- TR_LAYERS에 cursor 레이어(global) 추가, cursorMode일 때만 활성
- 기존 graphic group 수동 픽셀배치(setOption replaceMerge) 제거 →
  layerCursor가 A/B 마커(markPoint)·연결선·Δ라벨(markLine)을 데이터좌표로 반환,
  픽셀변환은 ECharts에 위임
- trRenderCursor()는 trRender() 위임으로 단순화
- 기울기 단위 보정: /s → /min (분당 변화율)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 09:57:21 +09:00
windpacer
3e9f3076ef chore: 루트 문서 정리 — knowledge/ CANON 소스 신설 + 흩어진 문서 루트 밖 격리
seed 품질 확보(GIGO 차단). 루트에 흩어졌던 ~150개 문서를 용도별 분리.

- knowledge/ 신설 = 단일 CANON 지식 소스 (RAG/지식은 여기만 참조)
  · 플랜트 지식 7: 구조설명 6-1/6-2차, 측류추출 관계식·시간지연, PGMEA 일반상식·운전주의점
  · 도면-데이터시트/: As-Built 15 + FCV 데이터시트 2 (PDF 바이너리는 .gitignore, 디스크 유지)
- 계획·진단·대화로그·멀티모델 초안(byQwen/byGemma 등)·완료작업(dxf-graph/·fastTable/·plans/)은
  **프로젝트 루트 밖 저장소로 격리**(삭제 아닌 이동, 복원 가능):
    /home/windpacer/projects/ReferenceSources/ExperionCrawler/
  (ExperionCrawler.Tests/ 도 동일 위치 — 완료/실패분, 필요시 복원)
- .gitignore: 대용량 PDF(knowledge 104M + src/Web/uploads 157M)·*.backup 제외

근거 플랜(아카이브): ReferenceSources/.../plans/online-lora-학습-파이프라인-실행계획-byOPUS.md Phase -1.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 09:55:19 +09:00
windpacer
ab3e36680f fix: 트렌드 운전음영 500 수정 — runbands @area 타입 미지정(42P08)
- GetRunBandsAsync: @area NULL 파라미터 타입 추론 실패(42P08) → @area::text 캐스트
- from/to UTC 정규화(ToUniversalTime)로 타임존 시프트 방지
- 검증: 동일 SQL bands 정상 반환, 연속 RUN은 next 이벤트 없으면 to까지 밴드

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 19:03:20 +09:00
windpacer
647c7c090f feat: 트렌드 P2 — 알람선·운전음영·듀얼커서·자동집계(LTTB) + 집계 버그수정
- 알람선(markLine HI/LO/SP; v_instrument_range euhi/eulo + .sp) — GET /api/trend/limits
- 운전음영(markArea RUN/TRIP; event_history LEAD 구간화) — GET /api/trend/runbands
- 듀얼커서 Δ(zr 클릭→Δt·Δy·기울기), 자동집계 경로 + line sampling:'lttb'
- fix: trQuery 집계 호출이 query-string으로 가 body의 tagNames 누락→빈 차트.
  JSON body로 전송 + 집계 0행/예외 시 raw(/api/history/query) 폴백
- fix: QueryHistoryWithIntervalAsync from/to UTC 정규화(ToUniversalTime) —
  '+00:00'/Local-kind 입력이 9h 시프트되던 잠재버그 방지(프론트 'Z' 경로 영향 0)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 18:56:40 +09:00
windpacer
52ed77efac docs: 트렌드 P2 작업지시서 (LLM 구현용)
- 알람선(markLine HI/LO/SP)·운전음영(markArea RUN/TRIP)·듀얼커서Δ·자동집계/LTTB
- 슬롯 추가 절차, 기존 함수/엔드포인트/스키마, camelCase DTO 등 cold-start 자가완결

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 17:46:42 +09:00
windpacer
c7e2250bd3 feat: 트렌드 워크스페이스(ECharts) 추가 + 이벤트히스토리 sub_area 정렬
트렌드 P1 (Tab 17 "트렌드"):
- 단일 ECharts 차트 슬롯구조(trState/TR_LAYERS/trRender) — P2/P3 무중단 증분 기반
- 기능: 그룹빌더(realtime 아날로그 클릭선택)/멀티시리즈·이중축/dataZoom(좌우날짜)/
  범례표(색변경·행클릭 강조·보이는구간 통계)/보이는범위 minmax 마커/라이브 현재값/
  트립·이벤트 오버레이(/api/event-history 재사용)/100%환산/Y줌
- 백엔드: trend_group 테이블 + v_analog_points 뷰(숫자 livevalue=아날로그) +
  TrendService/TrendController(/api/trend: analog-points·groups CRUD·live) + DI
- echarts 5.5.1 로컬 번들, DTO는 [JsonPropertyName]로 camelCase 고정

이벤트히스토리 sub_area 정렬(컬럼 일치):
- event_history_table section → sub_area (DDL/인덱스/엔티티/DTO/서비스/컨트롤러/evt UI/MCP/프롬프트)
- 이력 조회 PIVOT 재작성(MAX/CASE), ft.category '계기' → 'instrument'

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 17:42:54 +09:00
windpacer
930fac2b4f docs: 트렌드 워크스페이스(ECharts) 구현 플랜 — P1~P3 단일차트 슬롯구조
- trState + TR_LAYERS + trRender 합성구조로 P2/P3를 같은 차트에 무중단 증분
- P1(그룹/dataZoom/범례강조/minmax/라이브/트립오버레이) ~ P3(LLM분석/스마트그룹/상관) 로드맵
- 설치(ECharts 로컬번들)·백엔드(trend_group/v_analog_points)·프론트 코드 스니펫 포함

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 17:34:04 +09:00
windpacer
81e2ea145a fix: realtime supervisor — OPC 장기단절 후 자동복구 (OCE 오인중지 + 연결 타임아웃)
- SuperviseAsync: catch(OperationCanceledException){break} 가 OPC SDK 연결 타임아웃
  (TaskCanceledException=OCE 하위)을 '우리 취소'로 오인해 '중지됨'으로 영구정지되던
  버그 수정 → when(ct.IsCancellationRequested) 가드, 그 외 OCE는 일반 오류처럼 재시도
- CreateSessionAsync: CancellationToken.None → 실제 토큰 전달
  (죽은 서버 상대 세션생성이 SDK 기본 OperationTimeout ~2분 블로킹하던 원인 제거)
- 1회 연결 시도 10초 타임아웃(연결토큰 + WaitAsync 하드 백스톱)
- 재시도 주기 30s → 10s (리던던트 서버 전환 시 수분 단절도 빠르게 재포착)
- 라이브 검증: Experion kill→2.5분→revive 시 재연결 순환 유지 후 수동개입 0 자동 구독복구

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 17:31:23 +09:00
windpacer
50705ab0e8 feat: P&ID 연결 엑셀 라운드트립 — id 안정 키 + 운전자 문서규칙
- ExportToExcelAsync: 17번째 컬럼 id(pid_equipment.id) 추가 (col1~16 위치 불변)
- ImportFromExcelAsync: id 우선 매칭 — id 있으면 그 행만 in-place UPDATE
  (다중경로 보존), 빈 id면 INSERT, col17 헤더가 'id'가 아닌 옛 파일은 tag_no 폴백
- PidImportResult.RowsInserted 추가 + import 로그 신규건수 포함
- 구조설명-6-2차플랜트-byPBK.xlsx 문서규칙: upsert_pid_connection(9bcba0a) 연동
  규칙으로 슬림화 (콤마=병렬 병합, 카테고리 매핑, 멱등/잠금/변경금지는 도구가 처리)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 21:34:24 +09:00
windpacer
9bcba0a317 feat: 웹UI Phase 4 완료 — CSS 분리, pane 중첩 버그 수정, app.js 제거
Phase 4 — CSS 분리:
- style.css(2,230→670줄)에서 탭별 스타일을 css/<tab>.css 8개로 분할
  (t2s:437, pid:236, pb:106, hist:100, evt:50, opcsvr:14, llmchat:501, kbadmin:109)
- 크로스탭 공유 스타일(nm-*, hist-status, dt-picker 등)은 style.css 잔류
- index.html head에 11개 CSS link 태그 (1 style.css + 8 tab + 2 lib)

app.js 제거:
- index.html에서 <script src=/js/app.js> 참조 제거
- app.js → 10줄 placeholder (이미 Phase 0-3에서 모든 로직 이전 완료)

Pane wrapper 버그 수정:
- 16개 pane 파일에서 <section class=pane id=pane-xxx> wrapper 제거
- activateTab이 innerHTML로 주입 시 중첩 section + display:none 발생
- 내용이 전혀 안 보이는 문제 해결

문서 갱신:
- AGENTS.md: Frontend Architecture 섹션 추가
- 웹UI-개선플랜-byOPUS.md: Phase 0-4 완료 상태로 갱신, 결과 검증 추가

MCP:
- server.py: timestamp 정밀도 개선 등
2026-05-24 18:47:25 +09:00
windpacer
32a442abd6 docs: 세션 작업 문서 추가 — 웹UI 개선플랜(감리정정) + 대화모음
- 웹UI-개선플랜-byQwen27B.md: app.js/index.html 분리 리팩토링 계획.
  실코드 대조 감리 결과 §0.5 추가 — 치명 결함 3건(모듈레벨 상태/최상위
  실행문 누락, 로더 기동 부재, async 파셜 배선 타이밍) 정정 및 정정 로더 포함
- 메타데이터업데이트/문서뷰어/커밋-브랜치정리 대화모음

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 16:47:27 +09:00
windpacer
2e844abf11 feat: 운전판정 고도화 — realtime stall 수정 + 교차검증 + 단위/레인지
- ExperionRealtimeService를 단일 SuperviseAsync supervisor로 재설계:
  비블로킹 부팅, PublishingStopped/KeepAliveStopped 워치독으로 silent
  stall 감지, 30초 주기 무한 재연결, flush 루프 단일화
- RealtimeServiceStatus에 LastDataAgeSeconds/Stalled 추가, History는
  Stalled 시 스냅샷 skip
- v_plant_running_state에 진공펌프(vp-) 포함 + 교차검증 4객체
  (pump_corroboration_manual, v_pump_signal_map,
  v_plant_running_state_corroborated, v_plant_running_state_agg)
  + v_instrument_range 뷰 (boot DDL)
- MetadataLoaderService에 euhi/eulo/units 메타속성 추가
- generate_status_report에 agg 조회 연동 + sample/focus 버그 수정
- plant_context.md에 펌프 prefix(p-/vp-) + 교차검증 뷰 사용법

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 16:47:20 +09:00
windpacer
7dbeb36218 fix: box-drawing GFM 변환 — 행별 자체 │ 위치 사용으로 컬럼 경계 불일치 대응 2026-05-24 13:20:33 +09:00
windpacer
762b4a1e7d fix: box-drawing table multi-line cell merge
Continuation rows (≤1 non-empty cell, e.g. wrapped cell text)
were being treated as separate data rows, shifting columns.
Now merged into the previous row by appending to the same cell.
2026-05-24 13:11:28 +09:00
windpacer
c31a2cf2e7 feat: box-drawing table to GFM pipe table conversion 2026-05-24 13:08:07 +09:00
windpacer
1a4666e339 fix: box-drawing 테이블 행 분리 문제 — 정규식 prefix만 검사하도록 수정
- BOX_RE: 전체 라인 검사 → 선두 box-drawing 문자만 확인
- 셀 내부 ' % ( ) 등 모든 문자 허용되어 행 분리 방지
- CSS 백업: .md-body pre에 font-family: var(--fm) 추가
2026-05-24 12:47:29 +09:00
windpacer
94a4b10f41 fix: 문서 탐색기 raw HTML escape + 높이 보정
- marked.js html renderer 오버라이드: 터미널 덤프에 포함된
  <div class="hidden"> 등 raw HTML이 DOM을 깨는 현상 방지
- .docs-layout height calc(100vh - 116px) → calc(100vh - 126px)
  (pane-hdr 높이 정확히 반영)
2026-05-24 12:34:32 +09:00
windpacer
24478b0ccf feat: 문서 탐색기 PDF 내보내기 (브라우저 인쇄 → PDF로 저장)
마크다운/텍스트 뷰어 툴바에 🖨 PDF 버튼 추가. 렌더된 결과(KaTeX·mermaid
SVG·코드강조·GFM 표)를 깨끗한 새 창에 담아 print() → 인쇄창에서 "PDF로 저장".

- 폐쇄망 OK: 외부 리소스 없이 /lib 로컬 CSS만 사용 (KaTeX 폰트도 로컬)
- 한글: 인쇄 본문 폰트 맑은 고딕 지정 → 윈도우에서 깨짐 없음
- 실제 텍스트(검색·복사 가능), 페이지 잘림 방지(break-inside) 적용

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 07:08:15 +09:00
windpacer
3556739a3e chore: 프론트 라이브러리 wwwroot/lib 추적 (.gitignore 예외)
Python용 lib/ 무시 규칙이 wwwroot/lib 까지 잡아 vendoring 라이브러리가
미추적이던 문제 수정. clone 시 마크다운 렌더 등이 동작하도록 추적 전환.

- 신규: marked, dompurify, highlight.js(+테마), katex(js/css/auto-render+woff2 20),
  mermaid (문서 탐색기 의존)
- 기존 누락분 동반 추적: uPlot.iife.min.js, uPlot.min.css
- .gitignore: !src/Web/wwwroot/lib/ 예외 추가

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 06:34:23 +09:00
windpacer
eb9ce9a501 docs: 웹 UI 구조 개선 플랜 추가 (HTML/JS 모놀리식 분리)
index.html(1.7K줄)·app.js(5.1K줄) 모놀리식 분리 방안 — HTML 파셜(fetch),
Razor 파셜, Vite+바닐라 ESM, 프레임워크 비교 및 점진 이관 단계.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 06:32:24 +09:00
windpacer
9cc359b803 feat: 문서 탐색기 (Tab 16) — 프로젝트 폴더 트리 탐색 + txt/md/pdf 뷰어
프로젝트 폴더 전체를 안전하게 탐색하고 문서를 보고 편집하는 웹 UI.

- DocBrowserService: 루트 자동탐색(.git/.sln), 경로이탈·심볼릭·제외디렉토리
  ·민감파일 가드, 목록/읽기/원본/쓰기/이름변경/삭제/폴더/업로드
- DocsController(/api/docs): config·tree·text·raw(공개) / 변경계열은 KB admin 토큰
- 뷰어: md(marked+DOMPurify+hljs+KaTeX+mermaid) / pdf(원본 iframe) / txt(pre) / 그 외 다운로드
- 인라인 편집(md 실시간 분할 미리보기) + 관리(새폴더/업로드/이름변경/삭제)
- 사이드바 nav 스크롤 수정(.nav overflow), 헤더 컴팩트화로 문서 영역 확보

주의: 프론트 라이브러리(marked/mermaid/katex 등)는 wwwroot/lib/(.gitignore)라
미추적 — 별도 처리 필요.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 06:32:19 +09:00
windpacer
ce72e25f0e docs: 6-1차 플랜트(P6-1) 구조설명 자료 추가
구조설명-6-1차플랜트-byPBK.xlsx — P6-1 설비 구조 설명 자료.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 06:32:02 +09:00
windpacer
87ab8adfe0 docs: 측류추출 자동운전 플랜 문서 추가
C-6111 측류추출탑 자동운전 관련 플랜·관계식·운전 주의점 문서.

- 측류추출-자동운전-플랜-byOpus.md / -컨셉회의.md(.docx)
- 측류추출-관계식.md, PGMEA_측류추출운전방식_주의점.md
- 측류추출-시간지연-적용방식.md(박스 정렬 수정)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 06:31:58 +09:00