| name | manual-achievements |
| description | Ручные ачивки Movie Planner: «Герой тестировщик» (hero_tester), кому давать, SQL в prod БД, попап при входе. Использовать при «дай ачивку тестировщика», «награди за тестирование», grant achievement, hero_tester. |
Ручные ачивки
Автоматические ачивки считаются из статистики (PERSONAL_ACHIEVEMENTS_DEF в moviebot/api/site_stats.py). Ручные выдаются только записью в achievements_earned — без порогов фильмов/оценок.
«Герой тестировщик» (hero_tester)
| Поле | Значение |
|---|
| id | hero_tester |
| Название | Герой тестировщик |
| Описание | За выдающиеся заслуги в тестировании Movie Planner |
| Иконка | 🦸 |
| Редкость | legendary (золотое оформление в UI) |
| Код | moviebot/api/site_stats.py — проверка как у kp_import_first: earned, если есть строка в achievements_earned |
Смысл (продукт)
Публичная благодарность людям, которые реально помогли качеству MP: тестировали miniapp / app / сайт, ловили баги, гоняли импорт KP, сценарии планов, друзей и т.д. Не за «просто зашёл», не за объём просмотров — за заслуги в тестировании.
Решение о выдаче — только владелец продукта (Никита). Агент выдаёт по явной просьбе в чате, с указанием пользователя.
Кому уже выдавали (примеры)
| user_id | Имя / label | username / kp |
|---|
| 475811487 | Владислав | vladlumen |
| 245670444 | Zhenya | kp lion, TG из логов KP LOCAL |
| -31 | Tanya_movielover | kp 23484323, email/virtual TG id |
Как выдать
-
Найти user_id (Telegram): site_sessions, stats, логи (tg_user_id=), или прямо из запроса владельца.
-
Prod PostgreSQL (креды в проектном .env, не коммитить):
PGPASSWORD=... psql -h switchback.proxy.rlwy.net -U postgres -p 46844 -d railway
- INSERT (попап при следующем входе —
celebration_shown_at NULL):
INSERT INTO achievements_earned (user_id, achievement_id, earned_at, celebration_shown_at)
VALUES (<USER_ID>, 'hero_tester', NOW(), NULL)
ON CONFLICT (user_id, achievement_id)
DO UPDATE SET earned_at = EXCLUDED.earned_at, celebration_shown_at = NULL;
- Проверка:
SELECT user_id, achievement_id, earned_at, celebration_shown_at
FROM achievements_earned
WHERE user_id = <USER_ID> AND achievement_id = 'hero_tester';
Попап «Ура!»
- Список celebration-ачивок:
CELEBRATION_ACHIEVEMENT_IDS = {'hero_tester'} в site_stats.py.
- API:
GET /api/miniapp/achievements/celebration-pending, POST .../celebration-shown.
- Показ: miniapp boot, сайт после
/api/site/me, нативное app (AchievementCelebrationHost).
- После «Ура!» выставляется
celebration_shown_at — повторно не показывается.
Показать попап ещё раз (только по просьбе владельца):
UPDATE achievements_earned
SET celebration_shown_at = NULL
WHERE user_id = <USER_ID> AND achievement_id = 'hero_tester';
Вёрстка попапа
Центрированный диалог — правило .cursor/rules/ui-popups-modals.mdc, классы mp-dialog-overlay / mp-dialog-card. Не bottom sheet.
Чего не делать
- Не массово выдавать без списка от владельца.
- Не сбрасывать
celebration_shown_at на проде «для проверки» без просьбы.
- Не добавлять новые ручные ачивки без согласования: нужны id в
PERSONAL_ACHIEVEMENTS_DEF, при необходимости — в CELEBRATION_ACHIEVEMENT_IDS и тесты.
Добавление другой ручной ачивки (редко)
- Tuple в
PERSONAL_ACHIEVEMENTS_DEF (site_stats.py).
- В
_check_achievement — ветка по achievements_earned (как hero_tester / kp_import_first).
- При необходимости попапа — id в
CELEBRATION_ACHIEVEMENT_IDS + UI по ui-popups-modals.mdc.
- Тест в
tests/test_achievement_celebration.py или аналог.
- Документировать в этом SKILL.