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

Live-дашборд «Вступ 2026»

ПолеЗначення
Статус🚧 задеплоєно на Cloudflare Pages за Cloudflare Access (приватно, лише власник); публічно ще не відкрито
Поверхніокремий дашборд на CF Pages (edge-static), не web-app abitly.org
Доступністьнаразі приватно (email-SSO власника); публічне відкриття — рішення власника
ВласникTODO:
Останнє підтвердження2026-07-20 · CF Pages live (за CF Access) + read-only pull прод-БД + Playwright-рев’ю графіка

Живий публічний дашборд перебігу вступної кампанії-2026: подані заяви, конкурс, найпопулярніші напрями/ЗВО, розподіл балів НМТ і «Гонка спеціальностей» — як прогноз попиту із симулятора Abitly переходить у реальні подані заяви. Дизайн — темний, мінімалістичний (monobank-teardown), кожен блок самодостатній для скріншота в канал/медіа. Усе на реальних даних.

Три плани даних (усі реальні):

  • ЄДЕБО (vstup.edbo.gov.ua/statistics/date) — національний попит: заяви/особи за днями (снапшот: 327 795 заяв / 185 337 осіб).
  • Abitly Prod DB (studsearch-prod, схема abitly) — 92 401 бюджетне місце, 25 223 абітурієнти-2026, конкурс 3,5, продуктові вибори напрямів/ЗВО.
  • УЦОЯО — розподіл балів НМТ-2025 (пул-2026 складав ті самі тести).

Архітектура: snapshot-once, read-from-cache

Section titled “Архітектура: snapshot-once, read-from-cache”

Дашборд публічний і може отримати вірусний сплеск (репост у медіа) — тому жоден візит не торкається БД. Уся важка робота виконується рідко плановим джобом і матеріалізується в один незмінний snapshot.json (~6 КБ); сайт — статика, читає лише цей файл з CDN. 100 000 відкриттів/годину = 100 000 віддач з edge і 0 запитів у Postgres (БД бачить лише 2 запуски генератора на добу).

flowchart LR
  edbo["ЄДЕБО статистика<br/>(scrape)"] --> build
  prod[("Prod DB 2026<br/>read-only, PII-free")] --> build
  ucoqo["УЦОЯО НМТ-2025<br/>(baked)"] --> build
  build["build_snapshot.py"] --> snap["snapshot.json"]
  snap --> cdn["CDN edge (Cloudflare)"]
  cdn -->|"0 запитів у БД"| browser["браузер · inline-SVG, 0 залежностей"]

Клієнт (app.js, vanilla, 0 залежностей) малює всі графіки інлайновим SVG; fetch('data/snapshot.json') — один запит на візит, повністю з CDN.

  1. Hero — заяв подано у кампанії (велика цифра) + KPI: абітурієнти, заяви/особу, бюджетні місця, конкурс.
  2. «Заяви за днями» — кумулятивна крива поданих заяв (ЄДЕБО), hover за будь-який день.
  3. «Найпопулярніші спеціальності / ЗВО» — дві смуги: помаранчева = унікальні абітурієнти, що розглядають напрям у симуляторі Abitly (з 19 липня), синя = унікальні особи, що вже подали заяви в ЄДЕБО.
  4. «Гонка спеціальностей у часі» — стрімграф прогнозу + перемикач «Прогноз → реальні заяви» (див. нижче).
  5. «Розподіл балів НМТ · де мій бал» — інтерактивна гістограма УЦОЯО-2025: обери предмет, встав свій бал → перцентиль.
  6. Roadmap — ключові дати за Порядком прийому-2026.

«Гонка спеціальностей у часі» — ключовий графік

Section titled “«Гонка спеціальностей у часі» — ключовий графік”

Хендрольнутий SVG-стрімграф (центрована wiggle-база, inside-out порядок шарів, Catmull-Rom згладжування) у тому ж 0-залежному ідіомі, що й решта графіків. Має два режими через перемикач.

Режим OFF — прогноз (намір). X = дні (28.06 → сьогодні), кожна смуга — напрям, ширина = кумулятивна кількість унікальних абітурієнтів-2026, що тримають напрям пріоритетом №1–2 у своєму списку в симуляторі. Топ-12 напрямів + згорнутий хвіст «Інші»; hover показує склад пулу за будь-який день. Щоденна історія попиту копиться append-only знімками у схемі admission_timeline (abitly_dev) і вплітається у snapshot.json (початково крива реконструювалася з simulation_application.createdAtmin(createdAt) рядків із пріоритетом 1/2; аудит-логу змін КП немає, тож минулі видалення/перепріоритезації історично не відновлюються).

