20260129123056_5320607d-1564-4ca8-8045-391aad84d1fc.sql 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. -- Mise à jour de la fonction purge_old_articles
  2. -- NOUVELLE LOGIQUE : Supprimer les articles non vus depuis 48h
  3. -- SAUF ceux qui sont épinglés par au moins un utilisateur
  4. CREATE OR REPLACE FUNCTION public.purge_old_articles()
  5. RETURNS TABLE(deleted_count integer, admin_emails text[])
  6. LANGUAGE plpgsql
  7. SECURITY DEFINER
  8. SET search_path TO 'public'
  9. AS $$
  10. DECLARE
  11. v_deleted_count INTEGER;
  12. v_admin_emails TEXT[];
  13. v_cutoff_date TIMESTAMP WITH TIME ZONE;
  14. BEGIN
  15. -- Calculer la date limite (48 heures)
  16. v_cutoff_date := NOW() - INTERVAL '48 hours';
  17. -- Récupérer les emails des super users
  18. SELECT ARRAY_AGG(email) INTO v_admin_emails
  19. FROM public.super_users;
  20. -- NOUVELLE LOGIQUE : Supprimer les articles non vus depuis 48h
  21. -- SAUF ceux qui sont épinglés par au moins un utilisateur
  22. WITH articles_to_delete AS (
  23. SELECT a.id
  24. FROM public.articles a
  25. WHERE a.last_seen_at < v_cutoff_date
  26. AND NOT EXISTS (
  27. SELECT 1
  28. FROM public.user_articles ua
  29. WHERE ua.article_id = a.id
  30. AND ua.is_pinned = true -- Seuls les articles épinglés sont protégés
  31. )
  32. LIMIT 1000 -- Limiter pour éviter les timeouts
  33. ),
  34. -- Supprimer d'abord les entrées user_articles associées
  35. deleted_user_articles AS (
  36. DELETE FROM public.user_articles
  37. WHERE article_id IN (SELECT id FROM articles_to_delete)
  38. RETURNING article_id
  39. ),
  40. deleted AS (
  41. DELETE FROM public.articles
  42. WHERE id IN (SELECT id FROM articles_to_delete)
  43. RETURNING id
  44. )
  45. SELECT COUNT(*)::INTEGER INTO v_deleted_count FROM deleted;
  46. -- Log l'opération
  47. RAISE NOTICE 'Purge automatique: % articles supprimés (non vus depuis 48h, non épinglés)', v_deleted_count;
  48. -- Retourner les résultats
  49. RETURN QUERY SELECT v_deleted_count, v_admin_emails;
  50. END;
  51. $$;
  52. -- Mise à jour de la fonction de test pour refléter la nouvelle logique
  53. CREATE OR REPLACE FUNCTION public.test_purge_articles()
  54. RETURNS TABLE(articles_to_delete integer, oldest_article_date timestamp with time zone, newest_article_date timestamp with time zone, sample_titles text[])
  55. LANGUAGE plpgsql
  56. SECURITY DEFINER
  57. SET search_path TO 'public'
  58. AS $$
  59. DECLARE
  60. v_cutoff_date TIMESTAMP WITH TIME ZONE;
  61. BEGIN
  62. v_cutoff_date := NOW() - INTERVAL '48 hours';
  63. RETURN QUERY
  64. WITH eligible_articles AS (
  65. SELECT a.id, a.last_seen_at, a.title
  66. FROM public.articles a
  67. WHERE a.last_seen_at < v_cutoff_date
  68. AND NOT EXISTS (
  69. SELECT 1
  70. FROM public.user_articles ua
  71. WHERE ua.article_id = a.id
  72. AND ua.is_pinned = true -- Seuls les épinglés sont protégés
  73. )
  74. ),
  75. sample_articles AS (
  76. SELECT title
  77. FROM eligible_articles
  78. ORDER BY last_seen_at DESC
  79. LIMIT 5
  80. )
  81. SELECT
  82. (SELECT COUNT(*)::INTEGER FROM eligible_articles),
  83. (SELECT MIN(last_seen_at) FROM eligible_articles),
  84. (SELECT MAX(last_seen_at) FROM eligible_articles),
  85. (SELECT ARRAY_AGG(title) FROM sample_articles);
  86. END;
  87. $$;