diff --git a/db/migrations/041_publication_common_tags_and_category_descriptions.sql b/db/migrations/041_publication_common_tags.sql similarity index 83% rename from db/migrations/041_publication_common_tags_and_category_descriptions.sql rename to db/migrations/041_publication_common_tags.sql index 27d88a2..8d025d6 100644 --- a/db/migrations/041_publication_common_tags_and_category_descriptions.sql +++ b/db/migrations/041_publication_common_tags.sql @@ -1,6 +1,3 @@ -ALTER TABLE content_categories - ADD COLUMN IF NOT EXISTS description TEXT NOT NULL DEFAULT ''; - INSERT INTO app_settings(key, value_json, value_type, title, description, category) VALUES ( 'publication_common_tags', diff --git a/src/vk_parser_app/admin.py b/src/vk_parser_app/admin.py index bdee5dd..51a4f72 100644 --- a/src/vk_parser_app/admin.py +++ b/src/vk_parser_app/admin.py @@ -1325,21 +1325,13 @@ async def writer_category_payload() -> list[dict[str, Any]]: pool = await get_pool() rows = await pool.fetch( """ - SELECT sort_order AS id, name, tag, COALESCE(description, '') AS description + SELECT sort_order AS id, name, tag FROM content_categories WHERE is_active=TRUE ORDER BY sort_order, name """ ) - categories = [ - { - "id": int(row["id"]), - "name": str(row["name"]), - "tag": str(row["tag"]), - "description": str(row["description"] or ""), - } - for row in rows - ] + categories = [{"id": int(row["id"]), "name": str(row["name"]), "tag": str(row["tag"])} for row in rows] if categories: return categories return [ @@ -1352,8 +1344,7 @@ async def category_rows() -> list[dict[str, Any]]: pool = await get_pool() rows = await pool.fetch( """ - SELECT id, name, tag, COALESCE(description, '') AS description, - site_name, site_slug, site_enabled, + SELECT id, name, tag, site_name, site_slug, site_enabled, is_active, sort_order, created_at, updated_at FROM content_categories ORDER BY is_active DESC, sort_order, name @@ -3639,10 +3630,6 @@ async def category_create( csrf_token: str = Form(...), name: str = Form(...), tag: str = Form(""), - description: str = Form(""), - site_name: str = Form(...), - site_slug: str = Form(...), - site_enabled: str | None = Form(None), ): user = await get_current_user(request) if not user: @@ -3652,35 +3639,28 @@ async def category_create( if not name: return redirect("/workers") tag = normalize_hash_tag(tag or name, "category") - description = description.strip() - site_name = site_name.strip() - site_slug = re.sub(r"[^a-z0-9-]+", "-", site_slug.strip().lower().replace("_", "-")).strip("-") - if not site_name or not site_slug: - return redirect("/workers") + site_name = name pool = await get_pool() sort_order = int(await pool.fetchval("SELECT COALESCE(MAX(sort_order), 0) + 1 FROM content_categories") or 1) + site_slug = re.sub(r"[^a-z0-9-]+", "-", tag.strip().lower().replace("_", "-")).strip("-") or f"category-{sort_order}" await pool.execute( """ - INSERT INTO content_categories(name, tag, sort_order, description, site_name, site_slug, site_enabled) - VALUES($1, $2, $3, $4, $5, $6, $7) + INSERT INTO content_categories(name, tag, sort_order, site_name, site_slug, site_enabled) + VALUES($1, $2, $3, $4, $5, FALSE) ON CONFLICT (name) DO UPDATE SET tag=$2, - description=$4, - site_name=$5, - site_slug=$6, - site_enabled=$7, + site_name=$4, + site_slug=$5, is_active=TRUE, updated_at=NOW() """, name, tag, sort_order, - description, site_name, site_slug, - site_enabled is not None, ) - await audit(user["id"], "category.create", "content_category", None, {"name": name, "tag": tag, "description": description, "site_name": site_name, "site_slug": site_slug, "site_enabled": site_enabled is not None}) + await audit(user["id"], "category.create", "content_category", None, {"name": name, "tag": tag}) return redirect("/workers") @@ -3691,10 +3671,6 @@ async def category_update( csrf_token: str = Form(...), name: str = Form(...), tag: str = Form(""), - description: str = Form(""), - site_name: str = Form(...), - site_slug: str = Form(...), - site_enabled: str | None = Form(None), ): user = await get_current_user(request) if not user: @@ -3704,33 +3680,26 @@ async def category_update( if not name: return redirect("/workers") tag = normalize_hash_tag(tag or name, "category") - description = description.strip() - site_name = site_name.strip() - site_slug = re.sub(r"[^a-z0-9-]+", "-", site_slug.strip().lower().replace("_", "-")).strip("-") - if not site_name or not site_slug: - return redirect("/workers") + site_name = name + site_slug = re.sub(r"[^a-z0-9-]+", "-", tag.strip().lower().replace("_", "-")).strip("-") or f"category-{category_id}" pool = await get_pool() await pool.execute( """ UPDATE content_categories SET name=$2, tag=$3, - description=$4, - site_name=$5, - site_slug=$6, - site_enabled=$7, + site_name=$4, + site_slug=$5, updated_at=NOW() WHERE id=$1 """, category_id, name, tag, - description, site_name, site_slug, - site_enabled is not None, ) - await audit(user["id"], "category.update", "content_category", category_id, {"name": name, "tag": tag, "description": description, "site_name": site_name, "site_slug": site_slug, "site_enabled": site_enabled is not None}) + await audit(user["id"], "category.update", "content_category", category_id, {"name": name, "tag": tag}) return redirect("/workers") @@ -3770,15 +3739,13 @@ async def category_delete(request: Request, category_id: int, csrf_token: str = pool = await get_pool() row = await pool.fetchrow( """ - UPDATE content_categories - SET is_active=FALSE, - updated_at=NOW() + DELETE FROM content_categories WHERE id=$1 RETURNING name """, category_id, ) - await audit(user["id"], "category.archive", "content_category", category_id, {"name": row["name"] if row else None}) + await audit(user["id"], "category.delete", "content_category", category_id, {"name": row["name"] if row else None}) return redirect("/workers") diff --git a/src/vk_parser_app/templates/workers.html b/src/vk_parser_app/templates/workers.html index d42f86f..aeeedc3 100644 --- a/src/vk_parser_app/templates/workers.html +++ b/src/vk_parser_app/templates/workers.html @@ -73,7 +73,7 @@
- Название и описание помогают AI выбрать категорию, тэг используется в соцсетях. + Название помогает AI выбрать категорию, тэг используется в соцсетях.
@@ -88,24 +88,8 @@
-
- - -
-
- - -
-
- - -
-
@@ -115,7 +99,6 @@ Название / Тэг - Сайт / Slug ID Статус @@ -131,23 +114,12 @@
- -
- - -
- -
{{ c.sort_order }}
{% if c.is_active %}Активна{% else %}Выкл{% endif %} -
diff --git a/src/vk_parser_app/workers/ai_writer.py b/src/vk_parser_app/workers/ai_writer.py index a5cf43d..78e8c89 100644 --- a/src/vk_parser_app/workers/ai_writer.py +++ b/src/vk_parser_app/workers/ai_writer.py @@ -53,7 +53,7 @@ OUTPUT SCHEMA (return array matching input order): Rules: - Input is a JSON object with key "posts" containing accepted posts. -- Input has key "categories" with objects: id, name, tag, description. +- 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. - The "text" field for every rewrite must explicitly mention producer_name at least once. Do not satisfy this only through producer_tag, hashtags, notes, or metadata. - Pick exactly one category from the categories list in input and return its numeric id as category_id. @@ -208,7 +208,7 @@ async def load_writer_categories(pool) -> list[dict[str, Any]]: try: rows = await pool.fetch( """ - SELECT sort_order AS id, name, tag, COALESCE(description, '') AS description + SELECT sort_order AS id, name, tag FROM content_categories WHERE is_active=TRUE ORDER BY sort_order, name @@ -216,15 +216,7 @@ async def load_writer_categories(pool) -> list[dict[str, Any]]: ) except Exception: rows = [] - categories = [ - { - "id": int(row["id"]), - "name": str(row["name"]), - "tag": str(row["tag"]), - "description": str(row["description"] or ""), - } - for row in rows - ] + categories = [{"id": int(row["id"]), "name": str(row["name"]), "tag": str(row["tag"])} for row in rows] if categories: return categories legacy = parse_categories(await fetch_setting("ai_writer_categories", []))