auto: 일일 백업 2026-08-21 02:00
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
- 현대카드 자동납부 문자 `[현대카드] 자동납부 승인 ... 라이나생명 31,100원`이 raw 폴백으로 들어간 원인을 확인했다. 기존 구조는 라이나생명 SMS 자체를 파싱하지 않고 현대카드 누적액-후잉 잔액 차이 `-31,100원`일 때 월 1회 자동보정하는 방식이라, 차이가 이미 사라진 2026-08 건은 raw 전송으로 빠졌다.
|
||||
- 조치: `skills/whooing-sync/scripts/parsers.py`에 현대카드 자동납부 한 줄 형식 파서를 추가하고, `state/whooing_overrides.json`에 `현대카드 라이나생명 보험료 자동납부` 룰을 추가했다. 이후 같은 문자는 `의료,건강,보험 ← 현대신용(효원)`, item=`보험료`, amount=`31,100`으로 structured 처리된다. 기존 월 1회 잔액차 자동보정 및 보정 후 지연 SMS skip은 중복 방지용으로 유지.
|
||||
- 후속 확인: 2026-08-19 `현대 블루멤버스 승인 ... 쿠팡페이주식회사 18,500원`도 raw 200이었지만 후잉 잔액에 반영되지 않았다. 2026-08-19 쿠팡 18,500원(`생활용품 ← 현대신용(효원)`)과 2026-08-20 라이나생명 31,100원(`의료,건강,보험 ← 현대신용(효원)`)을 structured 수동 반영했고, 현대신용 잔액이 `1,104,760원`에서 `1,154,360원`으로 증가해 기대값과 일치함을 확인했다. `parsers.py`는 `현대 블루멤버스`처럼 "카드"가 빠진 현대카드 문자도 파싱하도록 추가 보강했다.
|
||||
@@ -204,7 +204,7 @@ def parse_kakao_bank(raw: str, created_at: str) -> "dict | None":
|
||||
# 누적1,466,011원 누적4,696,608원
|
||||
# 앞의 `현대카드[^\n]*` 가 greedy 라 "승인취소" 형태도 kind=취소 로 잡힌다.
|
||||
HYUNDAI_CARD_RE = re.compile(
|
||||
r"^\s*현대카드[^\n]*(?P<kind>승인|취소)\s*\n"
|
||||
r"^\s*현대(?:카드)?[^\n]*(?P<kind>승인|취소)\s*\n"
|
||||
r"(?P<who>[^\n]+)\s*\n"
|
||||
r"(?P<amount>[\d,]+)\s*원[^\n]*\n"
|
||||
r"\d{2}/\d{2}\s+\d{2}:\d{2}\s*\n"
|
||||
@@ -216,7 +216,7 @@ HYUNDAI_CARD_RE = re.compile(
|
||||
# RCS/MAAP 형식은 한 줄로 들어온다:
|
||||
# [Web발신] 현대카드 블루멤버스 승인 방*원 84,000원 일시불 05/16 11:57 네이버페이 누적820,000원
|
||||
HYUNDAI_CARD_INLINE_RE = re.compile(
|
||||
r"현대카드[^\n]*(?P<kind>승인|취소)\s+"
|
||||
r"현대(?:카드)?[^\n]*(?P<kind>승인|취소)\s+"
|
||||
r"(?P<who>\S+)\s+"
|
||||
r"(?P<amount>[\d,]+)\s*원[^\n]*?"
|
||||
r"\d{2}/\d{2}\s+\d{2}:\d{2}\s+"
|
||||
@@ -225,10 +225,24 @@ HYUNDAI_CARD_INLINE_RE = re.compile(
|
||||
re.MULTILINE,
|
||||
)
|
||||
|
||||
# 현대카드 자동납부 한 줄 형식:
|
||||
# [Web발신] [현대카드] 자동납부 승인 방*원님 라이나생명 31,100원
|
||||
HYUNDAI_AUTOPAY_RE = re.compile(
|
||||
r"\[?현대카드\]?\s*자동납부\s*(?P<kind>승인|취소|승인취소)\s+"
|
||||
r"(?P<who>\S+?님)\s+"
|
||||
r"(?P<merchant>.+?)\s+"
|
||||
r"(?P<amount>[\d,]+)\s*원\s*$",
|
||||
re.MULTILINE,
|
||||
)
|
||||
|
||||
|
||||
def parse_hyundai_card(raw: str, created_at: str) -> "dict | None":
|
||||
text = _normalize(raw).replace("[Web발신]", "").strip()
|
||||
m = HYUNDAI_CARD_RE.search(text) or HYUNDAI_CARD_INLINE_RE.search(text)
|
||||
m = (
|
||||
HYUNDAI_AUTOPAY_RE.search(text)
|
||||
or HYUNDAI_CARD_RE.search(text)
|
||||
or HYUNDAI_CARD_INLINE_RE.search(text)
|
||||
)
|
||||
if not m:
|
||||
return None
|
||||
amount = int(m.group("amount").replace(",", ""))
|
||||
@@ -240,8 +254,9 @@ def parse_hyundai_card(raw: str, created_at: str) -> "dict | None":
|
||||
"merchant": merchant,
|
||||
"raw": raw,
|
||||
}
|
||||
if m.group("cumulative"):
|
||||
result["cumulative"] = int(m.group("cumulative").replace(",", ""))
|
||||
cumulative = m.groupdict().get("cumulative")
|
||||
if cumulative:
|
||||
result["cumulative"] = int(cumulative.replace(",", ""))
|
||||
return result
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user