From 010df60ecc60ffa038c46015682c6b6f15f42b0b Mon Sep 17 00:00:00 2001 From: Roberto Milla Martinez Date: Thu, 21 Nov 2024 15:40:59 +0100 Subject: [PATCH 1/2] feat: schedule delete --- src/components/HelpOffers/HelpOfferForm.tsx | 10 ++ .../HelpRequests/HelpRequestForm.tsx | 10 ++ ...20241121143450_delete_expired_requests.sql | 138 ++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 supabase/migrations/20241121143450_delete_expired_requests.sql diff --git a/src/components/HelpOffers/HelpOfferForm.tsx b/src/components/HelpOffers/HelpOfferForm.tsx index e8ad3fc..c490946 100644 --- a/src/components/HelpOffers/HelpOfferForm.tsx +++ b/src/components/HelpOffers/HelpOfferForm.tsx @@ -9,6 +9,7 @@ import Unauthorized from '@/components/Unauthorized'; import { useTowns } from '@/context/TownProvider'; import { toast } from 'sonner'; import { CheckboxLegalText } from '../CheckboxLegalText'; +import { InfoIcon } from 'lucide-react'; export type HelpOfferFormData = { aceptaProtocolo: boolean; @@ -272,6 +273,15 @@ export default function HelpOfferForm({ data, buttonText, submitMutation }: Help {buttonText[0]} +
+ +
+

+ Las ofertas de ayuda se borrarán automáticamente a los 7 días. Si lo deseas, tras este plazo puedes crear + una nueva oferta con datos actualizados. +

+
+
); } diff --git a/src/components/HelpRequests/HelpRequestForm.tsx b/src/components/HelpRequests/HelpRequestForm.tsx index 5cb5d3f..8bc17e6 100644 --- a/src/components/HelpRequests/HelpRequestForm.tsx +++ b/src/components/HelpRequests/HelpRequestForm.tsx @@ -12,6 +12,7 @@ import { LngLat } from '@/components/map/GeolocationMap'; import { useSession } from '@/context/SessionProvider'; import Unauthorized from '@/components/Unauthorized'; import { CheckboxLegalText } from '../CheckboxLegalText'; +import { InfoIcon } from 'lucide-react'; export type HelpRequestFormData = { nombre: string; @@ -276,6 +277,15 @@ export default function HelpRequestForm({ > {isSubmitting ? buttonText[1] : buttonText[0]} +
+ +
+

+ Las solicitudes de ayuda se borrarán automáticamente a los 7 días. Si tras este plazo sigues necesitando + ayuda, crea una nueva solicitud con datos actualizados. +

+
+
); } diff --git a/supabase/migrations/20241121143450_delete_expired_requests.sql b/supabase/migrations/20241121143450_delete_expired_requests.sql new file mode 100644 index 0000000..f81deb7 --- /dev/null +++ b/supabase/migrations/20241121143450_delete_expired_requests.sql @@ -0,0 +1,138 @@ +create extension if not exists pg_cron with schema extensions; +create extension if not exists http with schema extensions; + +grant usage on schema cron to postgres; +grant all privileges on all tables in schema cron to postgres; + +select cron.schedule ( + 'delete_expired_records', -- name of the cron job + '*/5 * * * *', -- Every day at 4:00am (GMT) + $$ delete from public.help_requests where created_at < now() - interval '7 days'; $$ +); + +alter table public.help_requests add column expiry_notice_sent boolean default false; + +create index if not exists idx_help_requests_created_at on public.help_requests using btree (created_at, expiry_notice_sent, type); + +create or replace function send_request_expiry_notices() returns void as $$ +declare + api_key text; + email_body text; + email_list text[]; + help_request_ids bigint[]; + status_code int; +begin + -- Get the RESEND_API_KEY + select decrypted_secret into api_key + from vault.decrypted_secrets + where name = 'RESEND_API_KEY' + limit 1; + + -- If the API key is not found, do nothing + if api_key is null then + return; + end if; + + -- Construct the email body + email_body := 'Tu solicitud de ayuda en ajudadana.es caducará en 1 día y será eliminada automáticamente. Si todavía necesitas ayuda, considera crear una solicitud nueva con datos actualizados.'; + + -- Collect email addresses and help request IDs + select array_agg(u.email), array_agg(h.id) + into email_list, help_request_ids + from public.help_requests h + join auth.users u on h.user_id = u.id + where h.created_at < now() - interval '6 days' + and h.created_at >= now() - interval '7 days' + and h.expiry_notice_sent = false + and h.status = 'active' + and h.type = 'necesita' + limit 50; + + -- If there are no emails to send, do nothing + if email_list is null then + return; + end if; + + -- Send the email using the resend API + select status into status_code from http(( + 'POST', + 'https://api.resend.com/emails', + array[http_header('Authorization','Bearer ' || api_key)], + 'application/json', + '{ + "from": "Ajudadana ", + "to": ["' || array_to_string(email_list, '","') || '"], + "subject": "Tu solicitud en Ajudadana.es será eliminada", + "html": "

' || email_body || '

" + }' + )::http_request); + + if status_code <> 200 then + return; + end if; + + -- Update the help requests to mark the expiry notice as sent + update help_requests set expiry_notice_sent = true where id = any(help_request_ids); +end; +$$ language plpgsql; + +create or replace function send_offer_expiry_notices() returns void as $$ +declare + api_key text; + email_body text; + email_list text[]; + help_request_ids bigint[]; + status_code int; +begin + -- Get the RESEND_API_KEY + select decrypted_secret into api_key + from vault.decrypted_secrets + where name = 'RESEND_API_KEY' + limit 1; + + -- If the API key is not found, do nothing + if api_key is null then + return; + end if; + + -- Construct the email body + email_body := 'Tu oferta de ayuda en ajudadana.es caducará en 1 día y será eliminada automáticamente. Si lo deseas, crea una oferta de ayuda nueva con datos actualizados.'; + + -- Collect email addresses and help request IDs + select array_agg(u.email), array_agg(h.id) + into email_list, help_request_ids + from public.help_requests h + join auth.users u on h.user_id = u.id + where h.created_at < now() - interval '6 days' + and h.created_at >= now() - interval '7 days' + and h.expiry_notice_sent = false + and h.type = 'ofrece' + limit 50; + + -- If there are no emails to send, do nothing + if email_list is null then + return; + end if; + + -- Send the email using the resend API + select status into status_code from http(( + 'POST', + 'https://api.resend.com/emails', + array[http_header('Authorization','Bearer ' || api_key)], + 'application/json', + '{ + "from": "Ajudadana ", + "to": ["' || array_to_string(email_list, '","') || '"], + "subject": "Tu oferta de ayuda en Ajudadana.es será eliminada", + "html": "

' || email_body || '

" + }' + )::http_request); + + if status_code <> 200 then + return; + end if; + + -- Update the help requests to mark the expiry notice as sent + update help_requests set expiry_notice_sent = true where id = any(help_request_ids); +end; +$$ language plpgsql; From dafcb1c627b8db9ece8c2d0d60a45eab845f3959 Mon Sep 17 00:00:00 2001 From: Roberto Milla Martinez Date: Thu, 21 Nov 2024 15:41:47 +0100 Subject: [PATCH 2/2] fix: every day at 4.00 --- supabase/migrations/20241121143450_delete_expired_requests.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/supabase/migrations/20241121143450_delete_expired_requests.sql b/supabase/migrations/20241121143450_delete_expired_requests.sql index f81deb7..126006d 100644 --- a/supabase/migrations/20241121143450_delete_expired_requests.sql +++ b/supabase/migrations/20241121143450_delete_expired_requests.sql @@ -6,7 +6,7 @@ grant all privileges on all tables in schema cron to postgres; select cron.schedule ( 'delete_expired_records', -- name of the cron job - '*/5 * * * *', -- Every day at 4:00am (GMT) + '0 4 * * *', -- Every day at 4:00am (GMT) $$ delete from public.help_requests where created_at < now() - interval '7 days'; $$ );