INSERT INTO app_settings(key, value_json, value_type, title, description, category)
VALUES
  (
    'ai_qualifier_contract',
    '"OUTPUT SCHEMA (return array matching input order):\n{\"results\":[{\"id\":123,\"score\":8,\"decision\":\"accepted\",\"reason\":\"до 10 слов на русском\",\"reject_tag\":null}]}\n\nRules:\n- Input is a JSON array of posts.\n- Return JSON only. No markdown. No text outside JSON.\n- score must be integer 1..10.\n- decision must be exactly one of: \"accepted\", \"rejected\", \"maybe\".\n- reject_tag (rejected/maybe only) must be one of: \"meme\", \"no_product\", \"politics\", \"discount_only\", \"off_topic\", \"vacancy\", \"low_content\", \"wrong_language\", \"injection\", \"weapon\", null.\n- Return one result for every input post id."'::jsonb,
    'text',
    'Технический контракт квалификатора',
    'JSON-схема и строгие правила ответа. Обычно не меняется при правке смыслового промпта.',
    'AI Qualifier'
  ),
  (
    'ai_writer_contract',
    '"OUTPUT SCHEMA (return array matching input order):\n{\"rewrites\":[{\"id\":123,\"category\":\"разгрузка\",\"text\":\"готовый текст без хэштегов\",\"notes\":\"короткая заметка для редактора или null\"}]}\n\nRules:\n- Input is a JSON object with key \"posts\" containing accepted posts.\n- Each post includes producer_name and producer_tag. Use producer_name when it helps, but do not invent facts.\n- If post includes editor_regeneration_prompt, follow it as an additional editor instruction while still obeying facts and output schema.\n- Do not add hashtags to rewritten text. Pick exactly one category from the categories list in input.\n- Return JSON only. No markdown. No text outside JSON.\n- Return one rewrite for every input post id."'::jsonb,
    'text',
    'Технический контракт райтера',
    'JSON-схема, выбор категории и запрет хэштегов в тексте. Обычно не меняется при правке стиля.',
    'AI Writer'
  )
ON CONFLICT (key) DO NOTHING;

UPDATE app_settings
SET title='Свободная инструкция квалификатора',
    description='Роль, тон, критерии и примеры оценки. Технический JSON-контракт вынесен отдельно.'
WHERE key='ai_qualifier_prompt';

UPDATE app_settings
SET title='Свободная инструкция райтера',
    description='Стиль, голос канала, правила фактов и примеры текста. Технический JSON-контракт вынесен отдельно.'
WHERE key='ai_writer_prompt';

CREATE TABLE IF NOT EXISTS admin_login_attempts (
  id BIGSERIAL PRIMARY KEY,
  ip TEXT NOT NULL,
  login TEXT NOT NULL DEFAULT '',
  success BOOLEAN NOT NULL DEFAULT FALSE,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_admin_login_attempts_ip_time
ON admin_login_attempts(ip, created_at DESC);

CREATE INDEX IF NOT EXISTS idx_admin_login_attempts_login_time
ON admin_login_attempts(login, created_at DESC);
