Як це працює

Сезон, підсумки і снапшот

Три різні події, які легко сплутати, і що саме фіксується наприкінці сезону. Без жаргону.

` і

`

Три різні події, які легко сплутати

Це головне джерело плутанини — і саме через неї в UI довелося робити окремий банер (див. Розрив між кінцем сезону і freeze).

1. Кінець сезону — настає сам

Дата вже записана в базі (seasons.ends_at). Натискати нічого не треба. У цю мить сезонна таблиця перестає рухатись: XP, зароблений після, у сезонний рейтинг більше не потрапляє.

Технічно: season_standings рахує пів-відкрите вікно created_at < ends_at.

2. Finalize — коли натиснули кнопку

Підбиття підсумків сезону: система записує остаточні місця, видає медалі за топ-10 і чемпіонство, виплачує призи мем-контесту. Усе це — одна транзакція, або все, або нічого.

Може статись і в день кінця сезону, і через тиждень. Поки не натиснуто, сезон формально лишається «активним» (finalized_at is null).

→ seasons.md

3. Freeze аірдропу — ще пізніше й про інше

Це вже не про сезон, а про роздачу токенів. Окрема дія, окремі дані, окремі наслідки.

Проєкт не змушує робити 2 і 3 одночасно. Це гнучкість, але й ризик: ніхто не нагадає, що час настав. Саме тому зʼявилась щоденна перевірка /api/cron/ops-check, яка сигналить, коли сезон закінчився, а finalize ні.


Розрив між кінцем сезону і freeze

Між подіями 1 і 3 є вікно, у якому все виглядає дивно, якщо не знати правил:

  • сезонна таблиця вже замерзла;
  • квести, рулетка, скрині все ще нараховують XP;
  • цей XP у сезонний рейтинг не йде, але в аірдроп — йде, бо снапшот рахує довічні підсумки на момент freeze.

Раніше про це не говорило ніщо, і людина бачила тільки те, що її рейтинг стоїть. Тепер у цьому стані показується банер, у сезонному рейтингу зʼявляється пояснювальний рядок, а в /help є картка «Що після кінця відліку», де обидва годинники названо явно.

Правило, яке з цього випливає: що пізніше freeze після кінця сезону, то більше «позасезонної» активності потрапить в аірдроп. Це не помилка, але це має бути оголошено заздалегідь — інакше виглядатиме як зміна правил.


Що таке freeze простими словами

Уяви, що ти фотографуєш дошку з результатами. До зйомки на дошці можна писати й стирати. Після — фотографія вже є, і вона не міняється, навіть якщо дошку потім перепишуть.

Freeze робить рівно це. Система бере поточний стан кожного учасника — скільки XP, скільки ачівок, скільки квестів, скільки днів у сімʼї, чи холдер, який гаманець — рахує за формулою бали й записує результат намертво.

Чому «намертво» — це не обіцянка, а механіка

Ті рядки не можна ні змінити, ні видалити: у базі стоять тригери, які відхиляють DELETE, а руйнівні звʼязки з профілями прибрані. Навіть видалення профілю не чіпає снапшот. Це не питання дисципліни адміна — база фізично не дасть.

Дайджест: навіщо контрольна сума

Разом із фотографією рахується довгий рядок символів, який однозначно відповідає її вмісту. Публікуються обидва.

Будь-хто може взяти опубліковану таблицю, перерахувати суму сам і переконатися, що вона збігається. Якщо потім тихо змінити хоч одну цифру — сума не зійдеться, і це побачать усі. Незалежна перевірка робиться так:

node scripts/verify-digest.mjs --csv airdrop_<id>.csv --meta meta_<id>.json --expect sha256:…

У фотографію входить адреса гаманця

Снапшот фіксує не лише «скільки», а й «кому»: номер паспорта і адреса Solana-гаманця вморожуються в рядки й входять у контрольну суму.

Наслідок: якщо людина після freeze поміняє гаманець, стара фотографія лишиться зі старою адресою. Виправити це можна тільки новою фотографією з новою сумою. Тихо підмінити адресата неможливо.

Що дає Season 1

On-chain роздачі цього сезону немає, і токен не випускається. Season 1 дає:

  • номер паспорта — назавжди твій, фіксує, що ти був тут рано;
  • медалі за мілстоуни й сезонні досягнення;
  • місце в заморожених підсумках сезону;
  • опублікований снапшот із дайджестом — незворотний, перевірюваний запис того, хто був тут і що зробив.

Останнє — не «втішний приз». Це рівно та обіцянка, яку продукт дає з першого дня, тільки перетворена з гасла на запис, який будь-хто може перевірити самостійно. Коли зʼявиться що розподіляти, спиратись будуть на такий запис.

Гаманець: не обовʼязковий, але вирішує одне

Гаманець не потрібен, щоб брати участь. XP, рівні, квести, меми, медалі, стрик і рейтинг працюють без нього — нічого в прогресі за ним не замкнено.

Він вирішує рівно одне: чи будеш ти адресатом у сезонному снапшоті. Без гаманця бали все одно фіксуються, але графа адреси лишається порожньою. Якщо колись зʼявиться що розподіляти, отримати зможе лише той, у кого гаманець залінкований на момент freeze.

Гаманець незмінний після першого лінку — виправляє лише модератор. Тож привʼязуй той, який справді контролюєш; дедлайну немає й поспішати нема куди.