수술 파생 6종 — 236종 → 242종, ㉘ 수술 검증이 SKIP 에서 실검증으로

OCM_수술주상병(bzDataInterface.vb:13148 + GetOprInfDT_OKDMain :13364 —
기존 수술 조회와의 실질 차이가 상병 집계의 주상병 한정(OPRVAR1='0')
한 줄이라 SurgeryStore 에 mainDiagnosisOnly 를 얹었다. 치환이
빗나가면 필터 없는 값이 조용히 나가므로 가드로 던진다),
OCM_수술집도의_진료과/_그룹진료과(:3157/:3194 — 집도의(DTRUIDCOD)를
오늘 기준 마스터로 푸는 원문 특이점(OprStt 무필터·SYSDATE 유효기간)
그대로, 최신 수술 첫 행 고정), OCM_수술명칭(:3520 Case Else —
OPRCOD 를 수술일 순으로, 각 행 뒤 공백 1칸 + CRLF 결합. GNBEDRO·
HIMCHAN_BP 의 OPNAME 포함 분기 미이식).

사유 완결 2종: OCM_수술진단명(:3066 — PURME 전용, 그 외 병원은
Case 미매칭으로 항상 빈 값), OCM_수술처치(:3474 — SUSS·YJRCH 전용).

㉘ 정정: 수술 검증이 늘 SKIP 이던 원인은 소유자 탐색을 O_OprInf 로
한 것 — 실제 조회(GetOprInfDT)의 축은 S_OprInf(수술 신청)다.
표를 바로잡자 이 시험 DB 에서 수술 행 1건·OPNAME 실값이 검증됐다
(SurgeryStore 의 낡은 주석도 함께 정정).

