diff --git a/server/internal/tenant/repository/generated/workspace.sql.go b/server/internal/tenant/repository/generated/workspace.sql.go index 6b203b3..fac2170 100644 --- a/server/internal/tenant/repository/generated/workspace.sql.go +++ b/server/internal/tenant/repository/generated/workspace.sql.go @@ -104,7 +104,16 @@ func (q *Queries) GetQuotaSummary(ctx context.Context, tenantID int64) (int32, e } const getRecentArticlesByBrand = `-- name: GetRecentArticlesByBrand :many -SELECT a.id, a.brand_id, a.generate_status, a.publish_status, a.source_type, a.created_at, +SELECT a.id, a.brand_id, a.generate_status, + CASE + WHEN COALESCE(publish_status_summary.record_count, 0) = 0 THEN a.publish_status + WHEN COALESCE(publish_status_summary.has_publishing, false) THEN 'publishing' + WHEN COALESCE(publish_status_summary.has_success, false) + AND COALESCE(publish_status_summary.has_failed, false) THEN 'partial_success' + WHEN COALESCE(publish_status_summary.has_success, false) THEN 'success' + ELSE 'failed' + END AS publish_status, + a.source_type, a.created_at, av.title, av.markdown_content, av.word_count, av.source_label, t.template_name, COALESCE( @@ -114,6 +123,37 @@ SELECT a.id, a.brand_id, a.generate_status, a.publish_status, a.source_type, a.c FROM articles a LEFT JOIN article_versions av ON av.id = a.current_version_id LEFT JOIN article_templates t ON t.id = a.template_id +LEFT JOIN LATERAL ( + SELECT COUNT(*) AS record_count, + BOOL_OR(latest.status_bucket = 'publishing') AS has_publishing, + BOOL_OR(latest.status_bucket = 'success') AS has_success, + BOOL_OR(latest.status_bucket = 'failed') AS has_failed + FROM ( + SELECT DISTINCT ON ( + CASE + WHEN COALESCE(pr.target_type, 'platform_account') = 'enterprise_site' + THEN 'enterprise_site:' || COALESCE(pr.target_connection_id::TEXT, '') + ELSE 'platform_account:' || pr.platform_id || ':' || COALESCE(NULLIF(pa.platform_uid, ''), pr.platform_account_id::TEXT, '') + END + ) + CASE + WHEN pr.status IN ('success', 'published', 'publish_success') THEN 'success' + WHEN pr.status IN ('publishing', 'pending', 'queued', 'running') THEN 'publishing' + ELSE 'failed' + END AS status_bucket, + CASE + WHEN COALESCE(pr.target_type, 'platform_account') = 'enterprise_site' + THEN 'enterprise_site:' || COALESCE(pr.target_connection_id::TEXT, '') + ELSE 'platform_account:' || pr.platform_id || ':' || COALESCE(NULLIF(pa.platform_uid, ''), pr.platform_account_id::TEXT, '') + END AS target_identity + FROM publish_records pr + LEFT JOIN platform_accounts pa ON pa.id = pr.platform_account_id + WHERE pr.tenant_id = a.tenant_id + AND pr.article_id = a.id + AND pr.deleted_at IS NULL + ORDER BY target_identity, pr.created_at DESC, pr.id DESC + ) latest +) publish_status_summary ON true LEFT JOIN LATERAL ( SELECT input_params_json FROM generation_tasks diff --git a/server/internal/tenant/repository/queries/workspace.sql b/server/internal/tenant/repository/queries/workspace.sql index 9f88a54..97733a7 100644 --- a/server/internal/tenant/repository/queries/workspace.sql +++ b/server/internal/tenant/repository/queries/workspace.sql @@ -11,7 +11,16 @@ SELECT COUNT(*) FROM brands WHERE tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL; -- name: GetRecentArticlesByBrand :many -SELECT a.id, a.brand_id, a.generate_status, a.publish_status, a.source_type, a.created_at, +SELECT a.id, a.brand_id, a.generate_status, + CASE + WHEN COALESCE(publish_status_summary.record_count, 0) = 0 THEN a.publish_status + WHEN COALESCE(publish_status_summary.has_publishing, false) THEN 'publishing' + WHEN COALESCE(publish_status_summary.has_success, false) + AND COALESCE(publish_status_summary.has_failed, false) THEN 'partial_success' + WHEN COALESCE(publish_status_summary.has_success, false) THEN 'success' + ELSE 'failed' + END AS publish_status, + a.source_type, a.created_at, av.title, av.markdown_content, av.word_count, av.source_label, t.template_name, COALESCE( @@ -21,6 +30,37 @@ SELECT a.id, a.brand_id, a.generate_status, a.publish_status, a.source_type, a.c FROM articles a LEFT JOIN article_versions av ON av.id = a.current_version_id LEFT JOIN article_templates t ON t.id = a.template_id +LEFT JOIN LATERAL ( + SELECT COUNT(*) AS record_count, + BOOL_OR(latest.status_bucket = 'publishing') AS has_publishing, + BOOL_OR(latest.status_bucket = 'success') AS has_success, + BOOL_OR(latest.status_bucket = 'failed') AS has_failed + FROM ( + SELECT DISTINCT ON ( + CASE + WHEN COALESCE(pr.target_type, 'platform_account') = 'enterprise_site' + THEN 'enterprise_site:' || COALESCE(pr.target_connection_id::TEXT, '') + ELSE 'platform_account:' || pr.platform_id || ':' || COALESCE(NULLIF(pa.platform_uid, ''), pr.platform_account_id::TEXT, '') + END + ) + CASE + WHEN pr.status IN ('success', 'published', 'publish_success') THEN 'success' + WHEN pr.status IN ('publishing', 'pending', 'queued', 'running') THEN 'publishing' + ELSE 'failed' + END AS status_bucket, + CASE + WHEN COALESCE(pr.target_type, 'platform_account') = 'enterprise_site' + THEN 'enterprise_site:' || COALESCE(pr.target_connection_id::TEXT, '') + ELSE 'platform_account:' || pr.platform_id || ':' || COALESCE(NULLIF(pa.platform_uid, ''), pr.platform_account_id::TEXT, '') + END AS target_identity + FROM publish_records pr + LEFT JOIN platform_accounts pa ON pa.id = pr.platform_account_id + WHERE pr.tenant_id = a.tenant_id + AND pr.article_id = a.id + AND pr.deleted_at IS NULL + ORDER BY target_identity, pr.created_at DESC, pr.id DESC + ) latest +) publish_status_summary ON true LEFT JOIN LATERAL ( SELECT input_params_json FROM generation_tasks