Просмотр исходного кода

Utilise last_seen_at pour purge

Met à jour la fonction de purge pour s’appuyer sur last_seen_at au lieu de published_at et protège tous les articles liés à un utilisateur avant suppression; corrige l’import Resend dans send-purge-report et adapte le contenu email correspondants.

X-Lovable-Edit-ID: edt-9fe3c6f3-3b89-42ca-9353-881d29668de5
gpt-engineer-app[bot] 1 неделя назад
Родитель
Сommit
fa84310238

+ 3 - 8
supabase/functions/send-purge-report/index.ts

@@ -6,7 +6,7 @@
  */
 
 import { serve } from "https://deno.land/std@0.177.0/http/server.ts";
-import { Resend } from "npm:resend@2.0.0";
+import { Resend } from "https://esm.sh/resend@2.0.0";
 
 const resend = new Resend(Deno.env.get("RESEND_API_KEY"));
 
@@ -157,13 +157,8 @@ const handler = async (req: Request): Promise<Response> => {
             <div class="criteria">
               <h3>📋 Critères de purge appliqués</h3>
               <ul>
-                <li><strong>Âge des articles :</strong> Plus de 48 heures (2 jours)</li>
-                <li><strong>Articles préservés :</strong> 
-                  <ul>
-                    <li>Articles épinglés par au moins un utilisateur</li>
-                    <li>Articles avec plus de 20 lectures</li>
-                  </ul>
-                </li>
+                <li><strong>Critère principal :</strong> Non vu dans le flux RSS depuis 48 heures</li>
+                <li><strong>Articles préservés :</strong> Tous les articles ayant été consultés par au moins un utilisateur</li>
                 <li><strong>Fréquence :</strong> Tous les jours à 3h00 du matin</li>
               </ul>
             </div>

+ 85 - 0
supabase/migrations/20251217170833_29adc7df-c2e5-431f-8dd4-19f163f42926.sql

@@ -0,0 +1,85 @@
+-- Mettre à jour la fonction purge_old_articles pour utiliser last_seen_at
+-- et protéger tous les articles associés à un utilisateur
+CREATE OR REPLACE FUNCTION public.purge_old_articles()
+ RETURNS TABLE(deleted_count integer, admin_emails text[])
+ LANGUAGE plpgsql
+ SECURITY DEFINER
+ SET search_path TO 'public'
+AS $function$
+DECLARE
+  v_deleted_count INTEGER;
+  v_admin_emails TEXT[];
+  v_cutoff_date TIMESTAMP WITH TIME ZONE;
+BEGIN
+  -- Calculer la date limite (48 heures)
+  v_cutoff_date := NOW() - INTERVAL '48 hours';
+  
+  -- Récupérer les emails des super users
+  SELECT ARRAY_AGG(email) INTO v_admin_emails
+  FROM public.super_users;
+  
+  -- Supprimer les articles non vus depuis 48h et sans interaction utilisateur
+  WITH articles_to_delete AS (
+    SELECT a.id
+    FROM public.articles a
+    WHERE a.last_seen_at < v_cutoff_date
+    AND NOT EXISTS (
+      SELECT 1 
+      FROM public.user_articles ua
+      WHERE ua.article_id = a.id
+      -- Tout article avec une entrée user_articles est protégé
+    )
+    LIMIT 1000  -- Limiter pour éviter les timeouts
+  ),
+  deleted AS (
+    DELETE FROM public.articles
+    WHERE id IN (SELECT id FROM articles_to_delete)
+    RETURNING id
+  )
+  SELECT COUNT(*)::INTEGER INTO v_deleted_count FROM deleted;
+  
+  -- Log l'opération
+  RAISE NOTICE 'Purge automatique: % articles supprimés (non vus depuis 48h)', v_deleted_count;
+  
+  -- Retourner les résultats
+  RETURN QUERY SELECT v_deleted_count, v_admin_emails;
+END;
+$function$;
+
+-- Mettre à jour la fonction test_purge_articles avec les mêmes critères
+CREATE OR REPLACE FUNCTION public.test_purge_articles()
+ RETURNS TABLE(articles_to_delete integer, oldest_article_date timestamp with time zone, newest_article_date timestamp with time zone, sample_titles text[])
+ LANGUAGE plpgsql
+ SECURITY DEFINER
+ SET search_path TO 'public'
+AS $function$
+DECLARE
+  v_cutoff_date TIMESTAMP WITH TIME ZONE;
+BEGIN
+  v_cutoff_date := NOW() - INTERVAL '48 hours';
+  
+  RETURN QUERY
+  WITH eligible_articles AS (
+    SELECT a.id, a.last_seen_at, a.title
+    FROM public.articles a
+    WHERE a.last_seen_at < v_cutoff_date
+    AND NOT EXISTS (
+      SELECT 1 
+      FROM public.user_articles ua
+      WHERE ua.article_id = a.id
+    )
+  ),
+  sample_articles AS (
+    SELECT title
+    FROM eligible_articles
+    ORDER BY last_seen_at DESC
+    LIMIT 5
+  )
+  SELECT 
+    (SELECT COUNT(*)::INTEGER FROM eligible_articles),
+    (SELECT MIN(last_seen_at) FROM eligible_articles),
+    (SELECT MAX(last_seen_at) FROM eligible_articles),
+    (SELECT ARRAY_AGG(title) FROM sample_articles)
+  ;
+END;
+$function$;