feat(migrations): Harden task audit tracking and optimize article templates
- Added migration to harden task audit tracking by modifying audit_logs and related tables. - Introduced operator_id to several tables for better tracking of actions. - Updated article_templates with new prompt templates for various article types, enhancing content generation. - Created prompt_rules and schedule_tasks tables to manage content generation rules and scheduling. - Added foreign key constraints to articles for better data integrity.
This commit is contained in:
@@ -1,11 +1,24 @@
|
||||
-- name: CreateAuditLog :exec
|
||||
INSERT INTO audit_logs (operator_id, tenant_id, module, action, before_json, after_json, result)
|
||||
INSERT INTO audit_logs (
|
||||
operator_id,
|
||||
tenant_id,
|
||||
module,
|
||||
action,
|
||||
resource_type,
|
||||
resource_id,
|
||||
request_id,
|
||||
before_json,
|
||||
after_json,
|
||||
result,
|
||||
error_message
|
||||
)
|
||||
VALUES (sqlc.arg(operator_id), sqlc.arg(tenant_id), sqlc.arg(module), sqlc.arg(action),
|
||||
sqlc.arg(before_json), sqlc.arg(after_json), sqlc.arg(result));
|
||||
sqlc.arg(resource_type), sqlc.arg(resource_id), sqlc.arg(request_id),
|
||||
sqlc.arg(before_json), sqlc.arg(after_json), sqlc.arg(result), sqlc.arg(error_message));
|
||||
|
||||
-- name: CreateGenerationTask :one
|
||||
INSERT INTO generation_tasks (tenant_id, article_id, quota_reservation_id, task_type, input_params_json, status)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.arg(article_id), sqlc.arg(quota_reservation_id),
|
||||
INSERT INTO generation_tasks (tenant_id, operator_id, article_id, quota_reservation_id, task_type, input_params_json, status)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.arg(operator_id), sqlc.arg(article_id), sqlc.arg(quota_reservation_id),
|
||||
sqlc.arg(task_type), sqlc.arg(input_params_json), 'queued')
|
||||
RETURNING id;
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
-- ============================================================
|
||||
-- Prompt Rule Groups
|
||||
-- ============================================================
|
||||
|
||||
-- name: ListPromptRuleGroups :many
|
||||
SELECT id, tenant_id, name, sort_order, created_at, updated_at
|
||||
FROM prompt_rule_groups
|
||||
WHERE tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL
|
||||
ORDER BY sort_order, created_at;
|
||||
|
||||
-- name: CreatePromptRuleGroup :one
|
||||
INSERT INTO prompt_rule_groups (tenant_id, name, sort_order)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.arg(name), sqlc.arg(sort_order))
|
||||
RETURNING id, created_at;
|
||||
|
||||
-- name: UpdatePromptRuleGroup :exec
|
||||
UPDATE prompt_rule_groups SET name = sqlc.arg(name), sort_order = sqlc.arg(sort_order), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||
|
||||
-- name: SoftDeletePromptRuleGroup :exec
|
||||
UPDATE prompt_rule_groups SET deleted_at = NOW(), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||
|
||||
-- ============================================================
|
||||
-- Prompt Rules
|
||||
-- ============================================================
|
||||
|
||||
-- name: ListPromptRules :many
|
||||
SELECT pr.id, pr.tenant_id, pr.group_id, pr.name, pr.prompt_content,
|
||||
pr.scene, pr.default_tone, pr.default_word_count, pr.status,
|
||||
pr.created_at, pr.updated_at,
|
||||
COUNT(a.id)::INT AS article_count
|
||||
FROM prompt_rules pr
|
||||
LEFT JOIN articles a ON a.prompt_rule_id = pr.id AND a.deleted_at IS NULL
|
||||
WHERE pr.tenant_id = sqlc.arg(tenant_id)
|
||||
AND pr.deleted_at IS NULL
|
||||
AND (sqlc.narg(group_id)::bigint IS NULL OR pr.group_id = sqlc.narg(group_id))
|
||||
AND (sqlc.narg(status)::text IS NULL OR pr.status = sqlc.narg(status))
|
||||
AND (sqlc.narg(keyword)::text IS NULL OR pr.name ILIKE '%' || sqlc.narg(keyword) || '%')
|
||||
GROUP BY pr.id
|
||||
ORDER BY pr.created_at DESC
|
||||
LIMIT sqlc.arg(page_size) OFFSET sqlc.arg(page_offset);
|
||||
|
||||
-- name: CountPromptRules :one
|
||||
SELECT COUNT(*)
|
||||
FROM prompt_rules
|
||||
WHERE tenant_id = sqlc.arg(tenant_id)
|
||||
AND deleted_at IS NULL
|
||||
AND (sqlc.narg(group_id)::bigint IS NULL OR group_id = sqlc.narg(group_id))
|
||||
AND (sqlc.narg(status)::text IS NULL OR status = sqlc.narg(status))
|
||||
AND (sqlc.narg(keyword)::text IS NULL OR name ILIKE '%' || sqlc.narg(keyword) || '%');
|
||||
|
||||
-- name: ListPromptRulesUngrouped :many
|
||||
SELECT pr.id, pr.tenant_id, pr.group_id, pr.name, pr.prompt_content,
|
||||
pr.scene, pr.default_tone, pr.default_word_count, pr.status,
|
||||
pr.created_at, pr.updated_at,
|
||||
COUNT(a.id)::INT AS article_count
|
||||
FROM prompt_rules pr
|
||||
LEFT JOIN articles a ON a.prompt_rule_id = pr.id AND a.deleted_at IS NULL
|
||||
WHERE pr.tenant_id = sqlc.arg(tenant_id)
|
||||
AND pr.deleted_at IS NULL
|
||||
AND pr.group_id IS NULL
|
||||
GROUP BY pr.id
|
||||
ORDER BY pr.created_at DESC
|
||||
LIMIT sqlc.arg(page_size) OFFSET sqlc.arg(page_offset);
|
||||
|
||||
-- name: CountPromptRulesUngrouped :one
|
||||
SELECT COUNT(*)
|
||||
FROM prompt_rules
|
||||
WHERE tenant_id = sqlc.arg(tenant_id)
|
||||
AND deleted_at IS NULL
|
||||
AND group_id IS NULL;
|
||||
|
||||
-- name: GetPromptRuleByID :one
|
||||
SELECT id, tenant_id, group_id, name, prompt_content,
|
||||
scene, default_tone, default_word_count, status,
|
||||
created_at, updated_at
|
||||
FROM prompt_rules
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||
|
||||
-- name: CreatePromptRule :one
|
||||
INSERT INTO prompt_rules (tenant_id, group_id, name, prompt_content, scene, default_tone, default_word_count)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.narg(group_id), sqlc.arg(name), sqlc.arg(prompt_content),
|
||||
sqlc.narg(scene), sqlc.narg(default_tone), sqlc.narg(default_word_count))
|
||||
RETURNING id, created_at;
|
||||
|
||||
-- name: UpdatePromptRule :exec
|
||||
UPDATE prompt_rules
|
||||
SET name = sqlc.arg(name), group_id = sqlc.narg(group_id),
|
||||
prompt_content = sqlc.arg(prompt_content),
|
||||
scene = sqlc.narg(scene), default_tone = sqlc.narg(default_tone),
|
||||
default_word_count = sqlc.narg(default_word_count), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||
|
||||
-- name: UpdatePromptRuleStatus :exec
|
||||
UPDATE prompt_rules SET status = sqlc.arg(status), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||
|
||||
-- name: SoftDeletePromptRule :exec
|
||||
UPDATE prompt_rules SET deleted_at = NOW(), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||
|
||||
-- name: ListAllPromptRulesSimple :many
|
||||
SELECT id, name, status
|
||||
FROM prompt_rules
|
||||
WHERE tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL AND status = 'enabled'
|
||||
ORDER BY name;
|
||||
@@ -6,14 +6,14 @@ SELECT COALESCE(
|
||||
)::INT AS balance;
|
||||
|
||||
-- name: InsertQuotaLedger :one
|
||||
INSERT INTO tenant_quota_ledgers (tenant_id, quota_type, delta, balance_after, reason, reference_type, reference_id)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.arg(quota_type), sqlc.arg(delta), sqlc.arg(balance_after),
|
||||
INSERT INTO tenant_quota_ledgers (tenant_id, operator_id, quota_type, delta, balance_after, reason, reference_type, reference_id)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.arg(operator_id), sqlc.arg(quota_type), sqlc.arg(delta), sqlc.arg(balance_after),
|
||||
sqlc.arg(reason), sqlc.arg(reference_type), sqlc.arg(reference_id))
|
||||
RETURNING id;
|
||||
|
||||
-- name: CreateQuotaReservation :one
|
||||
INSERT INTO quota_reservations (tenant_id, quota_type, resource_type, resource_id, reserved_amount, status, expire_at)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.arg(quota_type), sqlc.arg(resource_type), sqlc.arg(resource_id),
|
||||
INSERT INTO quota_reservations (tenant_id, operator_id, quota_type, resource_type, resource_id, reserved_amount, status, expire_at)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.arg(operator_id), sqlc.arg(quota_type), sqlc.arg(resource_type), sqlc.arg(resource_id),
|
||||
sqlc.arg(reserved_amount), 'pending', sqlc.arg(expire_at))
|
||||
RETURNING id;
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
-- name: ListScheduleTasks :many
|
||||
SELECT st.id, st.tenant_id, st.prompt_rule_id, st.brand_id, st.name,
|
||||
st.cron_expr, st.target_platform, st.start_at, st.end_at,
|
||||
st.next_run_at, st.status, st.created_at, st.updated_at,
|
||||
pr.name AS prompt_rule_name,
|
||||
b.name AS brand_name
|
||||
FROM schedule_tasks st
|
||||
LEFT JOIN prompt_rules pr ON pr.id = st.prompt_rule_id
|
||||
LEFT JOIN brands b ON b.id = st.brand_id
|
||||
WHERE st.tenant_id = sqlc.arg(tenant_id)
|
||||
AND st.deleted_at IS NULL
|
||||
AND (sqlc.narg(status)::text IS NULL OR st.status = sqlc.narg(status))
|
||||
AND (sqlc.narg(prompt_rule_id)::bigint IS NULL OR st.prompt_rule_id = sqlc.narg(prompt_rule_id))
|
||||
ORDER BY st.created_at DESC
|
||||
LIMIT sqlc.arg(page_size) OFFSET sqlc.arg(page_offset);
|
||||
|
||||
-- name: CountScheduleTasks :one
|
||||
SELECT COUNT(*)
|
||||
FROM schedule_tasks
|
||||
WHERE tenant_id = sqlc.arg(tenant_id)
|
||||
AND deleted_at IS NULL
|
||||
AND (sqlc.narg(status)::text IS NULL OR status = sqlc.narg(status))
|
||||
AND (sqlc.narg(prompt_rule_id)::bigint IS NULL OR prompt_rule_id = sqlc.narg(prompt_rule_id));
|
||||
|
||||
-- name: GetScheduleTaskByID :one
|
||||
SELECT st.id, st.tenant_id, st.prompt_rule_id, st.brand_id, st.name,
|
||||
st.cron_expr, st.target_platform, st.start_at, st.end_at,
|
||||
st.next_run_at, st.status, st.created_at, st.updated_at,
|
||||
pr.name AS prompt_rule_name,
|
||||
b.name AS brand_name
|
||||
FROM schedule_tasks st
|
||||
LEFT JOIN prompt_rules pr ON pr.id = st.prompt_rule_id
|
||||
LEFT JOIN brands b ON b.id = st.brand_id
|
||||
WHERE st.id = sqlc.arg(id) AND st.tenant_id = sqlc.arg(tenant_id) AND st.deleted_at IS NULL;
|
||||
|
||||
-- name: CreateScheduleTask :one
|
||||
INSERT INTO schedule_tasks (tenant_id, prompt_rule_id, brand_id, name, cron_expr,
|
||||
target_platform, start_at, end_at, next_run_at)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.arg(prompt_rule_id), sqlc.narg(brand_id), sqlc.arg(name),
|
||||
sqlc.arg(cron_expr), sqlc.narg(target_platform), sqlc.narg(start_at), sqlc.narg(end_at),
|
||||
sqlc.narg(next_run_at))
|
||||
RETURNING id, created_at;
|
||||
|
||||
-- name: UpdateScheduleTask :exec
|
||||
UPDATE schedule_tasks
|
||||
SET prompt_rule_id = sqlc.arg(prompt_rule_id), brand_id = sqlc.narg(brand_id),
|
||||
name = sqlc.arg(name), cron_expr = sqlc.arg(cron_expr),
|
||||
target_platform = sqlc.narg(target_platform),
|
||||
start_at = sqlc.narg(start_at), end_at = sqlc.narg(end_at),
|
||||
next_run_at = sqlc.narg(next_run_at), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||
|
||||
-- name: UpdateScheduleTaskStatus :exec
|
||||
UPDATE schedule_tasks SET status = sqlc.arg(status), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||
|
||||
-- name: SoftDeleteScheduleTask :exec
|
||||
UPDATE schedule_tasks SET deleted_at = NOW(), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||
@@ -12,7 +12,7 @@ WHERE tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||
|
||||
-- name: GetRecentArticles :many
|
||||
SELECT a.id, a.generate_status, a.publish_status, a.source_type, a.created_at,
|
||||
av.title, av.word_count, av.source_label,
|
||||
av.title, av.markdown_content, av.word_count, av.source_label,
|
||||
t.template_name
|
||||
FROM articles a
|
||||
LEFT JOIN article_versions av ON av.id = a.current_version_id
|
||||
|
||||
Reference in New Issue
Block a user