«Широкий конкурс у живому часі»
Метадані
Section titled “Метадані”| Поле | Значення |
|---|---|
| Статус | 🟢 prod (ран 2026 активний); UX-пакет 2026-07-25 — на проді |
| Поверхні | web |
| Доступність | публічно; гості бачать топ-14 рядків рейтингу → register-гейт (AuthPopupOverlay), пошук/фільтри приховані |
| Власник | TODO: |
| Останнє підтвердження | 2026-07-25 · прод: 13 колонок кортежа з educationProgram, lastRecommendedPosition 30506 на Б37д, cut-line-page 17 (фільтр) vs 62 (без) |
Призначення
Section titled “Призначення”Показати абітурієнту, хто саме проходить у межах його групи широкого конкурсу
(напр. Б27дз) — за результатами прогону нашого симулятора адресного розміщення
(Наказ МОН №373, Додаток 6), а не за офіційними списками, яких ще немає.
Це те, чого немає в ЄДЕБО: прохідний бал кожної доріжки (субконкурсу),
поіменний список усіх заяв групи зі статусом-результатом алгоритму
(рекомендовано / відмовлено / не розглядалась / анульовано / не допущено),
підсвічена людина-визначник прохідного (заява, чий бал і є прохідним групи;
серверний прапорець is_cutoff, ties можливі) і прямі переходи на сторінку КП
та пошук вступника.
2025 — факти, не симуляція: кампанія завершена, тож активний ран 2025
зібраний разовим імпортером з сирих фінальних даних ЄДЕБО + канонічних прохідних
native-варіанта (min_passed_calc/osvita/native/passing_scores_native.html) —
значення на сторінці збігаються з цим документом 1:1 (3 знаки: Б29д = 182.896).
Симуляція по обкатаному флоу — для кампанії 2026.
Контракт v2: доріжки лише бюджетні — широкий конкурс розподіляє виключно держзамовлення; контрактний конкурс іде per-КП (без суперобсягу) і його рейтинг живе на сторінці КП, куди веде колонка «Код КП».
User flow
Section titled “User flow”Точка входу: https://abitly.org/wide-competition
- Користувач відкриває індекс і шукає свою групу — за назвою групи, кодом (
Б37дз), назвою спеціальності («Інженерія програмного забезпечення») або її кодом (F2). Спеціальності групи показані на картці, тож видно, чому група знайшлась. Фільтри: форма навчання + рік вступу (2025 · 2026). - Картка групи показує прохідний бал загальної доріжки. Рік без активного рану (2026 до імпорту) — порожній стан «дані зʼявляться після 19 липня», не помилка.
- Переходить на
/wide-competition/b27dz-denna. - Бачить шапку: назву групи, спеціальності, «оновлено N хв тому» і одну плитку —
прохідний бал активної доріжки. Суперобсяг і «проходять» зі сторінки прибрані;
бейдж «недобір» теж (число показується як є). Провенанс (
passingFrom) далі приходить у контракті й використовується в SEO-меті — сніпет не публікує поріг допуску як прохідний бал. - Перемикає доріжки (4): Загальний конкурс · Квота-1 · Квота-2 · Співбесіда/творчий.
Порожні — disabled із підказкою. Бейдж вкладки = учасників (
total), не розміщених. На квотних доріжках прохідний бал — «—» з поясненням (механіка квот вимкнена, див. «Обмеження»); маркер «прохідний» у списку заяв там не малюється. Квотник видний і у своїй квоті, і в загальному — це fallback Додатку 6, не дубль-помилка. - Дивиться список усіх заяв доріжки з кольоровим статусом-пілюлею. У 2025
(факти) зараховані мають статус «До наказу (бюджет)» (
enrolled), а не «Рекомендовано» — «рекомендовано» лишається прогнозам симулятора 2026 і 162 фінально-рекомендованим без зарахування. Рядок людини-визначника прохідного підсвічений зеленим з бейджем «прохідний» (сервернийis_cutoff; при рівності балів підсвічені всі — у Б37дз:денна їх 7), а одразу під ним — пояснювальна смуга (лише 2025): «Усі, кого зараховано на бюджет нижче цієї позиції, зайшли за квотами або були переведені на вакантні бюджетні місця». Фільтрує за статусом (dropdown показує лише наявні в доріжці статуси з лічильниками). - Шукає себе за прізвищем: пошук — серверний фільтр (апостроф-нечутливий), але позиції в рядках глобальні, тож ранги видно й у відфільтрованому списку.
- Догружає рейтинг кнопкою «Показати ще» (батчі по 500; лічильник «показано X з Y»).
- Клікає ПІБ →
/applicants?search={ПІБ}(пошук вступників із підставленим прізвищем; прихований ПІБ — без лінка). Клікає Код КП →/offers/result/{offerId}(сторінка конкурсної пропозиції). Обидва — у новій вкладці.
Дані та API
Section titled “Дані та API”| Джерело | Ендпоінт / entity | Призначення |
|---|---|---|
| api-v2 | GET /wide-competition/groups?year= | селектор груп + specialities[] і прохідний бал general на кожній групі; рік без рану → 404 (порожній стан, не помилка) |
| api-v2 | GET /wide-competition/:slug | шапка + 4 доріжки: прохідний + passingFrom, placed, total, statusCounts |
| api-v2 | GET /wide-competition/:slug/applications?via=&status=&search=&page=&limit= | сторінка рейтингу доріжки (tuple-encoded, пагінація) |
| api-v2 | GET /wide-competition/:slug/applications/cut-line-page?position=&<фільтри> | яка сторінка цього (відфільтрованого) списку містить межу — для кнопки «До прохідного балу»; ранги всередині фільтра серверні, клієнт їх не знає |
| Postgres | схема wide_competition (runs, groups, lanes, applications, offer_cutoffs) | immutable рани |
abitly-vstup-simulation | scripts/ingest/import-wide-2025-final.mjs + min_passed_calc/osvita/native/export-determinants.mjs | активний ран 2025: фінальні заяви ЄДЕБО + канонічні прохідні native + визначники (is_cutoff) |
abitly-vstup-simulation | placement/ (движок) + scripts/ingest/import-wide-run.mjs (імпортер) | 2026+: один прогін simulate() → рейтинги + прогнозні прохідні КП (offer_cutoffs) одним раном |
Повний контракт схеми й ТЗ імпортера — docs/wide-competition/schema-contract.md.
Зв’язки з іншими фічами
Section titled “Зв’язки з іншими фічами”- simulation — «Стан 2» тієї картки описує саме цей прогін; ця сторінка показує його результат публічно.
- priorities — пріоритет заяви визначає, на якій доріжці людина осідає.
- vstup-live-dashboard — публічний дашборд бере звідси «реальність» (
wide_competition.applications, пріоритет 1/2) для морфу прогноз→факт у «Гонці спеціальностей». - Пошук вступників (
/applicants, окремої картки поки немає) — ПІБ у рядку веде туди з підставленим прізвищем.
| Репо | Шлях | Примітка |
|---|---|---|
abitly-frontend-v2 | src/app/[locale]/(main)/wide-competition/ | роути (індекс + [group]) |
abitly-frontend-v2 | src/components/pages/wideCompetition/ | UI: віртуалізований список + «показати ще», StatusPill, фільтр |
abitly-api-v2 | src/api/wideCompetition/ | read-only модуль, пагінація/фільтри |
abitly-api-v2 | src/database/migrations/1784700000000-CreateWideCompetition.ts | схема (amend v2) |
abitly-vstup-simulation | scripts/ingest/seed-wide-dev.mjs | дев-фікстура v2 (dry-run без --yes) |
Обмеження та блокери
Section titled “Обмеження та блокери”- Симуляційні рани не ставлять
is_cutoff(движковий bind-визначник — окрема задача), тож зеленої підсвітки визначника на ранах 2026 немає. Саме тому кнопка «До прохідного балу» шукає межу заlastRecommendedPosition, а не за цим прапорцем. - Квотні доріжки без прохідних (
passing_score = NULL, UI показує «—»): native квотних прохідних не рахує, симулятор квоти поки вимкнув. Списки заяв на вкладках Квота-1/2 при цьому повні. ББ увімкнути нічим — сигналу немає. - «Знайти мене» (заділ):
offer_request_idрозв’язаний у 94.07% рядків рану 2025; тезки з тим самим балом та відсутні в дев заяви — NULL. - Дрібне: визначник групи
b11dz-dennaмає артефактний ПІБ у самому джерелі («7220-7501607 М. Є.») — показується як є. - Неопубліковані групи: поріг
placed_total < 10(3 групи 2025) + явний denylistUNPUBLISHED_SLUGS—b24dz-zaochna(рішення власника 2026-07-15: держзамовлення 2 місця, floor-недобір — конкурсу в списку немає). - Доступ ще не вирішено (публічно / за акаунтом / за entitlement
simulation).
Історія змін
Section titled “Історія змін”| Дата | Подія | Джерело |
|---|---|---|
| 2026-07-09 | Схема wide_competition + read-API + сторінки; гілка feat/wide-competition від dev/development | commit 7aa7ebd (api), a935aebd (web) |
| 2026-07-11 | Контракт v2: усі заяви зі статусами + фільтр, лінки «Код КП»/ПІБ, серверна пагінація, вкладку «Контракт» прибрано (конкурсу на контракт не існує), движок віддає subcompetitions, сід v2 | гілка feat/wide-competition (обидва репо) + seed-wide-dev.mjs |
| 2026-07-14 | SEO сторінок (мета в messages/meta/, canonical/hreflang, OG, JSON-LD, FAQ-блок, sitemap груп); пошук за спеціальністю (specialities[] у списку груп, крапкові коди успадковують назву батьківського); спрощення UI: картка показує прохідний бал замість «місць/осіб», зі сторінки прибрано суперобсяг, «проходять» і бейдж «недобір»; квотні доріжки показують «—»; фільтр по роках (2025 · 2026) | гілка feat/wide-competition (обидва репо) |
| 2026-07-15 | Контракт v3: канонічний ран 2025 «фінали» (заяви з сирого ЄДЕБО-CSV — дев зливав накази бюджет/контракт і труїв recommended; прохідні = native wide_min, Б29д 130.00→182.896); is_cutoff (визначник прохідного, 87 людей у 72/72 конкурентних групах) наскрізь БД→API (tuple v3)→UI замість kb-евристики; точність балів numeric(6,3); +6 груп медицини/вет БМ1д–БМ6д (магістр на ПЗСО) | import-wide-2025-final.mjs, export-determinants.mjs, гілка feat/wide-competition (обидва репо) |
| 2026-07-15 (2) | Статус enrolled «До наказу (бюджет)» для фінальних ранів (зараховані ≠ «рекомендовано»; словник +1, «розміщені» = enrolled+recommended) + пояснювальна смуга під визначником (лише 2025): нижче — квоти або переведення на вакантні місця | application_status_enum, cutoffNote у ApplicationsList |
| 2026-07-15 (3) | b24dz-zaochna знята з публікації (denylist UNPUBLISHED_SLUGS: держзамовлення 2 місця, floor — конкурсу немає); видимих груп 2025 — 70 | wideCompetition.constants.ts |
| 2026-07-22 | 🟢 prod: register-гейт для гостей — топ-14 рядків рейтингу → блюр + AuthPopupOverlay, пошук/фільтри приховані | fe#600 (main) + fe#601 (development) |
| 2026-07-25 | UX-пакет на dev: колонка «Освітня програма» (educationProgram = 12-й елемент кортежа, read-time lookup offers.education_program); нумерація з 1 при статус-фільтрі; кнопка «До прохідного балу» (scrollToIndex + підсвітка, гості → гейт); точний час оновлення (Europe/Kyiv) поруч із «N тому»; tooltip суперобсягу + примітка-джерело ЄДЕБО global-order; зірочку/примітку carryover-2025 прибрано; тултіпи «Недобір»/«Широкий конкурс» переписані зрозуміліше | api#618 (dev) + fe#615 (development) |
| 2026-07-25 (2) | «До прохідного балу» працює на всіх доріжках: лейн віддає lastRecommendedPosition (позиція останнього з бюджетним місцем), фронт шукає рядок за позицією й переякорює список на потрібну сторінку (startPage у ключі infinite-query) замість гортання. Причина: 2026-рани не мають is_cutoff узагалі, а в «Недобір»-групах межа = поріг допуску й лежить на дні рейтингу (Б01д 3096/3122, Б37д 30506/30774 — стрибок 1.6 с проти ~60 запитів). +кнопка «На початок списку» | api#620 (dev) + fe#618 (development) |
| 2026-07-25 (3) | «До прохідного балу» працює й під фільтрами (раніше кнопка зникала — а «Проходить (Б)» саме той зріз, де межа є останнім рядком). Новий GET /wide-competition/:slug/applications/cut-line-page?position=&<ті самі фільтри> → {page, rank}: позиції глобальні, але ранги всередині відфільтрованого набору серверні, тож позиція 30506 = сторінка 62 без фільтра і сторінка 17 під «Проходить (Б)». Цільовий рядок тепер виводиться з рангу, а не шукається, тож зріз, де точний рядок відфільтровано, все одно веде на межу. Нумерація під фільтром отримала зсув якоря | api#621 (dev) + fe#619 (development) |
| 2026-07-25 (4) | 🚀 Реліз на прод: цільовий набір (не весь dev/development — «ціна друга», «Моя позиція» й offers-перейменування лишились нерелізнутими). Бекенд api#623, фронт fe#622. Міграцій не було: offers.education_program і прогнозні колонки 2026 у проді вже були. Перед релізом коментарі, додані пакетом, прибрано (api#622, fe#621) | api#623 + fe#622 (main) |