Парсинг реєстрів та автоматизація
TL; DR
Надійна «звірочна» автоматика будується на трьох китах: детермінований ingestion (безпечна доставка, ідемпотентність, контроль цілісності), нормалізований шар даних (єдина схема, ключі зіставлення, стандартизовані одиниці часу/валют/знаків) і жорстка дисципліна якості (валідації, толеранси, DLQ, алерти, автокорекції). Мета - перетворити різношерсті файли/вебхуки в стабільні таблиці для звірки, звітності та BI з SLA за доступністю.
1) Ландшафт джерел і форматів
1. 1 Джерела
PSP/еквайєри/агрегатори: транзакції, сети, комісії, диспути.
Банки: виписки MT940, ISO 20022 CAMT. 052/053/054, платежі PAIN. 001/002.
АРМ/гаманці/виплати (OCT/RTP/SEPA): реєстри payouts, повернення.
Крипто-кастоді/біржі: он-чейн транзакції, звіти конвертацій/комісій.
Податки/гос. портали: CSV/XLSX/PDF, іноді через скриптований браузер.
1. 2 Формати
CSV/TSV (варіативні роздільники, локалі, кодування).
XLSX (мульти-шит, об'єднані комірки).
XML (ISO 20022 CAMT/PAIN, кастомні схеми XSD).
SWIFT MT940/942 (позиційні поля).
JSON-API/NDJSON (інкрементальні вивантаження, курсори).
PDF (табличні - парсер; скани - OCR).
ZIP/TAR. GZ (батчі з декількома файлами).
2) Архітектура ingestion-пайплайну
Контури:1. Landing: безпечне приймання файлів (SFTP/FTPS/WebDAV/API/webhooks) → негайно вважаємо checksum, зберігаємо сировину незмінно.
2. Raw: розкладка по датах/провайдерам/батчам, зберігання з версіями.
3. Normalize: парсинг → уніфікація типів/одиниць → normalized таблиці.
4. Validated: пост-валідації (правила якості) → прапори, DLQ.
5. Matched: зіставлення з внутрішніми подіями/банком.
6. Serving/BI: вітрини для звірки/фінансів/операцій.
Ключові вимоги:- Ідемпотентність ingestion: '(provider, file_name, file_size, checksum, statement_date)'→ унікальний ключ.
- Повтори/ретраї: повторне проганяння файлу не створює дублів.
- DLQ (dead-letter queue): все нерозпізнане/порушило правила - в ізольовану чергу.
- Версіонування: новий файл за той же день → нова версія з посиланням на попередню.
3) Безпека доставки і секретів
Канали: SFTP з обмеженими ключами; FTPS - тільки при строгому TLS; API - OAuth2/токени з коротким TTL.
Шифрування контенту: PGP/GPG при завантаженні файлів; S/MIME для e-mail-інбоксів (якщо використовуються).
Контроль цілісності: SHA-256/512 checksum, порівняння з хешем в маніфесті.
Секрети: зберігати в Vault/KMS, ротація, заборонені в конфіг-файлах/логах.
Доступи: RBAC + принцип «найменших привілеїв», окремі сервіс-акаунти.
4) Нормалізація і схема даних
4. 1 Універсальні правила
Час: завжди UTC в ISO-8601; для дат settlement -'DATE'без TZ.
Суми: 'DECIMAL (p, s)'в minor units + окремий'scale'; знак: прихід/витрата строго за словником.
Валюти: ISO-4217, фіксована таблиця курсів з'fx _ src'.
Локалі: заборона автодетекту - явне налаштування роздільників/десяткової точки/тисячних.
Кодування: вхід в UTF-8; інші - конвертація з логом.
4. 2 Нормалізований «плоский» шар (приклад)
json
{
"provider": "Acquirer_A",
"source_kind": "PSP_TX PSP_SETTLEMENT BANK WALLET CRYPTO",
"kind": "AUTH CAPTURE REFUND PAYOUT FEE SETTLEMENT CHARGEBACK",
"payment_id": "pay_123", // ваше
"provider_txid": "psp_abc_789", // внешнее
"merchant_ref": "mr_456",
"sequence": 0, // partial/refund line index
"amount_minor": 100000, // 1000.00
"currency": "EUR",
"fee_minor": 120, // 1.20
"fx_rate": 1.0000,
"fx_src": "PSP ECB BANK",
"event_ts": "2025-11-03T12:00:00Z",
"value_date": "2025-11-05",
"account": "PSP_MERCHANT_CARD_A",
"bin": "425000",
"last4": "1234",
"status": "APPROVED CAPTURED SUCCESS FAILED SETTLED",
"file_id": "ing_20251103_001",
"row_hash": "sha256(raw_row)"
}
5) Парсери за форматами: прийоми та граблі
5. 1 CSV/TSV
Явно задавайте'delimiter','quotechar','escapechar','encoding'.
5. 2 XLSX
Читання по sheet whitelist; заборона автосліянь - розплющування об'єднаних осередків.
Перетворення формул на значення; дати Excel → UTC з явною TZ.
5. 3 XML (ISO 20022 CAMT/PAIN)
Валідація по XSD; XPath-маппінг реквізитів ('< Ntry>','< TxDtls>','< Amt>','< CdtDbtInd>').
Нормалізація credit/debit → знак; підтримка множинних'< Chrgs>','< RmtInf>'.
5. 4 MT940
Розбір тегів':61:`, `:86:`; підтримка національних розширень; позиційні поля → правила slicing.
Консолідація декількох':61:'в один батч.
5. 5 JSON/NDJSON/API
5. 6 PDF/OCR
Спершу спроба табличного парсингу (таб-детектор), тільки потім OCR (Tesseract) з whitelist символів.
Пост-валідація: суми, контрольні підсумки, звірка кількості рядків.
5. 7 Архіви/батчі
Розпакування зі збереженням структури; кожному файлу - окремий'file _ id'; маніфест, контроль всіх частин.
6) Валідації та правила якості даних
Обов'язкові перевірки:- Схема: всі required поля присутні.
- Типи: суми - числові, дати - парсяться.
- Контрольні суми/підсумки: сума рядків = підсумок у файлі (якщо є).
- Діапазони: дата в розумному вікні; сума> 0 (або за словником допустимих негативних).
- Унікальність: '(provider, provider_txid, sequence)'не дублюється в normalized.
- Толеранси: допустимі розбіжності'amount/fx/time'.
Результат: `VALID`, `VALID_WITH_WARNINGS`, `INVALID → DLQ (reason_code)`.
7) Ідемпотентність і дедуплікація
Ingestion key: '(provider, file_name, filesize, checksum, statement_date)'→ єдиний'file _ id'.
Row-level idem: `row_hash = sha256(normalized_row_compact)`; повторне завантаження не створює нових записів.
Webhooks/API: 'idempotency _ key'провайдера + ваші мітки ('exec _ id'), зберігати TTL.
Дублі провайдера: дедуп по'provider _ txid'+'sequence', при розбіжності - в DLQ_DUPLICATE.
8) Оркестрація та розклади
Оркестратор: Airflow/Dagster (DAG: `fetch → decrypt → parse → normalize → validate → publish → match`).
SLA/SLO: 'Time-to-Availability (TtA)'від появи файлу до'normalized = READY'.
Ретраї: експоненціальний backoff + jitter; ліміти спроб; чіткі статуси.
Паралелізм та ізоляція: важкі OCR/парсинг XLSX - в окремому пулі/воркері з лімітом CPU/RAM.
DLQ-replay: періодичний reprocess при оновленні правил/маппінгів.
9) Спостережуваність і алерти
Метрики:- Ingestion Success%, Parse Success% за джерелами.
- TtA p50/p95, Throughput (рядків/хв).
- DLQ Rate и Aging DLQ p50/p95.
- Schema Drift Incidents (зміна заголовків/формату).
- Duplicate Rate по `provider_txid`.
- `TtA p95 > SLA` → P1.
- 'DLQ Rate> 2%'за годину по провайдеру → P1.
- 'Schema Drift detected'→ P0 (зупинка авто-матчингу за джерелом).
- 'Duplicate spike'→ P2 (перевірити провайдера/вебхуки).
Дашборд: воронка'files , карта DLQ з причин, TtA-квантилі.
10) Автокорекції та маппінги
Header aliases: словник з версіями (e. g., `Amount`→`amt`, `AMOUNT`→`amt`).
11) Зв'язок з «Звіркою платежів і звітів PSP»
Готовий normalized шар - вхід для матчингу (provider_txid/merchant_ref/fuzzy), розрахунку diff-таксономії, авто-журналів і settlement↔bank -зшивки. Ключові поля: `provider_txid`, `sequence`, `kind`, `amount_minor`, `value_date`, `account`.
12) Модель сховища та таблиці
Таблиця landed файлів:sql
CREATE TABLE landed_files (
file_id TEXT PRIMARY KEY,
provider TEXT,
source_kind TEXT,
file_name TEXT,
file_size BIGINT,
checksum TEXT,
statement_date DATE,
received_at TIMESTAMP WITH TIME ZONE,
version INT,
status TEXT, -- RECEIVED PARSED FAILED error TEXT
);
Нормалізовані рядки:
sql
CREATE TABLE psp_norm (
row_id BIGSERIAL PRIMARY KEY,
file_id TEXT REFERENCES landed_files(file_id),
provider TEXT,
source_kind TEXT,
kind TEXT,
payment_id TEXT,
provider_txid TEXT,
merchant_ref TEXT,
sequence INT,
amount_minor BIGINT,
currency CHAR(3),
fee_minor BIGINT,
fx_rate NUMERIC(18,8),
fx_src TEXT,
event_ts TIMESTAMPTZ,
value_date DATE,
account TEXT,
status TEXT,
row_hash TEXT UNIQUE,
repair_flags TEXT[]
);
CREATE INDEX idx_psp_norm_txid ON psp_norm(provider, provider_txid, sequence);
13) Псевдокод парсерів
CSV/XLSX:python def parse_table(file, spec):
df = load_csv_or_xlsx(file, delimiter=spec.delim, encoding=spec.enc, sheet=spec.sheet)
df = rename_headers(df, spec.header_aliases)
df = clean_amounts(df, thousand=spec.thousand, decimal=spec.decimal, sign_policy=spec.sign)
rows = []
for r in df.itertuples():
rows.append(normalize_row(r, spec))
return rows
XML CAMT:
python def parse_camt(xml):
root = parse_xml(xml, xsd="camt053.xsd")
for ntry in root.findall('.//Ntry'):
sign = 1 if ntry.findtext('CdtDbtInd') == 'CRDT' else -1 amt = Decimal(ntry.findtext('Amt')) sign
... map to normalized fields
OCR PDF (fallback):
python def parse_pdf_ocr(pdf):
text = tesseract(pdf, lang="eng", psm=6, whitelist="0123456789.,-;:/A-Za-z")
table = detect_table(text)
return normalize_table(table)
14) GDPR/PII і редагування логів
Маскування/хешування: PAN/email/телефон →'sha256 + salt', логи - без первинних значень.
Політика зберігання: «retention» за типом джерела (AML/бухоблік).
Доступи до PII - тільки за роллю; аудит читань/експортів.
15) KPI і цілі (для парсингу/ingestion)
Ingestion Success % ≥ 99. 5 %/день на джерело.
Parse Success % ≥ 99%, DLQ ≤ 1%.
TtA p95 (fayl→normalized) ≤ 15 хвилин (CSV/XML), ≤ 60 хвилин (PDF/OCR).
Schema Drift Incidents: 0/місяць без алерта/фікса.
Duplicate Rate по `provider_txid` ≤ 0. 05%.
16) Плейбуки інцидентів
Schema drift: стоп авто-матчингу, включити «м'який» парсер з ML-детектом колонок, підготувати alias-патч, прогнати DLQ-replay.
Сплеск DLQ: налагодження останніх файлів, перевірка кодування/локалі/знака, тимчасово знизити строгість толерансів (з прапором).
Затримки SFTP: перемикання на API-polling/вебхуки, збільшення ретраїв, комунікація з провайдером.
Spikes duplicates: увімкнути доперевірку'row _ hash', блок повторів до з'ясування.
17) Тест-кейс-пакет (UAT/Prod-готовність)
1. Ідемпотентність: повтор того ж завантаження → 1'file _ id', 0 нових рядків.
2. Локалі: файли з', '/'. '/пробілами → коректні суми.
3. Partial/refund: кілька'sequence'до одного'provider _ txid'.
4. XML XSD: невалідний CAMT →'INVALID'+ DLQ.
5. MT940 варіації: національні розширення → коректний розбір.
6. PDF→OCR: скан з шумом → витяг і проходження базових правил.
7. Schema drift: новий хедер → alias-патч і повторна обробка історичних файлів.
8. Throughput: навантажувальний тест N файлів/год → дотримання TtA SLA.
9. PII-редакція: логи без PAN/e-mail, тільки хеші.
18) Чек-лист впровадження
- Реєстр джерел: протокол, розклад, SLA, формат, контакт.
- Безпечні канали (SFTP/PGP/API), Vault для секретів.
- Ідемпотентний ingestion + checksum + версії.
- Парсери за форматами, alias-словник, sign/locale-політики.
- Нормалізований шар та індекси ключів.
- Правила валідацій, толеранси, DLQ і replay.
- Оркестратор (DAG), ретраї/backoff, пули ресурсів.
- Спостережуваність: метрики, дашборди, алерти.
- GDPR/PII-маскування, аудити доступу.
- Тест-кейси і регулярні schema-drift drills.
Резюме
Автоматизація парсингу - це не «написати парсер», а вибудувати промисловий контур: надійна доставка і шифрування, ідемпотентні пайплайни, сувора нормалізація, правила якості і прозорі алерти. Такий контур перетворює будь-які реєстри в передбачувані таблиці з гарантованим SLA за доступністю даних - фундамент для звірок, казначейства та управлінської звітності.