- dotnet test 342/342 · --edit-smoke 실패 0 (이름 검사 242종)
- --db-patient ①~㊱ 전건 통과 — ㉘ 이 처음으로 실값 PASS
- --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 불변

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Msystech
2026-08-20 08:51:30 +09:00
co-authored by Claude Fable 5
parent 02657b3893
commit 03fff0a3a4
4 changed files with 129 additions and 6 deletions
+7 -4
View File
@@ -2242,18 +2242,21 @@ public static class DbSmoke
}
// ㉘ 수술 — 원문 기계 추출 SQL 이 실제로 돈다.
var oprOwner = FirstComNum(conn, "O_OprInf", "OprComNum", "OprComNum");
// 처음엔 O_OprInf 로 소유자를 찾아 늘 SKIP 이었다 — 실제 조회
// (GetOprInfDT)의 축은 S_OprInf(수술 신청)다. 표를 바로잡으니
// 이 시험 DB 에서도 수술 태그가 실검증된다.
var oprOwner = FirstComNum(conn, "S_OprInf", "OprComNum", "OprComNum");
if (oprOwner is null)
{
// "행이 없다"와 "표가 없다/조회가 죽었다"를 가른다 —
// FirstComNum 은 예외를 삼키므로 이 줄 없이는 못 가른다.
foreach (var line in ExplainPeriod(conn, 0,
"SELECT COUNT(*) OPRCNT FROM O_OprInf WHERE :k = 0"))
"SELECT COUNT(*) OPRCNT FROM S_OprInf WHERE :k = 0"))
{
lines.Add($" [진단] O_OprInf: {line}");
lines.Add($" [진단] S_OprInf: {line}");
}
lines.Add("SKIP ㉘ 수술 — 확인 불가. 위 [진단] 줄이 원인이다:"
+ " ORA-00942 면 이 시험 DB 에 O_OprInf 가 아예 없는 것이고,"
+ " ORA-00942 면 이 시험 DB 에 S_OprInf 가 아예 없는 것이고,"
+ " 수술 태그는 운영 DB 에서만 검증할 수 있다");
}
else
@@ -1716,6 +1716,8 @@ public sealed class PatientTagResolver : ITagValueResolver
"ETC_승인의사", "OCM_수술소독간호사",
"OCM_적용진료과", "OCM_적용진료의사", "OCM_전과", "OCM_간호정보조사지_과거력",
"OCM_영상촬영이력",
"OCM_수술주상병", "OCM_수술집도의_진료과", "OCM_수술집도의_그룹진료과",
"OCM_수술명칭", "OCM_수술진단명", "OCM_수술처치",
};
/// <summary>
@@ -2246,6 +2248,66 @@ public sealed class PatientTagResolver : ITagValueResolver
}
return new TagValue(true, text.ToString());
}
case "OCM_수술주상병":
{
// GetOprInfDT_OKDMain(:13364) — 상병 집계를 주상병(OPRVAR1='0')로
// 한정한 수술 조회의 첫 행 OkdNam. 이 시험 DB 엔 O_OprInf 계열이
// 없어 운영 DB 에서만 값 검증이 된다(수술 8종과 동일).
var comNum = PatientContext.Value(context.ComInf, "ComNum");
if (!decimal.TryParse(comNum, out var m))
{
return new TagValue(false, "이 내원의 내원번호를 읽지 못했습니다");
}
if (contextStoreSource is null)
{
return new TagValue(false, "수술 조회가 연결되지 않았습니다");
}
var rows = new SurgeryStore(
Services.ConfigService.Current.ConnectionString)
.Surgeries(m, mainDiagnosisOnly: true);
if (rows.Count == 0)
{
return new TagValue(false, "확정(OprStt='E')된 수술 신청이 없습니다");
}
var okd = rows[0].TryGetValue("OKDNAM", out var v) ? v : string.Empty;
return okd.Length > 0
? new TagValue(true, okd)
: new TagValue(false, "수술 행에 주상병(OPRVAR1='0') 표기가 없습니다");
}
case "OCM_수술집도의_진료과":
case "OCM_수술집도의_그룹진료과":
{
var comNum = PatientContext.Value(context.ComInf, "ComNum");
if (!decimal.TryParse(comNum, out var m))
{
return new TagValue(false, "이 내원의 내원번호를 읽지 못했습니다");
}
return Wrap(store.SurgeonDepartment(m, tag == "OCM_수술집도의_그룹진료과"),
"집도의(DTRUIDCOD)와 오늘 기준 부서가 짝이 되는 수술이 없습니다");
}
case "OCM_수술명칭":
{
var comNum = PatientContext.Value(context.ComInf, "ComNum");
if (!decimal.TryParse(comNum, out var m))
{
return new TagValue(false, "이 내원의 내원번호를 읽지 못했습니다");
}
var names = store.SurgeryNames(m);
if (names.Count == 0)
{
return new TagValue(false, "확정 수술의 수술코드명(OPRCOD)이 없습니다");
}
// 원문 결합(:3546-3556): 각 행 뒤 공백 1칸, 행 사이 CRLF(마지막에도 공백)
return new TagValue(true, string.Join("\r\n", names.Select(n => $"{n} ")));
}
case "OCM_수술진단명":
// PURME 전용(:3066) — 그 밖의 병원은 Case 미매칭으로 항상 빈 값이다
return new TagValue(false,
"PURME 전용 태그입니다 — 그 밖의 병원에서는 레거시도 항상 빈 값입니다");
case "OCM_수술처치":
// SUSS·YJRCH 전용(:3474) — 그 밖의 병원은 Case 미매칭으로 항상 빈 값이다
return new TagValue(false,
"SUSS·YJRCH 전용 태그입니다 — 그 밖의 병원에서는 레거시도 항상 빈 값입니다");
case "OCM_간호정보조사지_과거력":
{
var comNum = PatientContext.Value(context.ComInf, "ComNum");
@@ -2491,6 +2553,8 @@ public sealed class PatientTagResolver : ITagValueResolver
"ETC_승인의사", "OCM_수술소독간호사",
"OCM_적용진료과", "OCM_적용진료의사", "OCM_전과", "OCM_간호정보조사지_과거력",
"OCM_영상촬영이력",
"OCM_수술주상병", "OCM_수술집도의_진료과", "OCM_수술집도의_그룹진료과",
"OCM_수술명칭", "OCM_수술진단명", "OCM_수술처치",
"OCM_입원시간", "OCM_입원일시", "OCM_입원일시_영문", "OCM_입실시간",
"OCM_의사퇴원예고일시", "OCM_퇴원예정일시", "OCM_퇴원시간", "OCM_퇴원일시",
"OCM_퇴원예고일시", "OCM_재원일수", "OCM_퇴원예고재원일수", "OCM_입원일자_낮병동",