20251217170833_29adc7df-c2e5-431f-8dd4-19f163f42926.sql 2.5 KB

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