Major project initialization and feature implementation: **Core Features:** - OPC UA client for Honeywell Experion HS R530 integration - Real-time data streaming and history data retrieval - Text-to-SQL query engine with TimeScaleDB - JSON-based node configuration system - SQLite database with migration support **Architecture:** - Clean architecture with Domain, Application, Infrastructure layers - ASP.NET Core Web API frontend - Web UI with real-time visualization - PKI-based OPC UA authentication (TLS) **Infrastructure Components:** - ExperionOpcClient: OPC UA connection management - ExperionRealtimeService: Real-time data streaming - ExperionHistoryService: Historical data queries - TextToSqlService: Natural language to SQL queries - SqlValidator: SQL injection prevention **Database:** - TimescaleDB integration (recommended) or SQLite fallback - Entity Framework Core with Extenstion methods - OPCTag, KeyValue tables for data storage **Security:** - Certificate-based OPC UA endpoint security - SSL/TLS encryption for database connections - Output param binding injection prevention **Testing:** - Unit tests for TextToSqlService and SqlValidator - Integration tests for Korean time range extraction See REVIEW_REQUEST.md for detailed code review information.
102 lines
3.2 KiB
Markdown
102 lines
3.2 KiB
Markdown
# GLM-4.7-Flash 코드 작업 규칙 (ExperionCrawler)
|
|
|
|
## 필수 준수 사항
|
|
|
|
### 작업 전
|
|
- 반드시 `task_state.md`를 먼저 읽어 진행 상태 파악
|
|
- 파일 수정 전 반드시 `read_file`로 전체 내용 확인 후 수정
|
|
|
|
### 코드 수정 원칙
|
|
- 요청된 범위만 수정 — 관련 없는 코드 리팩토링 금지
|
|
- 빌드 검증: 각 파일 수정 후 `dotnet build src/Web/ExperionCrawler.csproj --no-restore -v q` 실행
|
|
- 빌드 실패 시 즉시 원인 수정 후 재빌드, 다음 항목으로 넘어가지 않음
|
|
|
|
### issues.md 작성 형식
|
|
```
|
|
| # | 파일 | 심각도 | 분류 | 내용 | 상태 |
|
|
|---|------|--------|------|------|------|
|
|
| 1 | src/... | HIGH/MED/LOW | bug/perf/quality/security | 설명 | pending/fixed |
|
|
```
|
|
심각도 기준:
|
|
- HIGH: 런타임 예외, 데이터 손실, 보안 취약점
|
|
- MED: 성능 저하, 잘못된 동작, 예외 미처리
|
|
- LOW: 코드 품질, 불필요한 코드, 명명 불일치
|
|
|
|
### 클로드 검수를 위한 커밋 규칙
|
|
- 각 이슈 수정 완료 시: `git add -p` 후 이슈 번호 포함 커밋
|
|
예: `fix(#3): ExperionDbContext null 참조 예외 방어 처리`
|
|
- 전체 완료 후 `REVIEW_REQUEST.md` 생성하여 검수 요청
|
|
|
|
### MCP 도구 활용
|
|
- `search_codebase`: 관련 코드 패턴 검색에 적극 활용
|
|
- `ask_iiot_llm`: IIoT/OPC UA 도메인 판단이 필요할 때 사용
|
|
|
|
---
|
|
|
|
## [CRITICAL] ASP.NET Core 컨트롤러 JSON 직렬화 규칙
|
|
|
|
### 배경 (반드시 숙지)
|
|
|
|
`src/Web/Program.cs`에 다음 설정이 있다:
|
|
```csharp
|
|
opt.JsonSerializerOptions.PropertyNamingPolicy = null; // PascalCase 그대로 직렬화
|
|
```
|
|
|
|
이로 인해 C# 속성명이 **그대로** JSON 키가 된다.
|
|
프론트엔드(`app.js`)는 **모든 JSON 필드를 camelCase**로 접근하므로,
|
|
PascalCase 키가 오면 **모든 값이 `undefined`** 가 된다.
|
|
|
|
### 금지 패턴 (절대 사용 금지)
|
|
|
|
```csharp
|
|
// ❌ shorthand 익명 객체 — C# 속성명(PascalCase)이 JSON 키로 그대로 사용됨
|
|
return Ok(new { x.Id, x.TagName, x.NodeId, x.LiveValue });
|
|
|
|
// ❌ typed 객체를 Ok()에 직접 전달 — PascalCase 직렬화됨
|
|
return Ok(result);
|
|
return Ok(new MyDto { Id = 1, TagName = "abc" });
|
|
```
|
|
|
|
### 올바른 패턴 (항상 명시적 camelCase 매핑)
|
|
|
|
```csharp
|
|
// ✅ 항상 명시적으로 소문자 키 지정
|
|
return Ok(new
|
|
{
|
|
id = x.Id,
|
|
tagName = x.TagName,
|
|
nodeId = x.NodeId,
|
|
liveValue = x.LiveValue,
|
|
timestamp = x.Timestamp
|
|
});
|
|
|
|
// ✅ 컬렉션 포함 응답
|
|
return Ok(new
|
|
{
|
|
total = r.Total,
|
|
items = r.Items.Select(x => new
|
|
{
|
|
id = x.Id,
|
|
tagName = x.TagName,
|
|
nodeId = x.NodeId
|
|
})
|
|
});
|
|
```
|
|
|
|
### C# 예약어 처리
|
|
|
|
`class`는 C# 예약어이므로 `@class`를 사용한다. System.Text.Json이 `"class"`로 정상 직렬화한다:
|
|
|
|
```csharp
|
|
// ✅ @class → JSON "class"
|
|
return Ok(new { id = x.Id, @class = x.Class, name = x.Name });
|
|
```
|
|
|
|
### 점검 체크리스트
|
|
|
|
컨트롤러에서 `Ok(...)` 또는 `return` 사용 시:
|
|
- [ ] 익명 객체의 모든 키가 소문자(camelCase)인가?
|
|
- [ ] `new { x.SomeProp }` 형태(shorthand)가 없는가?
|
|
- [ ] typed record/class를 그대로 반환하지 않는가?
|
|
- [ ] C# 예약어(`class`, `string` 등)에 `@` 접두사를 붙였는가?
|