Update UI and migrations, fix dockerfile
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
ALTER TABLE raw_posts
|
||||
ADD COLUMN IF NOT EXISTS publication_status TEXT NOT NULL DEFAULT 'pending',
|
||||
ADD COLUMN IF NOT EXISTS publication_error TEXT,
|
||||
ADD COLUMN IF NOT EXISTS published_at TIMESTAMPTZ,
|
||||
ADD COLUMN IF NOT EXISTS tg_publication_chat_id BIGINT,
|
||||
ADD COLUMN IF NOT EXISTS tg_publication_thread_id BIGINT,
|
||||
ADD COLUMN IF NOT EXISTS tg_publication_message_ids BIGINT[],
|
||||
ADD COLUMN IF NOT EXISTS tg_publication_url TEXT;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_raw_posts_publication_queue
|
||||
ON raw_posts(publication_status, editorial_status, rewrite_status, published_at, reviewed_at, id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_raw_posts_publication_rank
|
||||
ON raw_posts(final_category_tag, final_source_tag, published_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS publication_runs (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
poster TEXT NOT NULL,
|
||||
schedule_id TEXT NOT NULL,
|
||||
scheduled_for DATE NOT NULL,
|
||||
scheduled_time TEXT NOT NULL,
|
||||
planned_count INTEGER NOT NULL DEFAULT 0,
|
||||
published_count INTEGER NOT NULL DEFAULT 0,
|
||||
status TEXT NOT NULL DEFAULT 'started',
|
||||
error TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(poster, schedule_id, scheduled_for)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_publication_runs_poster_date
|
||||
ON publication_runs(poster, scheduled_for DESC, scheduled_time);
|
||||
|
||||
INSERT INTO worker_controls(name, enabled, settings_json)
|
||||
VALUES ('tg-poster', FALSE, '{}'::jsonb)
|
||||
ON CONFLICT (name) DO NOTHING;
|
||||
|
||||
INSERT INTO app_settings(key, value_json, value_type, title, description, category)
|
||||
VALUES
|
||||
('tg_poster_enabled', 'false'::jsonb, 'bool', 'TG poster enabled', 'Double safety flag for publishing accepted posts to Telegram.', 'TG Poster'),
|
||||
('tg_poster_bot_token', '""'::jsonb, 'secret', 'TG poster bot token', 'Bot token for final Telegram publication. For test can be the same as upload bot token.', 'TG Poster'),
|
||||
('tg_poster_chat_id', '"-1003712724327"'::jsonb, 'str', 'TG publication chat id', 'Target Telegram channel/group id. Supports chat_id:thread_id for topics.', 'TG Poster'),
|
||||
('tg_poster_schedule_json', '[{"id":"morning","time":"10:00","count":1,"enabled":true},{"id":"evening","time":"18:00","count":1,"enabled":true}]'::jsonb, 'json', 'TG publication schedule', 'EKB time schedule rows: id, time HH:MM, count, enabled.', 'TG Poster'),
|
||||
('tg_poster_interval_sec', '60'::jsonb, 'int', 'TG poster interval, sec', 'Pause between poster checks.', 'TG Poster'),
|
||||
('tg_poster_media_group_max_items', '10'::jsonb, 'int', 'TG media group max items', 'Telegram media group supports 2..10 media items.', 'TG Poster'),
|
||||
('tg_poster_caption_limit', '1024'::jsonb, 'int', 'TG caption limit', 'Telegram caption limit for media messages.', 'TG Poster'),
|
||||
('tg_poster_message_limit', '4096'::jsonb, 'int', 'TG message limit', 'Telegram text message limit.', 'TG Poster'),
|
||||
('tg_poster_max_attempts', '3'::jsonb, 'int', 'TG post retry attempts', 'Retries for Telegram API errors.', 'TG Poster'),
|
||||
('tg_poster_retry_backoff_max_sec', '30'::jsonb, 'int', 'TG retry backoff max, sec', 'Max retry sleep for Telegram API errors.', 'TG Poster'),
|
||||
('tg_poster_send_delay_sec', '1'::jsonb, 'float', 'TG send delay, sec', 'Delay between Telegram sends.', 'TG Poster'),
|
||||
('tg_poster_text_overflow_caption', '"⬇️ Описание под медиа"'::jsonb, 'str', 'TG overflow caption', 'Caption used when full text is longer than Telegram media caption limit.', 'TG Poster'),
|
||||
('tg_poster_recent_window', '20'::jsonb, 'int', 'Ranking recent window', 'How many published posts are checked to reduce repeated categories and sources.', 'TG Poster'),
|
||||
('tg_poster_category_repeat_penalty', '3'::jsonb, 'float', 'Category repeat penalty', 'Ranking penalty for recently published same category.', 'TG Poster'),
|
||||
('tg_poster_source_repeat_penalty', '4'::jsonb, 'float', 'Source repeat penalty', 'Ranking penalty for recently published same source.', 'TG Poster')
|
||||
ON CONFLICT (key) DO NOTHING;
|
||||
|
||||
UPDATE app_settings
|
||||
SET description='Обрезает исходный raw-текст перед отправкой в LLM. Итоговый rewrite должен быть компактным: Telegram caption 1024 символа минус будущая строка хэштегов.'
|
||||
WHERE key='ai_writer_max_text_chars';
|
||||
|
||||
UPDATE app_settings
|
||||
SET value_json = to_jsonb($contract$
|
||||
OUTPUT SCHEMA (return array matching input order):
|
||||
{"rewrites":[{"id":123,"category_id":2,"text":"готовый текст без хэштегов","notes":"короткая заметка для редактора или null"}]}
|
||||
|
||||
Rules:
|
||||
- Input is a JSON object with key "posts" containing accepted posts.
|
||||
- Input has key "categories" with objects: id, name, tag.
|
||||
- Each post includes producer_name and producer_tag. producer_name can be a manufacturer, shop, or publishing source.
|
||||
- Pick exactly one category from the categories list in input and return its numeric id as category_id.
|
||||
- Do not add links or hashtags to rewritten text.
|
||||
- Keep text compact enough for Telegram media caption: target 850 characters, hard maximum 900 characters.
|
||||
- Remember the system appends category and source hashtags after text, so leave space for them.
|
||||
- Return JSON only. No markdown. No text outside JSON.
|
||||
- Never return an empty object. Never omit the "rewrites" key.
|
||||
- Return one rewrite for every input post id.
|
||||
- The "text" field must be a ready-to-publish Russian post with normal paragraph line breaks encoded as JSON string newlines.
|
||||
- The "notes" field must be a short editor note in Russian or null.
|
||||
$contract$::text),
|
||||
updated_at = NOW()
|
||||
WHERE key='ai_writer_contract';
|
||||
|
||||
UPDATE app_settings
|
||||
SET value_json = to_jsonb(
|
||||
regexp_replace(
|
||||
value_json #>> '{}',
|
||||
'- 3-6 коротких строк или 2-5 компактных абзацев;',
|
||||
'- 3-6 коротких строк или 2-4 компактных абзаца; итоговый text должен целиться в 850 символов и не превышать 900 символов, потому что система добавит хэштеги и Telegram caption ограничен 1024 символами;',
|
||||
'g'
|
||||
)
|
||||
)
|
||||
WHERE key='ai_writer_prompt'
|
||||
AND (value_json #>> '{}') LIKE '%3-6 коротких строк или 2-5 компактных абзацев%';
|
||||
Reference in New Issue
Block a user