mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-10-27 06:47:01 +00:00
170fcd026d
Link cited public help articles in chat replies and emails. Batch reference lookups and keep source metadata out of customer replies.
553 lines
20 KiB
SQL
553 lines
20 KiB
SQL
-- name: get-all-help-centers
|
|
SELECT id, created_at, updated_at, name, slug, page_title, meta_description, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template, livechat_inbox_id
|
|
FROM help_centers
|
|
ORDER BY created_at DESC;
|
|
|
|
-- name: get-active-help-centers
|
|
SELECT id, created_at, updated_at, name, slug, page_title, meta_description, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template, livechat_inbox_id
|
|
FROM help_centers
|
|
WHERE is_active = true
|
|
ORDER BY created_at DESC;
|
|
|
|
-- name: get-help-center-by-id
|
|
SELECT id, created_at, updated_at, name, slug, page_title, meta_description, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template, livechat_inbox_id
|
|
FROM help_centers
|
|
WHERE id = $1;
|
|
|
|
-- name: get-help-center-by-slug
|
|
SELECT id, created_at, updated_at, name, slug, page_title, meta_description, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template, livechat_inbox_id
|
|
FROM help_centers
|
|
WHERE slug = $1 AND is_active = true;
|
|
|
|
-- name: insert-help-center
|
|
INSERT INTO help_centers (name, slug, page_title, meta_description, custom_css, custom_js, default_locale, allowed_locales, theme, custom_domain, template, livechat_inbox_id)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
|
RETURNING *;
|
|
|
|
-- name: update-help-center
|
|
UPDATE help_centers
|
|
SET name = $2, slug = $3, page_title = $4, meta_description = $5, custom_css = $6, custom_js = $7, default_locale = $8, allowed_locales = $9, theme = $10, custom_domain = $11, template = $12, livechat_inbox_id = $13, updated_at = NOW()
|
|
WHERE id = $1
|
|
RETURNING *;
|
|
|
|
-- name: toggle-help-center-active
|
|
UPDATE help_centers
|
|
SET is_active = NOT is_active, updated_at = NOW()
|
|
WHERE id = $1
|
|
RETURNING *;
|
|
|
|
-- name: delete-help-center
|
|
DELETE FROM help_centers
|
|
WHERE id = $1;
|
|
|
|
-- name: get-help-center-locales-in-use
|
|
SELECT DISTINCT locale FROM article_collections WHERE help_center_id = $1
|
|
UNION
|
|
SELECT DISTINCT a.locale
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id
|
|
WHERE c.help_center_id = $1;
|
|
|
|
-- name: get-collections-by-help-center
|
|
SELECT id, created_at, updated_at, help_center_id, slug, parent_id, locale, name, description, icon, sort_order, is_published
|
|
FROM article_collections
|
|
WHERE help_center_id = $1
|
|
ORDER BY sort_order ASC, created_at DESC;
|
|
|
|
-- name: get-collection-by-id
|
|
SELECT id, created_at, updated_at, help_center_id, slug, parent_id, locale, name, description, icon, sort_order, is_published
|
|
FROM article_collections
|
|
WHERE id = $1;
|
|
|
|
-- name: get-collection-subtree-depth
|
|
WITH RECURSIVE subtree AS (
|
|
SELECT id, 1 AS depth FROM article_collections WHERE id = $1
|
|
UNION ALL
|
|
SELECT c.id, s.depth + 1 FROM article_collections c JOIN subtree s ON c.parent_id = s.id
|
|
)
|
|
SELECT COALESCE(MAX(depth), 1) FROM subtree;
|
|
|
|
-- name: lock-help-center
|
|
SELECT id FROM help_centers WHERE id = $1 FOR UPDATE;
|
|
|
|
-- name: lock-help-center-by-collection
|
|
SELECT hc.id FROM help_centers hc
|
|
JOIN article_collections c ON c.help_center_id = hc.id
|
|
WHERE c.id = $1
|
|
FOR UPDATE OF hc;
|
|
|
|
-- name: collection-has-content
|
|
SELECT EXISTS(SELECT 1 FROM article_collections WHERE parent_id = $1)
|
|
OR EXISTS(SELECT 1 FROM help_articles WHERE collection_id = $1);
|
|
|
|
-- name: get-article-ids-in-collection-subtree
|
|
WITH RECURSIVE subtree AS (
|
|
SELECT id FROM article_collections WHERE id = $1
|
|
UNION ALL
|
|
SELECT c.id FROM article_collections c JOIN subtree s ON c.parent_id = s.id
|
|
)
|
|
SELECT a.id FROM help_articles a WHERE a.collection_id IN (SELECT id FROM subtree);
|
|
|
|
-- name: get-article-ids-in-help-center
|
|
SELECT a.id FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id
|
|
WHERE c.help_center_id = $1;
|
|
|
|
-- name: update-collection-sort-order
|
|
UPDATE article_collections
|
|
SET sort_order = $3, updated_at = NOW()
|
|
WHERE id = $1 AND help_center_id = $2;
|
|
|
|
-- name: get-collection-by-id-for-update
|
|
SELECT id, created_at, updated_at, help_center_id, slug, parent_id, locale, name, description, icon, sort_order, is_published
|
|
FROM article_collections
|
|
WHERE id = $1
|
|
FOR UPDATE;
|
|
|
|
-- name: collection-slug-exists-in-help-center
|
|
SELECT EXISTS(
|
|
SELECT 1
|
|
FROM article_collections
|
|
WHERE help_center_id = $1 AND slug = $2 AND locale = $3
|
|
);
|
|
|
|
-- name: insert-collection
|
|
INSERT INTO article_collections (help_center_id, slug, parent_id, locale, name, description, icon, sort_order, is_published)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
|
RETURNING *;
|
|
|
|
-- name: update-collection
|
|
UPDATE article_collections
|
|
SET slug = $2, parent_id = $3, locale = $4, name = $5, description = $6, icon = $7, sort_order = $8, is_published = $9, updated_at = NOW()
|
|
WHERE id = $1
|
|
RETURNING *;
|
|
|
|
-- name: toggle-collection-published
|
|
UPDATE article_collections
|
|
SET is_published = NOT is_published, updated_at = NOW()
|
|
WHERE id = $1
|
|
RETURNING *;
|
|
|
|
-- name: delete-collection
|
|
DELETE FROM article_collections
|
|
WHERE id = $1;
|
|
|
|
-- name: get-article-by-id
|
|
SELECT a.id, a.created_at, a.updated_at, a.collection_id, a.author_id, a.created_by, a.translation_group_id, a.slug, a.locale, a.title, a.content,
|
|
a.excerpt, a.meta_title, a.meta_description, a.meta_image_url, a.sort_order, a.status, a.view_count, a.ai_enabled,
|
|
TRIM(u.first_name || ' ' || COALESCE(u.last_name, '')) AS author_name,
|
|
TRIM(cu.first_name || ' ' || COALESCE(cu.last_name, '')) AS created_by_name,
|
|
(SELECT COUNT(*) FROM help_article_feedback f WHERE f.article_id = a.id AND f.is_helpful) AS helpful_count,
|
|
(SELECT COUNT(*) FROM help_article_feedback f WHERE f.article_id = a.id AND NOT f.is_helpful) AS not_helpful_count
|
|
FROM help_articles a
|
|
LEFT JOIN users u ON u.id = a.author_id
|
|
LEFT JOIN users cu ON cu.id = a.created_by
|
|
WHERE a.id = $1;
|
|
|
|
-- name: get-article-translations
|
|
SELECT a.id, a.collection_id, a.locale, a.slug, a.title, a.status
|
|
FROM help_articles a
|
|
WHERE a.translation_group_id = (SELECT translation_group_id FROM help_articles WHERE id = $1)
|
|
ORDER BY a.locale;
|
|
|
|
-- name: insert-article
|
|
INSERT INTO help_articles (collection_id, author_id, created_by, slug, locale, title, content, excerpt, meta_title, meta_description, meta_image_url, sort_order, status, ai_enabled, translation_group_id)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, COALESCE(NULLIF($15, '')::UUID, gen_random_uuid()))
|
|
RETURNING id, created_at, updated_at, collection_id, author_id, created_by,
|
|
translation_group_id, slug, locale, title, content, excerpt, meta_title,
|
|
meta_description, meta_image_url, sort_order, status, view_count,
|
|
ai_enabled, embedded_fingerprint, search_tsv;
|
|
|
|
-- name: update-article
|
|
UPDATE help_articles
|
|
SET collection_id = COALESCE($9, collection_id), slug = $2, locale = $3, title = $4, content = $5, sort_order = $6, status = $7, ai_enabled = $8,
|
|
excerpt = $10, meta_title = $11, meta_description = $12, meta_image_url = $13, author_id = $14, updated_at = NOW()
|
|
WHERE id = $1
|
|
RETURNING id, created_at, updated_at, collection_id, author_id, created_by,
|
|
translation_group_id, slug, locale, title, content, excerpt, meta_title,
|
|
meta_description, meta_image_url, sort_order, status, view_count,
|
|
ai_enabled, embedded_fingerprint, search_tsv;
|
|
|
|
-- name: user-is-author-assignable
|
|
SELECT EXISTS(
|
|
SELECT 1 FROM users
|
|
WHERE id = $1 AND type IN ('agent', 'ai_assistant') AND deleted_at IS NULL
|
|
);
|
|
|
|
-- name: article-slug-exists-in-help-center
|
|
SELECT EXISTS(
|
|
SELECT 1
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id
|
|
WHERE c.help_center_id = (SELECT help_center_id FROM article_collections WHERE id = $1)
|
|
AND a.slug = $2 AND a.locale = $3
|
|
);
|
|
|
|
-- name: other-article-slug-exists-in-help-center
|
|
SELECT EXISTS(
|
|
SELECT 1
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id
|
|
WHERE c.help_center_id = (SELECT help_center_id FROM article_collections WHERE id = $1)
|
|
AND a.slug = $2 AND a.locale = $3 AND a.id <> $4
|
|
);
|
|
|
|
-- name: move-article-to-collection
|
|
UPDATE help_articles
|
|
SET collection_id = $2, updated_at = NOW()
|
|
WHERE id = $1
|
|
RETURNING *;
|
|
|
|
-- name: update-article-sort-order
|
|
UPDATE help_articles
|
|
SET sort_order = $3, updated_at = NOW()
|
|
WHERE id = $1 AND collection_id = $2;
|
|
|
|
-- name: update-article-status
|
|
UPDATE help_articles
|
|
SET status = $2, updated_at = NOW()
|
|
WHERE id = $1
|
|
RETURNING *;
|
|
|
|
-- name: get-linkable-translation-articles
|
|
SELECT a.id, a.title, a.locale, c.name AS collection_name
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id
|
|
WHERE c.help_center_id = $1
|
|
AND a.locale != $2
|
|
AND NOT EXISTS (
|
|
SELECT 1 FROM help_articles sibling
|
|
WHERE sibling.translation_group_id = a.translation_group_id AND sibling.id != a.id
|
|
)
|
|
ORDER BY a.locale, a.title;
|
|
|
|
-- name: article-locale-in-translation-group
|
|
SELECT EXISTS(
|
|
SELECT 1 FROM help_articles
|
|
WHERE translation_group_id = $1 AND locale = $2
|
|
);
|
|
|
|
-- name: count-article-translation-siblings
|
|
SELECT COUNT(*) FROM help_articles
|
|
WHERE translation_group_id = $1 AND id != $2;
|
|
|
|
-- name: link-article-translation
|
|
UPDATE help_articles a
|
|
SET translation_group_id = $2::UUID, updated_at = NOW()
|
|
WHERE a.id = $1
|
|
AND NOT EXISTS (
|
|
SELECT 1 FROM help_articles sibling
|
|
WHERE sibling.translation_group_id = a.translation_group_id AND sibling.id != a.id
|
|
)
|
|
RETURNING *;
|
|
|
|
-- name: unlink-article-translation
|
|
UPDATE help_articles
|
|
SET translation_group_id = gen_random_uuid(), updated_at = NOW()
|
|
WHERE id = $1
|
|
RETURNING *;
|
|
|
|
-- name: delete-article
|
|
DELETE FROM help_articles
|
|
WHERE id = $1;
|
|
|
|
-- name: get-help-center-tree-data
|
|
SELECT
|
|
'collection' AS type,
|
|
c.id,
|
|
c.created_at,
|
|
c.updated_at,
|
|
c.help_center_id,
|
|
c.slug,
|
|
c.parent_id,
|
|
c.locale,
|
|
c.name,
|
|
c.description,
|
|
c.icon,
|
|
c.sort_order,
|
|
c.is_published,
|
|
NULL::INTEGER AS collection_id,
|
|
NULL::TEXT AS title,
|
|
NULL::TEXT AS content,
|
|
NULL::TEXT AS status,
|
|
NULL::INTEGER AS view_count,
|
|
NULL::BOOLEAN AS ai_enabled,
|
|
NULL::TEXT AS author_name,
|
|
NULL::TEXT AS author_avatar
|
|
FROM article_collections c
|
|
WHERE c.help_center_id = $1 AND ($2 = '' OR c.locale = $2)
|
|
|
|
UNION ALL
|
|
|
|
SELECT
|
|
'article' AS type,
|
|
a.id,
|
|
a.created_at,
|
|
a.updated_at,
|
|
c.help_center_id,
|
|
a.slug,
|
|
NULL::INTEGER AS parent_id,
|
|
a.locale,
|
|
a.title AS name,
|
|
NULL::TEXT AS description,
|
|
NULL::TEXT AS icon,
|
|
a.sort_order,
|
|
NULL::BOOLEAN AS is_published,
|
|
a.collection_id,
|
|
a.title,
|
|
'' AS content,
|
|
a.status,
|
|
a.view_count,
|
|
a.ai_enabled,
|
|
NULL::TEXT AS author_name,
|
|
NULL::TEXT AS author_avatar
|
|
FROM help_articles a
|
|
JOIN article_collections c ON a.collection_id = c.id
|
|
WHERE c.help_center_id = $1 AND ($2 = '' OR a.locale = $2)
|
|
|
|
ORDER BY type DESC, parent_id NULLS FIRST, sort_order, name;
|
|
|
|
-- name: get-public-tree-data
|
|
WITH RECURSIVE published_collections AS (
|
|
SELECT id FROM article_collections
|
|
WHERE help_center_id = $1 AND parent_id IS NULL AND is_published = true AND ($2 = '' OR locale = $2)
|
|
UNION
|
|
SELECT c.id FROM article_collections c
|
|
JOIN published_collections p ON c.parent_id = p.id
|
|
WHERE c.is_published = true AND ($2 = '' OR c.locale = $2)
|
|
)
|
|
SELECT
|
|
'collection' AS type,
|
|
c.id,
|
|
c.created_at,
|
|
c.updated_at,
|
|
c.help_center_id,
|
|
c.slug,
|
|
c.parent_id,
|
|
c.locale,
|
|
c.name,
|
|
c.description,
|
|
c.icon,
|
|
c.sort_order,
|
|
c.is_published,
|
|
NULL::INTEGER AS collection_id,
|
|
NULL::TEXT AS title,
|
|
NULL::TEXT AS content,
|
|
NULL::TEXT AS status,
|
|
NULL::INTEGER AS view_count,
|
|
NULL::BOOLEAN AS ai_enabled,
|
|
NULL::TEXT AS author_name,
|
|
NULL::TEXT AS author_avatar
|
|
FROM article_collections c
|
|
WHERE c.id IN (SELECT id FROM published_collections)
|
|
|
|
UNION ALL
|
|
|
|
SELECT
|
|
'article' AS type,
|
|
a.id,
|
|
a.created_at,
|
|
a.updated_at,
|
|
c.help_center_id,
|
|
a.slug,
|
|
NULL::INTEGER AS parent_id,
|
|
a.locale,
|
|
a.title AS name,
|
|
NULL::TEXT AS description,
|
|
NULL::TEXT AS icon,
|
|
a.sort_order,
|
|
NULL::BOOLEAN AS is_published,
|
|
a.collection_id,
|
|
a.title,
|
|
'' AS content,
|
|
a.status,
|
|
a.view_count,
|
|
a.ai_enabled,
|
|
TRIM(u.first_name || ' ' || COALESCE(u.last_name, '')) AS author_name,
|
|
u.avatar_url AS author_avatar
|
|
FROM help_articles a
|
|
JOIN article_collections c ON a.collection_id = c.id AND c.locale = a.locale
|
|
LEFT JOIN users u ON u.id = a.author_id
|
|
WHERE c.id IN (SELECT id FROM published_collections) AND a.status = 'published'
|
|
AND ($2 = '' OR a.locale = $2)
|
|
|
|
ORDER BY type DESC, parent_id NULLS FIRST, sort_order, name;
|
|
|
|
-- name: get-published-article-by-slug
|
|
WITH RECURSIVE published_collections AS (
|
|
SELECT c.id FROM article_collections c
|
|
JOIN help_centers h ON h.id = c.help_center_id
|
|
WHERE h.slug = $1 AND c.parent_id IS NULL AND c.is_published = true
|
|
UNION
|
|
SELECT c.id FROM article_collections c
|
|
JOIN published_collections p ON c.parent_id = p.id
|
|
WHERE c.is_published = true
|
|
)
|
|
SELECT a.id, a.created_at, a.updated_at, a.collection_id, a.author_id, a.slug, a.locale, a.title, a.content,
|
|
a.excerpt, a.meta_title, a.meta_description, a.meta_image_url, a.sort_order, a.status, a.view_count, a.ai_enabled,
|
|
TRIM(u.first_name || ' ' || COALESCE(u.last_name, '')) AS author_name,
|
|
u.avatar_url AS author_avatar
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id AND c.locale = a.locale AND c.id IN (SELECT id FROM published_collections)
|
|
LEFT JOIN users u ON u.id = a.author_id
|
|
WHERE a.slug = $2 AND a.status = 'published' AND ($3 = '' OR a.locale = $3)
|
|
ORDER BY c.sort_order, a.sort_order, a.id
|
|
LIMIT 1;
|
|
|
|
-- name: get-published-article-translations
|
|
WITH RECURSIVE published_collections AS (
|
|
SELECT c.id FROM article_collections c
|
|
JOIN help_centers h ON h.id = c.help_center_id
|
|
WHERE h.slug = $1 AND c.parent_id IS NULL AND c.is_published = true
|
|
UNION
|
|
SELECT c.id FROM article_collections c
|
|
JOIN published_collections p ON c.parent_id = p.id
|
|
WHERE c.is_published = true
|
|
)
|
|
SELECT a.id, a.collection_id, a.locale, a.slug, a.title, a.status
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id AND c.locale = a.locale AND c.id IN (SELECT id FROM published_collections)
|
|
WHERE a.translation_group_id = (SELECT translation_group_id FROM help_articles WHERE id = $2)
|
|
AND a.status = 'published'
|
|
ORDER BY a.locale;
|
|
|
|
-- name: get-published-collection-locales
|
|
WITH RECURSIVE published_collections AS (
|
|
SELECT c.id FROM article_collections c
|
|
JOIN help_centers h ON h.id = c.help_center_id
|
|
WHERE h.slug = $1 AND c.parent_id IS NULL AND c.is_published = true
|
|
UNION
|
|
SELECT c.id FROM article_collections c
|
|
JOIN published_collections p ON c.parent_id = p.id
|
|
WHERE c.is_published = true
|
|
)
|
|
SELECT DISTINCT c.locale
|
|
FROM article_collections c
|
|
WHERE c.slug = $2 AND c.id IN (SELECT id FROM published_collections);
|
|
|
|
-- name: get-published-articles
|
|
WITH RECURSIVE published_collections AS (
|
|
SELECT c.id FROM article_collections c
|
|
JOIN help_centers h ON h.id = c.help_center_id
|
|
WHERE h.slug = $1 AND c.parent_id IS NULL AND c.is_published = true
|
|
UNION
|
|
SELECT c.id FROM article_collections c
|
|
JOIN published_collections p ON c.parent_id = p.id
|
|
WHERE c.is_published = true
|
|
)
|
|
SELECT a.id, a.created_at, a.updated_at, a.collection_id, a.slug, a.locale, a.title, a.excerpt, '' AS content, a.sort_order, a.status, a.view_count, a.ai_enabled
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id AND c.locale = a.locale AND c.id IN (SELECT id FROM published_collections)
|
|
WHERE a.status = 'published' AND ($2 = '' OR a.locale = $2)
|
|
ORDER BY a.view_count DESC, a.created_at DESC
|
|
LIMIT $3;
|
|
|
|
-- name: get-published-articles-by-collection
|
|
SELECT a.id, a.created_at, a.updated_at, a.collection_id, a.slug, a.locale, a.title, a.excerpt, '' AS content, a.sort_order, a.status, a.view_count, a.ai_enabled
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id AND c.locale = a.locale
|
|
WHERE a.collection_id = $1 AND a.id != $2 AND a.status = 'published' AND ($3 = '' OR a.locale = $3)
|
|
ORDER BY a.sort_order ASC, a.created_at DESC
|
|
LIMIT $4;
|
|
|
|
-- name: search-published-articles
|
|
WITH RECURSIVE published_collections AS (
|
|
SELECT c.id FROM article_collections c
|
|
JOIN help_centers h ON h.id = c.help_center_id
|
|
WHERE h.slug = $1 AND c.parent_id IS NULL AND c.is_published = true
|
|
UNION
|
|
SELECT c.id FROM article_collections c
|
|
JOIN published_collections p ON c.parent_id = p.id
|
|
WHERE c.is_published = true
|
|
)
|
|
SELECT a.id, a.created_at, a.updated_at, a.collection_id, a.slug, a.locale, a.title,
|
|
a.excerpt AS content,
|
|
a.sort_order, a.status, a.view_count, a.ai_enabled
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id AND c.locale = a.locale AND c.id IN (SELECT id FROM published_collections)
|
|
WHERE a.status = 'published' AND a.locale = $4
|
|
AND (a.search_tsv @@ to_tsquery(help_article_search_config($4), NULLIF($5, ''))
|
|
OR a.title ILIKE $2 ESCAPE '\' OR a.content ILIKE $2 ESCAPE '\')
|
|
ORDER BY ts_rank(a.search_tsv, to_tsquery(help_article_search_config($4), NULLIF($5, '')), 2) DESC, a.view_count DESC, a.created_at DESC
|
|
LIMIT $3;
|
|
|
|
-- name: increment-article-view-count
|
|
UPDATE help_articles
|
|
SET view_count = view_count + 1
|
|
WHERE id = $1;
|
|
|
|
-- name: increment-published-article-view-count
|
|
WITH RECURSIVE published_collections AS (
|
|
SELECT c.id FROM article_collections c
|
|
JOIN help_centers h ON h.id = c.help_center_id
|
|
WHERE h.slug = $1 AND c.parent_id IS NULL AND c.is_published = true
|
|
UNION
|
|
SELECT c.id FROM article_collections c
|
|
JOIN published_collections p ON c.parent_id = p.id
|
|
WHERE c.is_published = true
|
|
)
|
|
UPDATE help_articles
|
|
SET view_count = view_count + 1
|
|
WHERE id = (
|
|
SELECT a.id
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id AND c.locale = a.locale AND c.id IN (SELECT id FROM published_collections)
|
|
WHERE a.slug = $2 AND a.status = 'published' AND ($3 = '' OR a.locale = $3)
|
|
ORDER BY c.sort_order, a.sort_order, a.id
|
|
LIMIT 1
|
|
);
|
|
|
|
-- name: insert-article-feedback
|
|
INSERT INTO help_article_feedback (article_id, is_helpful)
|
|
SELECT $1, $2
|
|
WHERE EXISTS (SELECT 1 FROM help_articles WHERE id = $1 AND status = 'published');
|
|
|
|
-- name: insert-search-query
|
|
INSERT INTO help_search_queries (help_center_id, query, results_count)
|
|
VALUES ($1, $2, $3);
|
|
|
|
-- name: get-top-search-terms
|
|
SELECT LOWER(query) AS query, COUNT(*) AS count,
|
|
COUNT(*) FILTER (WHERE results_count = 0) AS no_results,
|
|
MAX(created_at)::text AS last_search
|
|
FROM help_search_queries
|
|
WHERE help_center_id = $1 AND created_at >= NOW() - ($3 * INTERVAL '1 day')
|
|
GROUP BY LOWER(query)
|
|
ORDER BY count DESC, last_search DESC
|
|
LIMIT $2;
|
|
|
|
-- name: get-no-result-search-terms
|
|
SELECT LOWER(query) AS query, COUNT(*) AS count,
|
|
COUNT(*) AS no_results,
|
|
MAX(created_at)::text AS last_search
|
|
FROM help_search_queries
|
|
WHERE help_center_id = $1 AND results_count = 0 AND created_at >= NOW() - ($3 * INTERVAL '1 day')
|
|
GROUP BY LOWER(query)
|
|
ORDER BY count DESC, last_search DESC
|
|
LIMIT $2;
|
|
|
|
-- name: delete-stale-search-queries
|
|
DELETE FROM help_search_queries
|
|
WHERE created_at < NOW() - ($1 * INTERVAL '1 day');
|
|
|
|
-- name: get-article-references
|
|
WITH RECURSIVE article_ancestors AS (
|
|
SELECT a.id AS article_id, c.id, c.parent_id, c.help_center_id, c.is_published
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id AND c.locale = a.locale
|
|
WHERE a.id = ANY($1) AND a.status = 'published' AND a.ai_enabled = true
|
|
UNION
|
|
SELECT p.article_id, c.id, c.parent_id, c.help_center_id, c.is_published
|
|
FROM article_collections c
|
|
JOIN article_ancestors p ON c.id = p.parent_id AND c.help_center_id = p.help_center_id
|
|
)
|
|
SELECT a.id, a.title, a.slug, a.locale, hc.slug AS help_center_slug, hc.custom_domain
|
|
FROM help_articles a
|
|
JOIN article_collections c ON c.id = a.collection_id
|
|
JOIN help_centers hc ON hc.id = c.help_center_id
|
|
WHERE a.id = ANY($1) AND a.status = 'published' AND a.ai_enabled = true AND hc.is_active = true
|
|
AND (a.locale = hc.default_locale OR hc.allowed_locales ? a.locale)
|
|
AND EXISTS (SELECT 1 FROM article_ancestors p WHERE p.article_id = a.id AND p.parent_id IS NULL)
|
|
AND NOT EXISTS (SELECT 1 FROM article_ancestors p WHERE p.article_id = a.id AND p.is_published = false)
|
|
ORDER BY array_position($1::integer[], a.id);
|