Режим ON — «Прогноз → реальні заяви». Смуги продовжуються з прогнозу в реальність: ліворуч від пунктирної межі — намір (та сама щоденна крива), праворуч кожна смуга «перетікає» в те, куди абітурієнти реально подали заяви тим самим пріоритетом №1–2 — за опрацьованими рейтинговими списками ЄДЕБО-2026 (wide_competition.applications, дедуп за особою). Той самий метрик з обох боків, тож морф «яблуко-до-яблука». Знімок: прогноз 5 229 у топ-2 → реальність 9 726 (8 370 унікальних осіб). Наочно видно розрив намір≠факт: Психологія 179 → 539, Медицина 187 → 385, тоді як деякі (Економіка, Міжнародні відносини) просіли.

Немає api-v2 — дашборд статичний, читає лише snapshot.json. Генератор (collect_prod_db.sh + build_snapshot.py) тягне агрегати read-only:

ДжерелоEntity / запитПризначення
ЄДЕБОvstup.edbo.gov.ua/statistics/date (scrape)національні заяви/особи за днями
Prod DBsimulation_application + offers + specialities + usersпрогноз-стрімграф (пріоритет 1/2 по днях) і топ напрямів/ЗВО
Prod DBwide_competition.applications (пріоритет 1/2, дедуп pib)реальність для морфу прогноз→факт + сині смуги ЄДЕБО-осіб
Prod DBoffers (max_budget_licence, year=2026)бюджетні місця, конкурс
Prod DBpremium_ordersпродуктові показники (продажі симуляції)
УЦОЯОстатичний агрегат НМТ-2025 (data/nmt_2025.json)гістограма «де мій бал»

Похідне у snapshot.json: cohort.spec_stream = {days[], series[{code,name,data[],reality}] + «Інші», reality_total, reality_people}. Деталі write-path, кешування й SQL — в ARCHITECTURE.md артефакту.

Зв’язки з іншими фічами

Section titled “Зв’язки з іншими фічами”
  • simulation — джерело прогнозу (пріоритет №1–2 у конструкторі вступліста); стрімграф — його агрегат у часі.
  • wide-competition — той самий реальний план даних (wide_competition.applications); дашборд бере з нього «реальність».
  • priorities — пріоритет заяви, за яким рахується топ-2 з обох боків морфу.
  • abitly-analytics — сусідня аналітична поверхня (abitly.org/analytics); дашборд — окремий publish-канал тієї ж моделі «снапшот замість live-обчислень».

Гітігнорний артефакт у хаб-воркспейсі (не в публічному репо):

ШляхПримітка
.context/vstup-2026-live/index.htmlструктура сторінки (блоки-картки)
.context/vstup-2026-live/assets/app.jsрендер + анімації + інтерактив (inline-SVG, 0 залежностей); renderStreamgraph() з морфом прогноз→реальність
.context/vstup-2026-live/assets/style.cssдизайн-система (dark, one-accent + стрім-палітра)
.context/vstup-2026-live/build_snapshot.pyгенератор снапшота (зливає джерела → snapshot.json)
.context/vstup-2026-live/collect_prod_db.shwrite-path: read-only агрегати з прод-БД (SSM-тунель, statement_timeout, PII-free)
.context/vstup-2026-live/ARCHITECTURE.md, README.mdархітектура даних/кешування + запуск
  • Приватний за Cloudflare Access: задеплоєно на CF Pages (abitly-vstup-live.pages.dev), але вхід лише для власника (email-SSO); публічне відкриття — рішення власника.
  • Реальність — знімок без щоденної історії (немає часової осі в wide_competition/offer_requests), тож права частина морфу — кінцева точка, а не крива.
  • Часткове покриття реальності: wide_competition.applications — лише опрацьовані рейтингові списки (≈10,8 тис. осіб, зростає, коли ЗВО обробляють заяви); прогноз — вибірка симулятора (~25 тис. абітурієнтів).
  • Пріоритет прогнозу «пінується» до createdAt вцілілих рядків (немає аудит-логу КП) — минулі перепріоритезації/видалення не видно.
  • Оновлення даних — рідко (планово 2×/добу / вручну), не realtime; бейдж свіжості показує «станом на …» чесно.
  • Команда-виключення застосована; у snapshot.jsonнуль ПД (лише агрегати).
ДатаПодіяДжерело
2026-07-19Дашборд-каркас: hero, крива заяв, топ спеціальностей/ЗВО, НМТ-розподіл, roadmap; snapshot-пайплайн (ЄДЕБО + Prod DB + УЦОЯО → snapshot.json → CDN); Playwright-рев’юартефакт .context/vstup-2026-live/
2026-07-20Стрімграф «Гонка спеціальностей» — прогноз попиту (пріоритет №1–2, кумулятив по днях, топ-12 + «Інші»), хендрольнутий SVG (wiggle + inside-out + Catmull-Rom)collect_prod_db.sh (spec_stream), build_snapshot.py, renderStreamgraph()
2026-07-20Перемикач «Прогноз → реальні заяви»: морф кожної смуги з прогнозу в реальні подані заяви ЄДЕБО тим самим пріоритетом (пунктирна межа + зона «реальність · зараз»); реальність — знімок, перехід — лінійний морфwide_competition.applications (spec reality), renderStreamgraph({reality:true})