opencode 로 바꾸고 작업전 커밋
This commit is contained in:
443
plans/enum-metadata-optimize-coding-plan.md
Normal file
443
plans/enum-metadata-optimize-coding-plan.md
Normal file
@@ -0,0 +1,443 @@
|
||||
# Enum Metadata 최적화 - 코딩 계획
|
||||
|
||||
> 작성일: 2026-05-08
|
||||
> 상태: 진행 중
|
||||
> 기반 문서: [`plans/enum-metadata-optimization.md`](plans/enum-metadata-optimization.md)
|
||||
> 목적: `state0~7descriptor` 제거, `desc`/`area`만 유지, pv 값 파싱 로직 추가
|
||||
|
||||
---
|
||||
|
||||
## 작업 Todo 리스트
|
||||
|
||||
각 단계는 독립적으로 완료 여부를 추적할 수 있다. 체크박스를 사용하여 진행 상황을 기록한다.
|
||||
|
||||
- [ ] STEP 1 — 백업: 수정 대상 파일들을 `.rooBackup/`에 백업
|
||||
- [ ] STEP 2 — `MetadataLoaderService.cs`: `MetaAttributes` 배열에서 state0~7descriptor 제거
|
||||
- [ ] STEP 3 — `MetadataLoaderService.cs`: 빌드 검증
|
||||
- [ ] STEP 4 — `ExperionDbContext.cs`: `v_tag_summary` 뷰에서 state descriptor JOIN 제거
|
||||
- [ ] STEP 5 — `ExperionDbContext.cs`: 빌드 검증
|
||||
- [ ] STEP 6 — `app.js`: pv 값 파싱 헬퍼 함수 `parseEnumPv()` 추가
|
||||
- [ ] STEP 7 — `app.js`: pv 값 표시 관련 코드 모두 `parseEnumPv()` 적용
|
||||
- [ ] STEP 8 — End-to-End 검증: 전체 빌드 + UI 테스트
|
||||
- [ ] STEP 9 — git 커밋 및 정리
|
||||
|
||||
---
|
||||
|
||||
## 변경 대상 파일 목록
|
||||
|
||||
| # | 파일 | 변경 내용 | 영향 범위 |
|
||||
|---|------|-----------|-----------|
|
||||
| 1 | `src/Infrastructure/OpcUa/MetadataLoaderService.cs` | `MetaAttributes` 배열 수정 | 메타데이터 로딩 |
|
||||
| 2 | `src/Infrastructure/Database/ExperionDbContext.cs` | `v_tag_summary` 뷰 단순화 | DB 뷰 |
|
||||
| 3 | `src/Web/wwwroot/js/app.js` | pv 파싱 헬퍼 + 표시 로직 변경 | 프론트엔드 UI |
|
||||
|
||||
---
|
||||
|
||||
## 각 단계 상세 계획
|
||||
|
||||
---
|
||||
|
||||
### STEP 1 — 백업: 수정 대상 파일들을 `.rooBackup/`에 백업
|
||||
|
||||
**목적**: 수정 전 원본 보존. 실패 시 복원 가능.
|
||||
|
||||
**실행 명령**:
|
||||
```bash
|
||||
TIMESTAMP=$(date +%Y%m%d%H%M)
|
||||
mkdir -p .rooBackup/enum-opt-$TIMESTAMP/src/Infrastructure/OpcUa
|
||||
mkdir -p .rooBackup/enum-opt-$TIMESTAMP/src/Infrastructure/Database
|
||||
mkdir -p .rooBackup/enum-opt-$TIMESTAMP/src/Web/wwwroot/js
|
||||
|
||||
cp src/Infrastructure/OpcUa/MetadataLoaderService.cs .rooBackup/enum-opt-$TIMESTAMP/src/Infrastructure/OpcUa/
|
||||
cp src/Infrastructure/Database/ExperionDbContext.cs .rooBackup/enum-opt-$TIMESTAMP/src/Infrastructure/Database/
|
||||
cp src/Web/wwwroot/js/app.js .rooBackup/enum-opt-$TIMESTAMP/src/Web/wwwroot/js/
|
||||
```
|
||||
|
||||
**검증 기준**:
|
||||
- [ ] `.rooBackup/enum-opt-YYYYMMDDHHMM/` 폴더가 생성되고 3개 파일이 복사됨
|
||||
- [ ] 원본 파일과 백업 파일의 체크섬이 일치함 (`md5sum` 비교)
|
||||
|
||||
**enum-metadata-optimization.md 규칙 매핑**:
|
||||
- 섹션 3.3: 수정이 필요한 코드 — `MetadataLoaderService.cs`, `ExperionDbContext.cs`, `app.js`
|
||||
|
||||
---
|
||||
|
||||
### STEP 2 — `MetadataLoaderService.cs`: `MetaAttributes` 배열에서 state0~7descriptor 제거
|
||||
|
||||
**파일**: [`MetadataLoaderService.cs`](src/Infrastructure/OpcUa/MetadataLoaderService.cs:20)
|
||||
**변경 위치**: 20~26줄 (`MetaAttributes` 배열 정의)
|
||||
|
||||
**변경 전 코드**:
|
||||
```csharp
|
||||
// 로드할 메타데이터 속성 목록
|
||||
private static readonly string[] MetaAttributes =
|
||||
{
|
||||
"desc", "area",
|
||||
"state0descriptor", "state1descriptor", "state2descriptor",
|
||||
"state3descriptor", "state4descriptor", "state5descriptor",
|
||||
"state6descriptor", "state7descriptor"
|
||||
};
|
||||
```
|
||||
|
||||
**변경 후 코드**:
|
||||
```csharp
|
||||
// 로드할 메타데이터 속성 목록 (state0~7descriptor 제거 — pv 값에서 파싱)
|
||||
private static readonly string[] MetaAttributes =
|
||||
{
|
||||
"desc", "area"
|
||||
};
|
||||
```
|
||||
|
||||
**diff**:
|
||||
```diff
|
||||
-// 로드할 메타데이터 속성 목록
|
||||
+// 로드할 메타데이터 속성 목록 (state0~7descriptor 제거 — pv 값에서 파싱)
|
||||
private static readonly string[] MetaAttributes =
|
||||
{
|
||||
- "desc", "area",
|
||||
- "state0descriptor", "state1descriptor", "state2descriptor",
|
||||
- "state3descriptor", "state4descriptor", "state5descriptor",
|
||||
- "state6descriptor", "state7descriptor"
|
||||
+ "desc", "area"
|
||||
};
|
||||
```
|
||||
|
||||
**변경 이유**:
|
||||
- pv 값 `{코드 | DisplayName | }`에 이미 state descriptor 정보가 포함되어 있으므로 중복 저장 제거
|
||||
- OPC UA 읽기 요청 80% 감소 (10개 속성 → 2개 속성)
|
||||
- tag_metadata 행 80% 감소 (태그당 10행 → 2행)
|
||||
|
||||
**영향 분석**:
|
||||
- `LoadMetadataAsync()` 메서드: `MetaAttributes.Contains(n.Name)`으로 `node_map_master`에서 필터링하므로 state descriptor 노드는 더 이상 조회되지 않음
|
||||
- `ReadTagsAsync()`: 8개 menos의 nodeId로 배치 읽기 → 네트워크 트래픽 감소
|
||||
- UPSERT 쿼리: 8개 menos의 행 삽입 → DB 부하 감소
|
||||
|
||||
**검증 기준**:
|
||||
- [ ] `MetaAttributes` 배열이 `["desc", "area"]` 두 개만 포함
|
||||
- [ ] 컴파일 오류 없음
|
||||
- [ ] `LoadMetadataAsync()` 메서드의 로직 변경 없이 배열 변경만으로 동작
|
||||
|
||||
**enum-metadata-optimization.md 규칙 매핑**:
|
||||
- 섹션 3.2: desc, area만 저장
|
||||
- 섹션 3.3: `MetadataLoaderService.cs` 수정 — `MetaAttributes` 배열에서 state0~7descriptor 제거
|
||||
- 섹션 4.2: tag_metadata 저장 속성 — desc, area 만
|
||||
|
||||
---
|
||||
|
||||
### STEP 3 — `MetadataLoaderService.cs` 변경 후 빌드 검증
|
||||
|
||||
**목적**: STEP 2 변경이 컴파일 오류 없이 통과하는지 확인
|
||||
|
||||
**실행 명령**:
|
||||
```bash
|
||||
dotnet build src/Web/ExperionCrawler.csproj --no-restore -v q
|
||||
```
|
||||
|
||||
**검증 기준**:
|
||||
- [ ] 빌드 성공 (exit code 0)
|
||||
- [ ] 경고 없음 (또는 기존 경고만)
|
||||
- [ ] `MetaAttributes` 배열 참조하는 다른 코드가 없는지 확인
|
||||
|
||||
**실패 시 대응**:
|
||||
- 컴파일 오류가 발생하면 오류 메시지를 읽고 원인 분석
|
||||
- `MetaAttributes` 길이에 의존하는 코드가 있으면 해당 코드도 수정
|
||||
|
||||
---
|
||||
|
||||
### STEP 4 — `ExperionDbContext.cs`: `v_tag_summary` 뷰에서 state descriptor JOIN 제거
|
||||
|
||||
**파일**: [`ExperionDbContext.cs`](src/Infrastructure/Database/ExperionDbContext.cs:302)
|
||||
**변경 위치**: 302~330줄 (`v_tag_summary` 뷰 생성 SQL)
|
||||
|
||||
**변경 전 코드** (315~329줄):
|
||||
```sql
|
||||
desc_md.value AS description,
|
||||
area_md.value AS area,
|
||||
s0d_md.value AS state0_descriptor,
|
||||
s1d_md.value AS state1_descriptor,
|
||||
s2d_md.value AS state2_descriptor
|
||||
FROM (SELECT DISTINCT split_part(tagname, '.', 1) AS base_tag FROM realtime_table) rt_base
|
||||
LEFT JOIN realtime_table pv_rt ON pv_rt.tagname = rt_base.base_tag || '.pv'
|
||||
LEFT JOIN realtime_table sp_rt ON sp_rt.tagname = rt_base.base_tag || '.sp'
|
||||
LEFT JOIN realtime_table op_rt ON op_rt.tagname = rt_base.base_tag || '.op'
|
||||
LEFT JOIN realtime_table instate0_rt ON instate0_rt.tagname = rt_base.base_tag || '.instate0'
|
||||
LEFT JOIN realtime_table instate1_rt ON instate1_rt.tagname = rt_base.base_tag || '.instate1'
|
||||
LEFT JOIN realtime_table instate2_rt ON instate2_rt.tagname = rt_base.base_tag || '.instate2'
|
||||
LEFT JOIN tag_metadata desc_md ON desc_md.base_tag = rt_base.base_tag AND desc_md.attribute = 'desc'
|
||||
LEFT JOIN tag_metadata area_md ON area_md.base_tag = rt_base.base_tag AND area_md.attribute = 'area'
|
||||
LEFT JOIN tag_metadata s0d_md ON s0d_md.base_tag = rt_base.base_tag AND s0d_md.attribute = 'state0descriptor'
|
||||
LEFT JOIN tag_metadata s1d_md ON s1d_md.base_tag = rt_base.base_tag AND s1d_md.attribute = 'state1descriptor'
|
||||
LEFT JOIN tag_metadata s2d_md ON s2d_md.base_tag = rt_base.base_tag AND s2d_md.attribute = 'state2descriptor'
|
||||
```
|
||||
|
||||
**변경 후 코드**:
|
||||
```sql
|
||||
desc_md.value AS description,
|
||||
area_md.value AS area
|
||||
FROM (SELECT DISTINCT split_part(tagname, '.', 1) AS base_tag FROM realtime_table) rt_base
|
||||
LEFT JOIN realtime_table pv_rt ON pv_rt.tagname = rt_base.base_tag || '.pv'
|
||||
LEFT JOIN realtime_table sp_rt ON sp_rt.tagname = rt_base.base_tag || '.sp'
|
||||
LEFT JOIN realtime_table op_rt ON op_rt.tagname = rt_base.base_tag || '.op'
|
||||
LEFT JOIN realtime_table instate0_rt ON instate0_rt.tagname = rt_base.base_tag || '.instate0'
|
||||
LEFT JOIN realtime_table instate1_rt ON instate1_rt.tagname = rt_base.base_tag || '.instate1'
|
||||
LEFT JOIN realtime_table instate2_rt ON instate2_rt.tagname = rt_base.base_tag || '.instate2'
|
||||
LEFT JOIN tag_metadata desc_md ON desc_md.base_tag = rt_base.base_tag AND desc_md.attribute = 'desc'
|
||||
LEFT JOIN tag_metadata area_md ON area_md.base_tag = rt_base.base_tag AND area_md.attribute = 'area'
|
||||
```
|
||||
|
||||
**diff**:
|
||||
```diff
|
||||
desc_md.value AS description,
|
||||
area_md.value AS area,
|
||||
- s0d_md.value AS state0_descriptor,
|
||||
- s1d_md.value AS state1_descriptor,
|
||||
- s2d_md.value AS state2_descriptor
|
||||
+ area_md.value AS area
|
||||
FROM (SELECT DISTINCT split_part(tagname, '.', 1) AS base_tag FROM realtime_table) rt_base
|
||||
LEFT JOIN realtime_table pv_rt ON pv_rt.tagname = rt_base.base_tag || '.pv'
|
||||
LEFT JOIN realtime_table sp_rt ON sp_rt.tagname = rt_base.base_tag || '.sp'
|
||||
LEFT JOIN realtime_table op_rt ON op_rt.tagname = rt_base.base_tag || '.op'
|
||||
LEFT JOIN realtime_table instate0_rt ON instate0_rt.tagname = rt_base.base_tag || '.instate0'
|
||||
LEFT JOIN realtime_table instate1_rt ON instate1_rt.tagname = rt_base.base_tag || '.instate1'
|
||||
LEFT JOIN realtime_table instate2_rt ON instate2_rt.tagname = rt_base.base_tag || '.instate2'
|
||||
LEFT JOIN tag_metadata desc_md ON desc_md.base_tag = rt_base.base_tag AND desc_md.attribute = 'desc'
|
||||
LEFT JOIN tag_metadata area_md ON area_md.base_tag = rt_base.base_tag AND area_md.attribute = 'area'
|
||||
- LEFT JOIN tag_metadata s0d_md ON s0d_md.base_tag = rt_base.base_tag AND s0d_md.attribute = 'state0descriptor'
|
||||
- LEFT JOIN tag_metadata s1d_md ON s1d_md.base_tag = rt_base.base_tag AND s1d_md.attribute = 'state1descriptor'
|
||||
- LEFT JOIN tag_metadata s2d_md ON s2d_md.base_tag = rt_base.base_tag AND s2d_md.attribute = 'state2descriptor'
|
||||
""");
|
||||
```
|
||||
|
||||
**변경 이유**:
|
||||
- state0~2descriptor가 더 이상 tag_metadata에 저장되지 않으므로 JOIN 제거
|
||||
- 뷰 조회 성능 향상 (3개 LEFT JOIN 제거)
|
||||
|
||||
**영향 분석**:
|
||||
- `v_tag_summary` 뷰를 조회하는 코드가 `state0_descriptor`, `state1_descriptor`, `state2_descriptor` 컬럼을 참조하면 NULL 반환
|
||||
- 이 뷰를 사용하는 곳이 있는지 검색 필요 (현재는 DB 초기화 시에만 사용)
|
||||
|
||||
**검증 기준**:
|
||||
- [ ] `v_tag_summary` 뷰 SQL에서 state descriptor 관련 JOIN 3개 제거됨
|
||||
- [ ] `area_md.value AS area` 뒤 쉼표 제거 (마지막 SELECT 컬럼)
|
||||
- [ ] SQL 문법 오류 없음
|
||||
|
||||
**enum-metadata-optimization.md 규칙 매핑**:
|
||||
- 섹션 3.3: `ExperionDbContext.cs` 수정 — v_tag_summary 뷰에서 state descriptor JOIN 제거
|
||||
|
||||
---
|
||||
|
||||
### STEP 5 — `ExperionDbContext.cs` 변경 후 빌드 검증
|
||||
|
||||
**목적**: STEP 4 변경이 컴파일 오류 없이 통과하는지 확인
|
||||
|
||||
**실행 명령**:
|
||||
```bash
|
||||
dotnet build src/Web/ExperionCrawler.csproj --no-restore -v q
|
||||
```
|
||||
|
||||
**검증 기준**:
|
||||
- [ ] 빌드 성공 (exit code 0)
|
||||
- [ ] SQL 문자열 문법 오류 없음 (raw string literal 안에서 SQL 구문 확인)
|
||||
- [ ] 쉼표 누락/과잉 없음
|
||||
|
||||
**실패 시 대응**:
|
||||
- SQL 구문 오류가 발생하면 SELECT 컬럼 목록의 쉼표 확인
|
||||
- `area_md.value AS area`가 마지막 컬럼이므로 쉼표 제거했는지 확인
|
||||
|
||||
---
|
||||
|
||||
### STEP 6 — `app.js`: pv 값 파싱 헬퍼 함수 `parseEnumPv()` 추가
|
||||
|
||||
**파일**: [`app.js`](src/Web/wwwroot/js/app.js:2126)
|
||||
**삽입 위치**: `fmtVal()` 함수 바로 아래 (2132줄 이후)
|
||||
|
||||
**추가할 코드**:
|
||||
```javascript
|
||||
/**
|
||||
* OPC UA EnumValueType pv 값 파싱
|
||||
* "{0 | L-STpv | }" → "L-STpv"
|
||||
* "{0 | MID | }" → "MID"
|
||||
* 일반 값은 그대로 반환
|
||||
*/
|
||||
function parseEnumPv(v) {
|
||||
if (v == null) return v;
|
||||
const s = String(v);
|
||||
// "{코드 | DisplayName | }" 패턴 매칭
|
||||
const m = s.match(/^\{\s*\d+\s*\|\s*([^|]+?)\s*\|\s*\}$/);
|
||||
return m ? m[1].trim() : s;
|
||||
}
|
||||
```
|
||||
|
||||
**삽입 위치 상세**:
|
||||
- 2132줄 (`}` — `fmtVal` 함수 종료) 바로 다음에 삽입
|
||||
- 기존 `fmtVal` 함수는 변경하지 않음
|
||||
|
||||
**기능 설명**:
|
||||
- 입력: pv 값 문자열 (예: `"{0 | L-STpv | }"`)
|
||||
- 출력: DisplayName 부분만 (예: `"L-STpv"`)
|
||||
- EnumValueType 형식이 아닌 일반 값은 그대로 반환
|
||||
|
||||
**정규식 설명**:
|
||||
- `^\{` — `{`로 시작
|
||||
- `\s*\d+\s*` — 정수 코드 (공백 허용)
|
||||
- `\|\s*` — `|` 구분자
|
||||
- `([^|]+?)` — DisplayName (첫 번째 캡처 그룹)
|
||||
- `\s*\|\s*\}$` — `| }`로 끝남
|
||||
|
||||
**검증 기준**:
|
||||
- [ ] `parseEnumPv("{0 | L-STpv | }")` → `"L-STpv"` 반환
|
||||
- [ ] `parseEnumPv("{0 | MID | }")` → `"MID"` 반환
|
||||
- [ ] `parseEnumPv("123.45")` → `"123.45"` 반환 (변경 없음)
|
||||
- [ ] `parseEnumPv(null)` → `null` 반환
|
||||
- [ ] 브라우저 콘솔에서 수동 테스트 가능
|
||||
|
||||
**enum-metadata-optimization.md 규칙 매핑**:
|
||||
- 섹션 3.2: pv 값 파싱 방법 — `{코드 | 이름 | }`에서 DisplayName 추출
|
||||
- 섹션 3.3: `app.js` — pv 값 표시 시 파싱 로직 추가
|
||||
|
||||
---
|
||||
|
||||
### STEP 7 — `app.js`: pv 값 표시 관련 코드 모두 `parseEnumPv()` 적용
|
||||
|
||||
**파일**: [`app.js`](src/Web/wwwroot/js/app.js:633)
|
||||
**변경 위치**: `pbRender()` 함수 내 liveValue 표시 부분 (633줄)
|
||||
|
||||
**변경 전 코드** (633줄):
|
||||
```javascript
|
||||
<td class="val">${p?.liveValue != null ? esc(String(fmtVal(p.liveValue))) : '<span style="color:var(--t3)">—</span>'}</td>
|
||||
```
|
||||
|
||||
**변경 후 코드**:
|
||||
```javascript
|
||||
<td class="val">${p?.liveValue != null ? esc(String(fmtVal(parseEnumPv(p.liveValue)))) : '<span style="color:var(--t3)">—</span>'}</td>
|
||||
```
|
||||
|
||||
**diff**:
|
||||
```diff
|
||||
-<td class="val">${p?.liveValue != null ? esc(String(fmtVal(p.liveValue))) : '<span style="color:var(--t3)">—</span>'}</td>
|
||||
+<td class="val">${p?.liveValue != null ? esc(String(fmtVal(parseEnumPv(p.liveValue)))) : '<span style="color:var(--t3)">—</span>'}</td>
|
||||
```
|
||||
|
||||
**변경 이유**:
|
||||
- `liveValue`가 EnumValueType 형식(`{0 | L-STpv | }`)이면 DisplayName만 표시
|
||||
- 일반 숫자 값은 `parseEnumPv()`가 그대로 반환하므로 영향 없음
|
||||
- `fmtVal()`은 숫자 포맷팅만 담당, `parseEnumPv()`는 EnumValueType 파싱만 담당 (단일 책임)
|
||||
|
||||
**다른 적용 위치 확인**:
|
||||
- `fmtVal()`을 사용하는 모든 곳을 검색하여 pv 값 표시에 사용되는 곳에 `parseEnumPv()` 적용
|
||||
- `t2sRenderTable()` (1606줄): `fmtVal(val)` — 시계열 데이터이므로 변경 불필요 (아날로그 값 중심)
|
||||
- `histQuery()` 결과 렌더링 (956줄): `fmtVal(raw)` — 이력 데이터이므로 변경 불필요
|
||||
|
||||
**검증 기준**:
|
||||
- [ ] 포인트빌더 테이블에서 xv-3202.pv 값이 `"{0 | L-MID | }"` 대신 `"L-MID"`로 표시됨
|
||||
- [ ] 일반 숫자 값(예: ficq-6113.pv = "123.45")은 여전히 `"123.45"`로 표시됨
|
||||
- [ ] 브라우저 콘솔에서 JS 오류 없음
|
||||
|
||||
**enum-metadata-optimization.md 규칙 매핑**:
|
||||
- 섹션 3.2: 프론트엔드에서 pv 값 표시 시 `{`와 `|`를 파싱하여 상태 이름만 표시
|
||||
|
||||
---
|
||||
|
||||
### STEP 8 — End-to-End 검증: 전체 빌드 + UI 테스트
|
||||
|
||||
**목적**: 모든 변경 사항이 함께 동작하는지 최종 확인
|
||||
|
||||
**실행 명령**:
|
||||
```bash
|
||||
# 1. 전체 솔루션 빌드
|
||||
dotnet build ExperionCrawler.sln -v q
|
||||
|
||||
# 2. 애플리케이션 시작
|
||||
dotnet run --project src/Web/ExperionCrawler.csproj
|
||||
```
|
||||
|
||||
**검증 체크리스트**:
|
||||
|
||||
#### 빌드 검증
|
||||
- [ ] `dotnet build` 성공 (exit code 0)
|
||||
- [ ] 컴파일 오류 0개
|
||||
- [ ] 경고 수 증가 없음
|
||||
|
||||
#### 백엔드 검증
|
||||
- [ ] 애플리케이션 시작 시 DB 초기화 성공
|
||||
- [ ] `v_tag_summary` 뷰 생성 성공 (state descriptor JOIN 없음)
|
||||
- [ ] 메타데이터 로드 시 `desc`, `area`만 조회됨 (로그 확인)
|
||||
- [ ] `tag_metadata` 테이블에 state0~7descriptor 행 없음
|
||||
|
||||
#### 프론트엔드 검증
|
||||
- [ ] 브라우저 콘솔 JS 오류 없음
|
||||
- [ ] 포인트빌더 테이블에서 digital 태그 pv 값이 DisplayName만 표시됨
|
||||
- 예: `xv-3202.pv` → `"L-MID"` (기존: `"{0 | L-MID | }"`)
|
||||
- [ ] 아날로그 태그 pv 값은 정상 표시됨
|
||||
- 예: `ficq-6113.pv` → `"123.45"`
|
||||
- [ ] 메타데이터 조회 시 `desc`, `area`만 반환됨
|
||||
|
||||
#### 성능 검증
|
||||
- [ ] 메타데이터 로드 시간 감소 확인 (기존 대비)
|
||||
- [ ] `tag_metadata` 테이블 행 수 감소 확인 (기존 10행/태그 → 2행/태그)
|
||||
|
||||
**enum-metadata-optimization.md 규칙 매핑**:
|
||||
- 섹션 4.3: 기대 효과 — OPC UA 읽기 요청 80% 감소, tag_metadata 행 80% 감소
|
||||
- 섹션 4.4: 다음 단계 — 메타데이터 로드 테스트 실행
|
||||
|
||||
---
|
||||
|
||||
### STEP 9 — git 커밋 및 정리
|
||||
|
||||
**목적**: 변경 사항을 커밋하고 작업 기록 남기기
|
||||
|
||||
**커밋 전략**: 각 파일 변경을 별도 커밋으로 관리
|
||||
|
||||
```bash
|
||||
# 1. MetadataLoaderService.cs 커밋
|
||||
git add src/Infrastructure/OpcUa/MetadataLoaderService.cs
|
||||
git commit -m "feat: MetaAttributes에서 state0~7descriptor 제거 (pv 값 파싱으로 대체)"
|
||||
|
||||
# 2. ExperionDbContext.cs 커밋
|
||||
git add src/Infrastructure/Database/ExperionDbContext.cs
|
||||
git commit -m "feat: v_tag_summary 뷰에서 state descriptor JOIN 제거"
|
||||
|
||||
# 3. app.js 커밋
|
||||
git add src/Web/wwwroot/js/app.js
|
||||
git commit -m "feat: pv 값 파싱 헬퍼 parseEnumPv() 추가, 포인트빌더 테이블 적용"
|
||||
|
||||
# 4. 계획 문서 커밋
|
||||
git add plans/enum-metadata-optimize-coding-plan.md
|
||||
git commit -m "docs: enum metadata 최적화 코딩 계획 작성"
|
||||
```
|
||||
|
||||
**검증 기준**:
|
||||
- [ ] 각 커밋 메시지가 변경 내용을 명확히 설명함
|
||||
- [ ] `git log`에서 커밋 순서가 논리적임
|
||||
- [ ] `.rooBackup/` 폴더에 gitignore 적용되어 있음 (백업 파일 커밋 제외)
|
||||
|
||||
---
|
||||
|
||||
## 부록: rollback 절차
|
||||
|
||||
작업 중 문제가 발생하면 백업 파일로 복원:
|
||||
|
||||
```bash
|
||||
TIMESTAMP=$(ls -d .rooBackup/enum-opt-* | tail -1 | xargs basename)
|
||||
cp .rooBackup/$TIMESTAMP/src/Infrastructure/OpcUa/MetadataLoaderService.cs src/Infrastructure/OpcUa/
|
||||
cp .rooBackup/$TIMESTAMP/src/Infrastructure/Database/ExperionDbContext.cs src/Infrastructure/Database/
|
||||
cp .rooBackup/$TIMESTAMP/src/Web/wwwroot/js/app.js src/Web/wwwroot/js/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 검증 요약
|
||||
|
||||
각 STEP의 검증 기준을 한눈에 확인:
|
||||
|
||||
| STEP | 파일 | 핵심 검증 항목 |
|
||||
|------|------|----------------|
|
||||
| 1 | — | 백업 파일 3개 생성됨 |
|
||||
| 2 | MetadataLoaderService.cs | `MetaAttributes` = `["desc", "area"]` |
|
||||
| 3 | — | 빌드 성공 |
|
||||
| 4 | ExperionDbContext.cs | state descriptor JOIN 3개 제거됨 |
|
||||
| 5 | — | 빌드 성공 |
|
||||
| 6 | app.js | `parseEnumPv()` 함수 추가됨 |
|
||||
| 7 | app.js | `pbRender()`에서 `parseEnumPv()` 적용됨 |
|
||||
| 8 | 전체 | End-to-End 테스트 통과 |
|
||||
| 9 | — | git 커밋 완료 |
|
||||
Reference in New Issue
Block a user