Files
raa-parser_poster/db/migrations/014_prompt_contracts_and_admin_security.sql
T
2026-08-03 16:18:56 +05:00

44 lines
3.2 KiB
SQL

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);