OCM_담당의사 3종을 옮긴다 — 처음으로 레거시와 의도적으로 다르게 간다

23종 → 26종. 조회 둘(P_CodInf 선택 + M_UidMst)이 새로 붙었다.

## 원칙을 처음 깬다

지금까지는 "레거시가 이상해 보여도 그대로 옮긴다"였다
(주민번호의 DateValidCheck 가 그랬다 — 조건이 항상 참이지만 그대로 뒀다).

여기서는 그럴 수 없다. GetCodInfDT 는 ORDER BY 없이 CodMtiSeq='0' 만 걸고
호출부가 Rows(0) 을 집는데, 이 DB 에서 그런 내원이 <b>25,488건</b>이고 최대 41행이다.
41행 중 첫 행은 사실상 무작위다 — <b>재현할 결정적 동작이 존재하지 않는다.</b>

그래서 적용일시로 거르고 최신순 1행을 집는다(문맥의 CodInf 와 같은 규칙).
레거시도 이 시각을 넘기기는 한다 — 마스터 유효기간 조인에만 쓸 뿐이고
P_CodInf 의 CodStrDtm/CodEndDtm 은 WHERE 에 없다.
"그 시점의 진료과"를 뽑으려던 의도가 반쯤만 구현된 것으로 보인다.
근거는 docs/TAG-PORTABLE-48.md 에 남겼다.

## 폴백을 빠뜨리지 않았다

GetUidMst(clsCommonLib.vb:10615)는 유효기간으로 먼저 찾고
<b>0행이면 코드만으로 다시 찾는다</b>. 그 폴백을 빼면 유효기간이 지난 의사가
통째로 빈칸이 된다. 두 번째 조회까지 옮겼다.

## 세 갈래 시각

  입원 · ComPrgStt='ILV' → 퇴원일시
  입원 · 그 밖           → 문맥의 적용일시
  외래                   → 접수일시
담당의 유효기간을 볼 날짜도 갈린다(입원은 진료과 행의 CodEndDtm, 외래는 접수일자).

## 또 같은 함정을 밟을 뻔했다

㉒ 를 처음 돌렸을 때 0열이 나왔다. 쿼리 문제로 보였지만 아니었다 —
시험 내원(1988년)에 P_CodInf 행이 아예 없었다. 앞서 "내원 0건인 환자로 판정하려 한" 것과
같은 함정이다. 행을 가진 내원을 찾아 걸도록 고쳤다: 내원 5000323 → 52열, 이름 3자.

## 게이트

- dotnet test 336/336
- --edit-smoke 실패 0 — 이름 검사가 26종 전부 실제 태그임을 확인
- --db-patient ①~㉒ 전건 통과 (㉒ 담당의 조회 신규)
- --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 불변

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Msystech
2026-08-19 11:50:25 +09:00
co-authored by Claude Opus 5
parent 942780ae97
commit 5bf2cf034d
5 changed files with 145 additions and 2 deletions
@@ -2168,6 +2168,25 @@ public static class DbSmoke
{
lines.Add($" [조사] CodMtiSeq=0 이 2행 이상인 내원: {line}");
}
// ㉒ 담당의 조회가 실제로 행을 돌려주는가.
// 적용일시 BETWEEN + 최신순 1행으로 골라야 결정적이다(위 조사 근거).
// 0행이면 그 조건이 어긋난 것이라 태그 셋이 통째로 빈다.
{
// 시험 내원에 진료과 행이 <b>아예 없으면</b> 0열이 나오는데
// 그건 쿼리가 아니라 데이터다. P_CodInf 에 행을 가진 내원을 찾아 건다 —
// 앞서 이 함정을 밟은 적이 있다(내원 0건인 환자로 판정하려 했다).
var owner = FirstComNum(conn, "P_CodInf", "CodComNum", "CodStrDtm") ?? target;
var ownerCtx = owner == target ? ctx : contexts.Load(owner);
var doctor = ownerCtx is null
? new Dictionary<string, string>()
: (IReadOnlyDictionary<string, string>)contexts.Doctor(owner, ownerCtx.AdpDtm);
var uidNam = PatientContext.Value(doctor, "UidNam");
lines.Add($" 담당의 조회: 내원 {owner:F0} → {doctor.Count}열,"
+ $" 이름 {uidNam.Length}자 (값은 기록하지 않는다)");
Check("㉒ 담당의 조회가 예외 없이 돌고 행을 돌려준다", doctor.Count > 0,
"0열 — 적용일시 BETWEEN 조건이나 CodDtrCod 를 의심할 것");
}
}
}
}