리크 테스트 gui
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
13 KiB

# 로그인 프로시저 연동 및 검사 결과 저장 개편 사양서
본 문서는 로그인 검증 시 특정 저장 프로시저를 연동하고, 검사 완료 결과를 신규 정의된 `dbo.EOL` 테이블 스키마 및 16컬럼 로컬 CSV 구조에 맞추어 통합 저장하도록 변경한 설계 및 구현 상세 사양을 정리한 기술 지식베이스입니다.
---
## 1. 로그인 프로시저 연동 설계 및 구현
### 1.1 설정 사양 (`Database.ini`)
프로그램 구동 시 로그인 및 DB 접속 세부 사양을 유연하게 제어하기 위해 프로그램 실행 디렉터리(`AppContext.BaseDirectory`) 아래의 `Database.ini` 파일을 파싱하여 설정을 로드합니다.
* **파일 위치**: `Database.ini`
* **설정 형식**:
사람이 직접 읽고 편집하기 편리하도록 개별 상세 접속 파라미터(`Db_Server`, `Db_Name`, `Db_User`, `Db_Password`)로 줄바꿈하여 설정할 수 있습니다. (하위 호환성을 위해 단일 `ConnectionString` 통째 입력 방식도 동시에 지원합니다.)
```ini
; [데이터베이스 접속 상세 설정]
Db_Server=192.168.0.20
Db_Name=NE1aW_PT_SENSOR
Db_User=sa
Db_Password=sa1234
[Login]
Procedure=dbo.CheckOperator
ProcessName=EOL
OfflinePreview=false
```
### 1.2 소스코드 변경 내역
#### [LoginSettings.cs](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Services/LoginServicesStub.cs#L45-L113)
* **추가 프로퍼티**:
* `Procedure` (string): 검증에 사용할 DB 저장 프로시저명
* `ProcessName` (string): 검사에 연동된 공정명
* **로드 로직**: `Database.ini` 파일로부터 `Procedure``ProcessName` 키를 대소문자 구분 없이 인식하여 설정 개체에 바인딩합니다.
#### [LoginAccountRepository.cs (ExistsAsync)](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Services/LoginServicesStub.cs#L240-L312)
* **동작 흐름**:
1. 데모 계정(`test`/`test`)을 입력한 경우 DB 조회나 설정 여부와 상관없이 최우선적으로 로그인을 즉시 통과시킵니다. (기존의 `admin`, `su` 데모 계정은 제거되었습니다.)
2. `OfflinePreview``true`이면 DB 조회를 건너뛰고 무조건 로그인을 성공 처리합니다.
3. `Database.ini``Procedure` 설정이 정의되어 있으면 `SqlCommand` 객체의 `CommandType``StoredProcedure`로 지정하여 해당 프로시저를 호출합니다.
* **SQL 매개변수**:
* `@OperatorId`: 사용자 입력 ID
* `@Password`: 사용자 입력 패스워드
* `@ProcessName`: INI 파일의 `ProcessName` 정보 (`EOL`)
* **인증 판단**: 프로시저 반환값을 정수로 파싱하여 결과가 `0`보다 크면 성공(`true`), 그렇지 않으면 실패(`false`)로 판단합니다.
4. `Procedure` 설정이 없을 경우 Fallback 쿼리(`SELECT COUNT(*) FROM [Users] WHERE [OperatorId] = @Id ...`)를 작동시킵니다.
5. DB 연결 또는 쿼리 오류 등으로 인해 SQL Exception이 발생하더라도 프로그램 비정상 종료를 예방하는 예외 격리 구조를 갖추고 있습니다.
---
## 2. 검사 결과 저장 개편 (`dbo.EOL` 스키마 및 CSV 일원화 대응)
### 2.1 데이터베이스 구성 명세 (`dbo.EOL`)
사용자가 정의한 구성안에 맞춰 `Password` 컬럼을 완전히 삭제하고, 검사 결과 및 전역 로그인 메타데이터 정보를 릭(Leak) 검사 결과와 병합하여 UPSERT(MERGE) 처리합니다.
| 물리 컬럼명 | 데이터 타입 | 매핑 설명 | 비고 |
| :--- | :--- | :--- | :--- |
| **`IC_SN`** | `NVARCHAR(10)` | 제품의 최종 조합 ID (`inspectData.IcSn`) | **PK / FK** |
| **`PCB_Barcode`** | `NVARCHAR(10)` | 고유 식별용 바코드 정보 | **UK** *(inspectData.PcbBarcode 매핑)* |
| `Maker` | `NVARCHAR(10)` | 로그인 메이커 정보 (`App.LoginResult.Maker`) | |
| `Model` | `NVARCHAR(10)` | 로그인 모델 정보 (`App.LoginResult.Model`) | |
| `Variant_1` | `NVARCHAR(10)` | 로그인 변형1 정보 (`App.LoginResult.Variant1`) | |
| `Variant_2` | `NVARCHAR(10)` | 로그인 변형2 정보 (`App.LoginResult.Variant2`) | |
| `Operator` | `NVARCHAR(10)` | 로그인 검사자 ID (`App.LoginResult.Operator`) | |
| `Production_Date` | `DATETIME2(0)` | 검사 일시 (`inspectData.ProductionDate ?? DateTime.Now`) | |
| `Line` | `NVARCHAR(5)` | 로그인 작업 라인 (`App.LoginResult.LineNo`) | |
| `Lot_No` | `NVARCHAR(8)` | 로그인 Lot 번호 (`App.LoginResult.LotNo`) | |
| `Jig_No` | `NVARCHAR(10)` | 로그인 지그 번호 (`App.LoginResult.JigNo`) | |
| `Channel` | `NVARCHAR(5)` | 검증 수행 채널 (`LEFT` / `RIGHT`) | |
| `Spec_UL` | `DECIMAL(3,2)` | 스펙 상한값 (`decimal` 변환) | |
| `Spec_LL` | `DECIMAL(3,2)` | 스펙 하한값 (`decimal` 변환) | |
| `Leak_Value` | `DECIMAL(5,4)` | 측정된 누설량 (`decimal` 변환) | |
| `Result` | `NVARCHAR(5)` | 합격 여부 판정 (`OK` / `NG`) | |
### 2.2 SQL UPSERT 쿼리 명세 (MERGE 구문)
`IC_SN` 키를 기준으로 이미 데이터가 적재되어 있다면 모든 관련 필드를 신규 검사 정보로 `UPDATE` 하고, 미등록 상태라면 새로 `INSERT` 하도록 설계되었습니다.
```sql
MERGE INTO [dbo].[EOL] AS Target
USING (SELECT @IC_SN AS IC_SN) AS Source
ON (Target.IC_SN = Source.IC_SN)
WHEN MATCHED THEN
UPDATE SET
Target.PCB_Barcode = @PCB_Barcode,
Target.Maker = @Maker,
Target.Model = @Model,
Target.Variant_1 = @Variant_1,
Target.Variant_2 = @Variant_2,
Target.Operator = @Operator,
Target.Production_Date = @Production_Date,
Target.Line = @Line,
Target.Lot_No = @Lot_No,
Target.Jig_No = @Jig_No,
Target.Channel = @Channel,
Target.Spec_UL = @Spec_UL,
Target.Spec_LL = @Spec_LL,
Target.Leak_Value = @Leak_Value,
Target.Result = @Result
WHEN NOT MATCHED THEN
INSERT (IC_SN, PCB_Barcode, Maker, Model, Variant_1, Variant_2, Operator, Production_Date, Line, Lot_No, Jig_No, Channel, Spec_UL, Spec_LL, Leak_Value, Result)
VALUES (@IC_SN, @PCB_Barcode, @Maker, @Model, @Variant_1, @Variant_2, @Operator, @Production_Date, @Line, @Lot_No, @Jig_No, @Channel, @Spec_UL, @Spec_LL, @Leak_Value, @Result);
```
### 2.3 소스코드 구현 핵심 사항
* **[EolDatabaseService.cs](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Services/EolDatabaseService.cs#L24-L101)**:
* WPF 애플리케이션의 전역 로그인 상태 개체인 `App.LoginResult`를 안전하게 로컬 변수로 바인딩(`Null-coalescing` 연산자 적용)하여 로그인 정보가 비어 있는 비정상 상황에서도 DB 저장이 실패하지 않도록 설계했습니다.
* `decimal.TryParse` 패턴을 도입하여 `SpecUL`, `SpecLL`, `MeasuredValue`와 같은 수치형 데이터를 안전하게 파싱한 뒤 SQL Parameter로 전달함으로써 타입 변환 예외 위험을 격리했습니다.
* **개별 매핑 및 시간 동기화**: `inspectData.IcSn``inspectData.PcbBarcode`를 DB 파라미터로 각각 매핑하고, 저장 시간 역시 CSV와의 정합성 일치를 위해 `inspectData.ProductionDate ?? DateTime.Now`를 바인딩하도록 고도화했습니다.
* **[TestProcessService.cs (EolDatabaseService 인스턴스 생성)](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Services/TestProcessService.cs)**:
* 기존에 분산 관리되던 DB 접속 스트링(`config.xml`의 `DbConnectionString`) 대신, 모든 데이터베이스 접속 및 검증 주소를 `Database.ini` 파일 하나로 일원화하기 위해 `DatabaseSettings.Load(dbIniPath).ConnectionString` 방식으로 접속 정보를 읽어오도록 수정하여 설정 관리 포인트를 통합했습니다.
* **메타데이터 저장 정합성 확보**: 합격, 불합격, 타임아웃 등 모든 분기에서 `InspectData` 객체 생성 시 로그인 정보(`Maker`, `Model`, `Variant`, `Operator` 등) 및 실제 검사 시간(`ProductionDate`), 바코드 값을 완벽히 주입하여 로컬 CSV 백업 파일 작성 시 공란으로 비어있지 않도록 일원화했습니다.
* **[ProjectModels.cs (AppConfig 및 InspectData)](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Models/ProjectModels.cs#L19-L21)**:
* `AppConfig` 내부에 존재하던 데이터베이스 연결 주소 하드코딩 속성에 `[Obsolete]` 경고를 지정하고, 실제 데이터베이스 연결에서는 이 속성이 사용되지 않도록 완전히 배제했습니다.
* `InspectData` 클래스 모델을 확장하여 새로운 DB 테이블 컬럼 바인딩 필드(Maker, Model, Variant 등)를 추가하여 데이터 저장 및 표현의 정합성을 수립했습니다.
* **[LogUtils.cs (FileLogger 및 LogParser)](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Utils/LogUtils.cs)**:
* **로컬 CSV 16컬럼 저장**: `FileLogger.LogInspectData`를 수정하여 DB `dbo.EOL` 테이블 스키마와 완벽히 동일한 16개 컬럼(`IC_SN,PCB_Barcode,Maker,Model,Variant_1,Variant_2,Operator,Production_Date,Line,Lot_No,Jig_No,Channel,Spec_UL,Spec_LL,Leak_Value,Result`) 순서 및 헤더로 CSV 로그 파일에 기록하도록 개선했습니다.
* **상세 필터 검색**: `LogParser.ParseLogs` 메서드 시그니처를 확장하여 `opFilter`, `lotFilter`, `modelFilter` 매개변수를 추가하고, DB 쿼리 실행 시 `LIKE` 조건식을 동적으로 조합해 교차 상세 검색을 수행하도록 수정했습니다.
* **안정성 및 공유 잠금(FileShare) 조치**: 현장 작업자가 엑셀로 백업 CSV를 열어 두어 파일 락이 발생하더라도 `FileShare.ReadWrite` 모드를 적용하여 데이터가 안전하게 읽어지도록 개선했습니다.
* **로캘 독립적 날짜 파싱**: 시스템 국가 언어 설정과 관계없이 안전하게 파일을 파싱할 수 있게 `DateTime.TryParseExact`로 날짜 포커스를 통제했습니다.
* **중복 제거 필터 적용**: 동일 제품 재검사 시 DB는 덮어쓰기되고 CSV는 누적되는 동작 차이를 극복하기 위해, CSV 조회(`ParseLogsFromCsv`) 시 동일 제품 코드에 한해 가장 최신 날짜/시간의 1건만 노출하도록 중복 제거 필터를 적용했습니다.
* **CSV Fallback 및 하위 호환성**: DB 연결 실패 혹은 미등록 시 작동하는 로컬 CSV 파싱(`ParseLogsFromCsv`) 과정에서, 한 행의 쉼표 분할 크기(`parts.Length`)를 기반으로 구형 8개 컬럼 파일과 신규 16개 컬럼 파일을 자동 감지해 맵핑하는 정합성 및 예외 안전 장치를 탑재했습니다. 필터 조건 입력 시 구형 포맷은 자동 필터링 제외 처리됩니다.
* **[DataViewModel.cs](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/ViewModels/DataViewModel.cs)**:
* `OperatorFilter`, `LotNoFilter`, `ModelFilter` 바인딩 속성을 신설하고, 검색 실행(`ExecuteSearch`) 호출 시 이를 `LogParser.ParseLogs`에 매개변수로 전달하여 연계 검색이 수행되도록 변경했습니다.
* **[DataView.xaml](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Views/DataView.xaml)**:
* 확장된 상세 필터 조건들을 유연하게 담고 레이아웃이 훼손되지 않도록 필터 패널 영역을 **2행(Rows) 구조**로 전면 리디자인하여 UX 사용성을 개선했습니다.
* 데이터 그리드의 열 바인딩 정보를 신규 스키마 컬럼 구성과 일치하도록 17개 컬럼으로 보강했습니다.
---
## 3. 개발 및 빌드 검증 가이드
### 3.1 Non-SDK 스타일 빌드 경고 및 주의사항
본 프로젝트는 **Non-SDK 스타일(C# .NET Framework 4.7.2)** 기반의 레거시 WPF 애플리케이션입니다.
* **문제 현상**: `dotnet build`를 사용해 컴파일을 시도하면 XAML 파일을 파싱 및 코드비하인드로 자동 변환하는 WPF 전용 MSBuild Target 프로세스가 누락되어 `g.cs` 임시 파일들이 누락됩니다. 이로 인해 컨트롤 식별자가 정의되지 않았다는 다수의 컴파일 에러(예: `CS0103 'Variant1TextBox' 이름이 현재 컨텍스트에 없습니다.`)가 발생하게 됩니다.
* **올바른 빌드 방법**: Visual Studio 2022 환경의 정식 `MSBuild.exe`를 사용하여 컴파일을 수행해야 합니다.
```powershell
# MSBuild 정식 컴파일 명령어 (Cwd: leak_test_project/)
& "C:\Program Files\Microsoft Visual Studio\18\Insiders\MSBuild\Current\Bin\MSBuild.exe" "leak_test_project\leak_test_project.csproj" /t:Rebuild /p:Configuration=Release
```
### 3.2 빌드 배포 자동화 (`.csproj`)
`Database.ini` 파일이 프로그램 실행 및 릴리즈 배포 경로에 자동 포함되도록 하기 위해 `leak_test_project.csproj` 파일 내에 아래와 같이 `PreserveNewest` 복사 수명 설정을 구현했습니다.
```xml
<ItemGroup>
<None Include="App.config" />
<None Include="Database.ini">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
```
이를 통해 VS에서 프로젝트를 빌드하거나 재빌드할 때마다 자동으로 최신 `Database.ini` 파일이 컴파일 결과물 폴더(`bin/Debug/` 및 `bin/Release/`)로 자동 갱신 및 복사됩니다.