# OPC UA Manager

원본 `Program.cs` (단일 파일)를 **ASP.NET Core Web API + 프론트엔드** 프로젝트로 분리한 버전입니다.

## 프로젝트 구조

```
OpcUaManager/
├── OpcUaManager.csproj
├── Program.cs                    ← ASP.NET Core 진입점, DI 등록
├── appsettings.json
├── init_db.sql                   ← PostgreSQL 테이블 초기화
│
├── Models/
│   └── Models.cs                 ← DTO / 도메인 모델 전체
│
├── Services/
│   ├── CertService.cs            ← X.509 인증서 생성 (pki/ 폴더 체계 유지)
│   ├── OpcSessionService.cs      ← OPC UA 세션 관리 (Singleton)
│   ├── OpcCrawlerService.cs      ← HoneywellCrawler 로직 → Service 분리
│   └── DatabaseService.cs        ← PostgreSQL 저장/조회 (SaveToDatabase 패턴 유지)
│
├── Controllers/
│   ├── CertController.cs         ← POST /api/cert/generate
│   ├── SessionController.cs      ← POST /api/session/connect|disconnect
│   ├── CrawlerController.cs      ← POST /api/crawler/start
│   └── DatabaseController.cs     ← POST /api/database/write|query|test
│
└── wwwroot/
    └── index.html                ← 프론트엔드 (단일 HTML, 백엔드 API 연결)
```

## 원본 코드와의 대응 관계

| 원본 코드 위치 | 분리된 위치 |
|---|---|
| `Directory.CreateDirectory("pki/...")` | `CertService.EnsurePkiDirectories()` |
| `new X509Certificate2(pfxPath, ...)` | `CertService.LoadPfx()` |
| `ApplicationConfiguration { ... }` | `OpcSessionService.ConnectAsync()` |
| `DiscoveryClient → Session.Create` | `OpcSessionService.ConnectAsync()` |
| `HoneywellCrawler.BrowseRecursiveAsync` | `OpcCrawlerService.CrawlAsync()` |
| `HoneywellCrawler.SaveToCsv` | `OpcCrawlerService.SaveToCsvAsync()` |
| `SaveToDatabase(tagName, val, status)` | `DatabaseService.SaveToDatabaseAsync()` |
| `for (int i = 0; i < 5; i++) { ... }` | `DatabaseService.WriteLoopAsync()` |

**원본 인증서 체계 유지 항목:**
- `pki/own/certs/`, `pki/trusted/certs/`, `pki/issuers/certs/`, `pki/rejected/certs/` 폴더 구조
- `X509KeyStorageFlags.Exportable | MachineKeySet`
- `AutoAcceptUntrustedCertificates = true`, `AddAppCertToTrustedStore = true`
- OPC UA SAN(Subject Alternative Name) 에 `ApplicationUri` 포함 (필수 요구사항)

## 실행 방법

### 1. PostgreSQL 초기화
```bash
createdb opcdb
psql -U postgres -d opcdb -f init_db.sql
```

### 2. 백엔드 실행
```bash
cd OpcUaManager
dotnet restore
dotnet run
# → http://localhost:5000
# → Swagger: http://localhost:5000/swagger
```

### 3. 프론트엔드 접속
브라우저에서 `http://localhost:5000` 접속
(또는 `wwwroot/index.html` 을 별도 Live Server로 열고 API URL을 `http://localhost:5000` 으로 설정)

## API 엔드포인트 요약

```
POST /api/cert/generate          인증서 생성
GET  /api/cert/list              PFX 목록 조회
GET  /api/cert/download/{name}   PFX 다운로드

POST /api/session/connect        OPC 연결
POST /api/session/disconnect     OPC 연결 해제
GET  /api/session/status         세션 상태

POST /api/crawler/start          노드 탐사 시작
GET  /api/crawler/csv            CSV 다운로드

POST /api/database/test          DB 연결 테스트
POST /api/database/init          테이블 초기화
POST /api/database/write         OPC 읽기 + DB 저장 (N회)
POST /api/database/query         최근 레코드 조회
```

## 의존 패키지

```xml
OPCFoundation.NetStandard.Opc.Ua.Client  1.5.x
Npgsql                                    8.0.x
Swashbuckle.AspNetCore                   6.6.x
```
