이 스킬
Mappers — accountMappings.json (DART SSOT)
계정 매핑 SSOT — `src/dartlab/reference/data/accountMappings.json` 단일 파일 (standardAccounts ~3,143 + mappings ~34,622 + layers 5 + edgar) 구조 정의 + 12 단계 fallback 룰 + atomic write 진입점 (mappingPromote.py --layer). 구조·관리 정본은 operation.mappingRefresh §0.
이어 가기
- Mappers (계정 정규화)
engines.mappers - accountMappings 보강 4 단계 파이프라인
operation.mappingRefresh
절차
실행 순서
- 1
`standardAccounts` — ~3,143 표준 계정 (snakeId 단일 SSOT, IFRS 분류).
- 2
`mappings` — 한글/영문 → snakeId 평면 사전 (~34,622, 12 단계 fallback 1 단계 hit).
- 3
`layers` — stage 별 정규화 dict 5 종 (옛 in-code ID_SYNONYMS/ACCOUNT_NAME_SYNONYMS/
- 4
`edgar` — EDGAR tag 매핑 소스 (옛 별도 mapperData 흡수). 인덱스는 consumer 파생.
- 5
`_metadata` — 갱신 추적. **파생 카운트 박기 금지** (drift stale 버그 근원).
- 6
`_metadata.lastUpdate` 날짜 ≤ 오늘 (역날짜 X).
- 7
`mappings` 의 모든 value 가 `standardAccounts` 의 snakeId.
- 8
`layers.snakeAlias`/`korSynonym` 의 value 가 snakeId (id/name/labelEn layer 는 미적용).
- 9
`_metadata` 에 파생 카운트(standardAccounts/learnedSynonyms/merged) 부재 (drift 가드).
- 10
golden `test_ssot_equivalence_*` + `test_ssot_structure` 통과.
- 11
[engines.mappers](/skills/engines.mappers) — base SKILL (학습 파이프라인 4 단계 + 5 신호 게이트)
- 12
[engines.mappers.synonyms](/skills/engines.mappers.synonyms) — learnedSynonyms 측 SSOT + EDGAR 비대칭
엔진 역할
mappers 엔진의 DART 매핑 데이터 SSOT sub-spec. base SKILL engines.mappers 의 학습 파이프라인 4 단계와 5 신호 게이트가 생성하는 결과물 SSOT — src/dartlab/reference/data/accountMappings.json 단일 파일. EDGAR 측 (synonyms sub-spec) 과 직교 — 두 provider 비대칭 (EDGAR 는 자체 mapperData/ 보유).
공개 호출 방식
# RunPython prelude (engines.mappers 와 동일)
col = normalizeColumn("BS", "총자산") # → "total_assets"
# 직접 로더 (운영자/디버그)
from dartlab.reference.mappers.accountMapper import AccountMapper
mapper = AccountMapper()
print(mapper.stats())
# MapperStats(name='account', totalEntries=34249, coverage=1.0, lastUpdated='2026-03-09')
mapper.lookup("매출액")
# {'snakeId': 'sales', 'category': 'is', ...} 호출 동작
normalizeColumn / AccountMapper.lookup 모두 본 sub-spec 의 SSOT 파일을 메모리 로드 (lru_cache) 후 12 단계 fallback 매칭 — 사전 hit → synonym 정규화 → 공백/괄호/하이픈 역인덱스 → 액 suffix.
JSON 직접 편집 후 AccountMapper.release() 호출해야 cache 무효화 (lru_cache.cache_clear).
파일 구조
{
"_metadata": {
"description": "...", "schemaVersion": 2,
"lastUpdate": "2026-06-05", "addedCount": 373, "promoteCommit": "e33ec2b8..."
},
"standardAccounts": {
"total_assets": {"korName": "자산총계", "category": "asset", "type": "total", "topic": "BS"},
...
},
"mappings": {"총자산": "total_assets", "Total Assets": "total_assets", ...},
"layers": {
"idSynonym": {"SalesRevenue": "Revenue", ...},
"nameSynonym": {"영업수익": "매출액", ...},
"snakeAlias": {"operating_income": "operating_profit", ...},
"labelEn": {"sales": "Revenue", ...},
"korSynonym": {"세전이익": "profit_before_tax", ...}
},
"edgar": {
"accounts": [{"snakeId": "total_assets", "stmt": "BS", "commonTags": [...]}, ...],
"learnedTags": {"revenues": "sales", ...},
"stmtOverrides": {"NetIncomeLoss|IS": "net_profit", ...}
}
} standardAccounts— ~3,143 표준 계정 (snakeId 단일 SSOT, IFRS 분류).mappings— 한글/영문 → snakeId 평면 사전 (~34,622, 12 단계 fallback 1 단계 hit).layers— stage 별 정규화 dict 5 종 (옛 in-code ID_SYNONYMS/ACCOUNT_NAME_SYNONYMS/ SNAKEID_ALIASES/_EDGAR_LABELS/_KR_SYNONYMS 흡수). 평면화 금지 — 단계 의미 보존.edgar— EDGAR tag 매핑 소스 (옛 별도 mapperData 흡수). 인덱스는 consumer 파생._metadata— 갱신 추적. 파생 카운트 박기 금지 (drift stale 버그 근원).
12 단계 fallback 룰
mappings[accountId]직 hitlearnedSynonyms[accountNm]직 hitaccountNm한자 → 한글 정규화 후 retryaccountNm(주)/(연결) suffix 제거 후 retry- 공백 정규화 후 retry
- 괄호 제거 후 retry
- 하이픈 정규화 후 retry
accountIdprefix (-표준계정코드 미사용-) 제거 후 retry- 액 suffix (영업이익액 → 영업이익) 제거 후 retry
accountNmjamo 분해 → 1 자모 차이 standardAccounts.korName 매칭- accountNm substring (≥ 0.70 score) standardAccounts.korName 매칭
- None 반환 (진짜 미커버)
각 단계 hit 시 confidence 1.0 (1 단계) → 0.6 (10~11 단계) 감점. 답변 시 confidence < 0.8 명시.
atomic write 진입점
prod JSON 직접 편집 금지 — src/dartlab/reference/mapping/mappingPromote.py 만 진입점:
# 운영자 절차 (operation.mappingRefresh 4 단계 마지막)
uv run python -X utf8 src/dartlab/reference/mapping/mappingPromote.py apply --batch=<staged_file> mappingPromote.py 가:
- atomic write (
accountMappings.json.tmp→ rename) _metadata.lastUpdate/addedCount/promoteCommit갱신AccountMapper.release()자동 호출 (cache 무효화)- single-line JSON 보존 (
separators=(',', ':')— diff noise 최소)
대표 반환 형태
AccountMapper.lookup("매출액")
→ dict
snakeId : str # "sales"
korName : str # "매출액"
category : str # "revenue"
type : str # "operating"
topic : str # "IS"
confidence : float # 1.0 (1 단계 hit)
matchStage : int # 1 ~ 11 기본 검증
_metadata.lastUpdate날짜 ≤ 오늘 (역날짜 X).mappings의 모든 value 가standardAccounts의 snakeId.layers.snakeAlias/korSynonym의 value 가 snakeId (id/name/labelEn layer 는 미적용)._metadata에 파생 카운트(standardAccounts/learnedSynonyms/merged) 부재 (drift 가드).- golden
test_ssot_equivalence_*+test_ssot_structure통과.
관련
- engines.mappers — base SKILL (학습 파이프라인 4 단계 + 5 신호 게이트)
- engines.mappers.synonyms — learnedSynonyms 측 SSOT + EDGAR 비대칭
- operation.mappingRefresh — 운영자 트리거 절차 4 단계
런타임
실행 환경별 호환성
| 환경 | 상태 | 비고 / 제한 |
|---|---|---|
| Local Python | supported | · |
| Server | supported | · |
| MCP | supported | · |
| Web AI | supported | · |
| Pyodide | limited | · |