Skip to content
isdnetworks
Go back

한 축이 아니라 쌍으로 분기한다

(수정됨)

여러 은행과 결제 대행사에서 오는 입금 통지를 모아 처리하는 흐름을 만들고 있었다. 통지마다 처리 방식이 달라서 무엇을 기준으로 분기할지 정해야 했다. 처음에는 통지에 붙은 출처 값 source 로 나누려고 했다.

Table of contents

Open Table of contents

분류와 종류가 달랐다

출처 값으로 나눠 보고 실제 자료를 세어 보니 한 출처 안에 다른 종류가 섞여 있었다.

출처 "은행 A" 안에
  → 실제 종류: 입금 통지 대부분 + 입금 취소 통지 한 줌

출처 "대행사 B" 수십 건
  → 입금 통지 + 취소 통지 + 잔액 조정 통지

출처는 어디서 왔는지를 나타낼 뿐이고 처리 방식은 통지 종류에 달려 있었다.

그런데 종류를 담는 필드가 따로 없었고 subject 앞에 붙은 접두어가 그 역할을 하고 있었다.

[입금] 제목...
[입금취소] 제목...

구조화된 필드가 아니라 문자열 안에 종류가 들어 있는 상태였다.

접두어에 있던 변형

접두어를 정규화하려고 실제 자료를 세어 봤더니 같은 종류에 세 변형이 있었다.

[입금-가상계좌]   대부분
[입금]            일부
[입금 - 가상계]   한 건

계좌 종류 표시가 붙거나 표기가 조금씩 달랐고 띄어쓰기 자리에 U+0020 말고 U+00A0 와 U+3000 이 섞이고 괄호가 U+0028 과 전각 U+FF08 로 갈렸다.

눈으로 보면 같아 보이는 문자가 실제로는 전혀 다른 코드포인트인 경우도 있었다. U+002D 자리에 U+2010 과 U+2013 과 전각 U+FF0D 가 섞여 있었다. 그래서 하이픈 이후를 떼는 정규식을 만들어 변형을 다 받아들이게 했다.

/^\[ *([^\]\-–—]+?) *(?:[-–—][^\]]*)?\]/

문자 클래스에 일반 하이픈과 엔대시와 엠대시를 다 넣은 것은 실제 자료에 셋이 다 있었기 때문이다. NFKC 정규화는 U+FF0D 와 U+3000 은 접지만 U+2010 과 U+2013 은 그대로 두므로 정규화만 걸고 실제 자료를 안 셌으면 절반은 안 잡혔을 것이다. 정규화 하나에 기대는 것 대신 실제 자료를 세는 쪽을 골랐다. 이유는 어느 변형이 있는지는 자료만이 말해 줘서다.

종류만으로도 부족했다

종류를 뽑아내고 나서도 분기가 완전하지 않았다. 같은 종류의 통지인데 어느 곳에서 왔느냐에 따라 처리가 달라지는 경우가 있었다.

즉 한 축으로는 나눌 수 없고 출처와 종류를 쌍으로 놓고 봐야 했다. 그래서 가능한 (source, kind) 조합을 완전 열거표 PARSER_MAP 으로 만들고 각 조합의 파서 스키마를 명시했다.

(은행 A, 입금)      →  스키마 X
(은행 A, 입금취소)  →  스키마 Y
(대행사 B, 입금)    →  스키마 X'   ← 같은 종류인데 다르다
(대행사 B, 잔액조정) →  스키마 Z

축이 하나가 아닐 수 있다는 것을 인정하고 나서야 분기가 정리됐다.

대응 — 없는 조합을 다루기

표에 없는 조합이 들어오면 어떻게 할지도 정해야 했다. 기본 처리로 넘겨 버리면 그 통지가 조용히 잘못 처리될 수 있다.

기본 처리로 넘기는 것과 멈추고 알리는 것 두 가지 방법 중 뒤쪽으로 했다. 새 조합이 생기면 그 시점에 알게 되고 표에 추가할 수 있다. 조용히 처리하는 것보다 멈추고 알리는 편이 이런 경우에는 안전했다.

조용히 틀리는 위험

전체를 훑어 통지 골격을 비교해 보니 한 조합만 구조가 달랐다.

다른 것들   고정 항목 셋 (계좌·금액·시각)
그 조합     항목별 여러 줄. 고정 항목이 없다

고정 스키마로 담을 수 없어 별도 스키마가 필요했고 그 조합을 다른 처리에 태우면 필드 위치가 어긋난다.

그런데 파서가 결과를 account·amount·noticed_at 고정 필드 구조체로 만들어 내기 때문에 분기가 틀려도 오류가 나지 않는다. 형식은 무조건 맞춰 나오므로 금액 자리에 다른 값이 든 결과가 조용히 나가는 것이다. 이 구조에서는 분기 오류가 가장 늦게 발견되므로 표를 만들 때 실제 자료로 전부 확인했다.

정리


Share this post on:

Previous Post
상태를 바꾸면 대상마다 할 일이 생겼다
Next Post
종결 처리가 여러 자리에 걸쳐 있었다