-- Migration 191: account_quota_overrides.unlimited — безлимит как данные, не хардкод
--
-- WHY:
--   app.services.account_quota.is_unlimited() до этой миграции проверял ровно два
--   условия: роль admin ИЛИ literal `username == 'kopylov'` — захардкоженное сравнение
--   строки прямо в коде. Восстановление пилота praktika (ГК «Практика», доступ вернул
--   владелец продукта 2026-07-27 — см. auth/roles.yaml) с безлимитным грантом сделало
--   бы это хардкодом ВТОРОГО имени: не масштабируется (каждый следующий безлимитный
--   клиент требовал бы code-change + review + deploy вместо data-change) и плохо само
--   по себе как паттерн (магическая строка вместо конфигурируемых данных).
--
--   unlimited — отдельная boolean-колонка, а не sentinel-значение monthly_limit
--   (-1 / 0): `0` неоднозначен («ноль оценок в месяц» vs «без лимита»), explicit
--   boolean честнее и не требует специального парсинга в user_limit()/is_unlimited().
--
--   kopylov ПЕРЕНЕСЁН в данные этой же миграцией (хардкод в коде убран, не оставлен
--   параллельно) — единый источник правды для non-admin unlimited-аккаунтов вместо
--   двух параллельных механизмов (код-константа + таблица). Порядок деплоя
--   (SQL-миграция применяется РАНЬШЕ, чем стартует новый код — см.
--   .claude/rules/sql.md "Migration order") гарантирует, что строка kopylov уже в
--   таблице к моменту, когда новый is_unlimited() (без хардкода) начинает работать —
--   поведение kopylov не меняется ни на секунду простоя.
--
-- WHAT:
--   1. account_quota_overrides.unlimited boolean NOT NULL DEFAULT false.
--   2. Seed: kopylov (перенос хардкода) + praktika (новый грант, пилот восстановлен
--      2026-07-27) — оба unlimited=true. monthly_limit=999999 — placeholder: get_status()
--      безусловно читает monthly_limit через user_limit() даже для unlimited-аккаунтов
--      (чтобы вернуть какое-то "limit" поле в /quota), а само enforcement для unlimited
--      обходит этот лимит (is_unlimited() гейтит раньше в check_and_raise()/increment()).
--      Значение просто не должно выглядеть абсурдным, если когда-либо surfaced напрямую.
--
-- IDEMPOTENCY:
--   ALTER TABLE ... ADD COLUMN IF NOT EXISTS (новая колонка) + INSERT ... ON CONFLICT
--   DO UPDATE (повторный прогон сходится к тому же состоянию, не дублирует строки).
--
-- Dependencies: 185_account_quota_overrides.sql (создаёт account_quota_overrides).

BEGIN;

ALTER TABLE account_quota_overrides
    ADD COLUMN IF NOT EXISTS unlimited boolean NOT NULL DEFAULT false;

COMMENT ON COLUMN account_quota_overrides.unlimited IS
    'Безлимитный грант (нет месячного лимита оценок) — читается '
    'app.services.account_quota.is_unlimited(). Заменяет прежний хардкод username в коде.';

INSERT INTO account_quota_overrides (username, monthly_limit, unlimited, note)
VALUES ('kopylov', 999999, true,
        'Личный аккаунт — безлимит перенесён из хардкода is_unlimited() в данные '
        '(migration 191, 2026-07-27), поведение не изменилось')
ON CONFLICT (username) DO UPDATE SET
    monthly_limit = EXCLUDED.monthly_limit,
    unlimited = EXCLUDED.unlimited,
    note = EXCLUDED.note,
    updated_at = now();

INSERT INTO account_quota_overrides (username, monthly_limit, unlimited, note)
VALUES ('praktika', 999999, true,
        'ГК «Практика» — пилот восстановлен 2026-07-27 (решение владельца продукта), '
        'безлимитный грант')
ON CONFLICT (username) DO UPDATE SET
    monthly_limit = EXCLUDED.monthly_limit,
    unlimited = EXCLUDED.unlimited,
    note = EXCLUDED.note,
    updated_at = now();

COMMIT;
