Перейти до вмісту

Парсер даних вступу (abitly-parse)

ПолеЗначення
ПродуктAbitly
Типworker / ETL
Статус🟢 prod
ВласникTODO:

Парсить дані вступної кампанії — реєстр ЗВО, конкурсні пропозиції (offers), заяви вступників (offer_requests), спеціальності, квоти — з ЄДЕБО та допоміжних джерел і завантажує їх upsert-ами у Postgres (схема abitly) одночасно в dev і prod. Це головне джерело «сирих» вступних даних для API та симуляції.

Репозиторій та рантайм

Section titled “Репозиторій та рантайм”
Репоhttps://github.com/abitly-org/abitly-parse
ХостингAWS ECS Fargate scheduled task abitly-prod-web-parser (EventBridge cron(0 9,14,20 * * ? *) — тричі на день) + ручні запуски локально
Спосіб деплоюDocker image → ECR; CMD = python pipeline.py refresh-current --no-refresh-offers --targets dev,studsearchprod
Публічні URL / доменинемає (batch worker)
ДжерелоЩо даєКлієнт
registry.edbo.gov.uaреєстр ЗВО, контакти приймальних комісійcommon/registry.py (Server Actions)
vstup.edbo.gov.ua (+ архівні vstup{year})offers, заяви вступників; live-портал 2026 — RSA+AES-шифрований APIcommon/vstup_current.py, common/edbo_crypto.py
abit-poisk.org.uaПІБ вступників, fallback-рейтинги коли ЄДЕБО лежитьcommon/abitpoisk.py
vstup.osvita.uaквоти (max_quota1/max_quota2)common/osvita.py (scrapling)

Стадії per-таблиця: fetch → build → link → load (FK-порядок: universities → faculties → specialities → offers → offer_requests). Сирі відповіді кешуються у файли (cache/**/*.jsonl.gz, на Fargate — EFS abitly-prod-web-parser-cache). Load — ідемпотентний INSERT … ON CONFLICT DO UPDATE; прохідні бали — fill-only (COALESCE), квоти — sticky-zero. Колонки score_map, prediction_status, explanation парсер не заповнює — їх пишуть API (POST /offers/admitted-scores/populate) і симуляція.

Gates перед записом: FK-preflight, blocked-build при нерозпізнаних назвах/спеціальностях, fewer-entries safeguard для fallback, table_metadata.last_updated як freshness-маркер.

  • Залежить від: зовнішніх порталів ЄДЕБО/abit-poisk/osvita, Postgres (dev і prod через SSM-тунелі), Claude CLI (LLM-enrich назв факультетів/ЗВО)
  • Від нього залежать: API, vstup-simulation, аналітика вступу

Лише назви. Повний індекс: environments.

ЗміннаПризначенняДе зберігається
DB_NAME / DB_USER / DB_PASSWORD / DB_SSLMODEпідключення до цільових БДSSM /abitly/prod/web-parser/DB_*_DEV, DB_*_STUDSEARCHPROD
SSM_INSTANCE_ID[_DEV/_PROD]тунельні інстанси для локальних запусківлокальний .env
ABITPOISK_VERIFYвимкнення SSL-перевірки abit-poiskлокальний .env
CLAUDE_BINшлях до claude CLI для enrichлокальний .env
Terminal window
python pipeline.py fetch # повний sweep усіх джерел
python pipeline.py refresh-current \
--no-refresh-offers --targets dev,studsearchprod # live-цикл кампанії (те, що крутиться в проді)
python pipeline.py admissions --year 2026 # build offers + requests + link + passing
  • Інкрементальний fetch (--no-refresh-offers) не бачить нові КП у вже закешованих ЗВО → періодично потрібен повний --refresh.
  • SSM-тунель відвалюється на довгих load (~28 хв) → chunked-транзакції вже вбудовані, але ручні запуски можуть падати.
  • Fallback на abit-poisk лишає content-keyed ids у БД → після відновлення ЄДЕБО потрібен offer_requests cleanup --load (маркер cache/vstup/current/fallback_usage.json).
  • Дані «зникли/протухли» на сайті → перевір abitly.table_metadata.last_updated і runbook Typesense.
  • ЄДЕБО блокує/капчить: жорсткий бан (403/429) → retry+backoff → SystemExit, БД лишається stale-but-intact; «тихий» блок (200 + порожнє тіло) приймається як валідні дані — ризик регресії каталогу. Проксі не підтримується, алертів на фейл таски немає — деталі й план у data-архітектурі (слабке місце №14).

Повна картина потоків даних → data-архітектура.