Aggiunge un keepalive giornaliero per evitare la pausa Supabase free tier

Il progetto Supabase free va in pausa dopo 7 giorni senza richieste API.
Un Vercel Cron Job chiama /api/public/keepalive una volta al giorno, che
fa una lettura minima per tenere il progetto attivo senza servizi esterni.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5 committed 2026-09-27 14:43:28 +02:00
1 parent 342b457ee7
commit 20ca6ba5a6
3 files changed
+54

No files matched your search

+21
View File
@@ -23,6 +23,7 @@ import { Route as PartitaCsiIdRouteImport } from './routes/partita-csi.$id'
import { Route as PartitaIdRouteImport } from './routes/partita.$id' import { Route as PartitaIdRouteImport } from './routes/partita.$id'
import { Route as ApiPublicApriSondaggioRouteImport } from './routes/api/public/apri-sondaggio' import { Route as ApiPublicApriSondaggioRouteImport } from './routes/api/public/apri-sondaggio'
import { Route as ApiPublicCsiRouteImport } from './routes/api/public/csi' import { Route as ApiPublicCsiRouteImport } from './routes/api/public/csi'
import { Route as ApiPublicKeepaliveRouteImport } from './routes/api/public/keepalive'
import { Route as ApiPublicNotificaPersonalizzataRouteImport } from './routes/api/public/notifica-personalizzata' import { Route as ApiPublicNotificaPersonalizzataRouteImport } from './routes/api/public/notifica-personalizzata'
import { Route as ApiPublicNotificheAttiveRouteImport } from './routes/api/public/notifiche-attive' import { Route as ApiPublicNotificheAttiveRouteImport } from './routes/api/public/notifiche-attive'
import { Route as ApiPublicPromemoriaPalloniRouteImport } from './routes/api/public/promemoria-palloni' import { Route as ApiPublicPromemoriaPalloniRouteImport } from './routes/api/public/promemoria-palloni'
@@ -101,6 +102,11 @@ const ApiPublicCsiRoute = ApiPublicCsiRouteImport.update({
path: '/api/public/csi', path: '/api/public/csi',
getParentRoute: () => rootRouteImport, getParentRoute: () => rootRouteImport,
} as any) } as any)
const ApiPublicKeepaliveRoute = ApiPublicKeepaliveRouteImport.update({
id: '/api/public/keepalive',
path: '/api/public/keepalive',
getParentRoute: () => rootRouteImport,
} as any)
const ApiPublicNotificaPersonalizzataRoute = const ApiPublicNotificaPersonalizzataRoute =
ApiPublicNotificaPersonalizzataRouteImport.update({ ApiPublicNotificaPersonalizzataRouteImport.update({
id: '/api/public/notifica-personalizzata', id: '/api/public/notifica-personalizzata',
@@ -156,6 +162,7 @@ export interface FileRoutesByFullPath {
'/partita/$id': typeof PartitaIdRoute '/partita/$id': typeof PartitaIdRoute
'/api/public/apri-sondaggio': typeof ApiPublicApriSondaggioRoute '/api/public/apri-sondaggio': typeof ApiPublicApriSondaggioRoute
'/api/public/csi': typeof ApiPublicCsiRoute '/api/public/csi': typeof ApiPublicCsiRoute
'/api/public/keepalive': typeof ApiPublicKeepaliveRoute
'/api/public/notifica-personalizzata': typeof ApiPublicNotificaPersonalizzataRoute '/api/public/notifica-personalizzata': typeof ApiPublicNotificaPersonalizzataRoute
'/api/public/notifiche-attive': typeof ApiPublicNotificheAttiveRoute '/api/public/notifiche-attive': typeof ApiPublicNotificheAttiveRoute
'/api/public/promemoria-palloni': typeof ApiPublicPromemoriaPalloniRoute '/api/public/promemoria-palloni': typeof ApiPublicPromemoriaPalloniRoute
@@ -179,6 +186,7 @@ export interface FileRoutesByTo {
'/partita/$id': typeof PartitaIdRoute '/partita/$id': typeof PartitaIdRoute
'/api/public/apri-sondaggio': typeof ApiPublicApriSondaggioRoute '/api/public/apri-sondaggio': typeof ApiPublicApriSondaggioRoute
'/api/public/csi': typeof ApiPublicCsiRoute '/api/public/csi': typeof ApiPublicCsiRoute
'/api/public/keepalive': typeof ApiPublicKeepaliveRoute
'/api/public/notifica-personalizzata': typeof ApiPublicNotificaPersonalizzataRoute '/api/public/notifica-personalizzata': typeof ApiPublicNotificaPersonalizzataRoute
'/api/public/notifiche-attive': typeof ApiPublicNotificheAttiveRoute '/api/public/notifiche-attive': typeof ApiPublicNotificheAttiveRoute
'/api/public/promemoria-palloni': typeof ApiPublicPromemoriaPalloniRoute '/api/public/promemoria-palloni': typeof ApiPublicPromemoriaPalloniRoute
@@ -203,6 +211,7 @@ export interface FileRoutesById {
'/partita/$id': typeof PartitaIdRoute '/partita/$id': typeof PartitaIdRoute
'/api/public/apri-sondaggio': typeof ApiPublicApriSondaggioRoute '/api/public/apri-sondaggio': typeof ApiPublicApriSondaggioRoute
'/api/public/csi': typeof ApiPublicCsiRoute '/api/public/csi': typeof ApiPublicCsiRoute
'/api/public/keepalive': typeof ApiPublicKeepaliveRoute
'/api/public/notifica-personalizzata': typeof ApiPublicNotificaPersonalizzataRoute '/api/public/notifica-personalizzata': typeof ApiPublicNotificaPersonalizzataRoute
'/api/public/notifiche-attive': typeof ApiPublicNotificheAttiveRoute '/api/public/notifiche-attive': typeof ApiPublicNotificheAttiveRoute
'/api/public/promemoria-palloni': typeof ApiPublicPromemoriaPalloniRoute '/api/public/promemoria-palloni': typeof ApiPublicPromemoriaPalloniRoute
@@ -228,6 +237,7 @@ export interface FileRouteTypes {
| '/partita/$id' | '/partita/$id'
| '/api/public/apri-sondaggio' | '/api/public/apri-sondaggio'
| '/api/public/csi' | '/api/public/csi'
| '/api/public/keepalive'
| '/api/public/notifica-personalizzata' | '/api/public/notifica-personalizzata'
| '/api/public/notifiche-attive' | '/api/public/notifiche-attive'
| '/api/public/promemoria-palloni' | '/api/public/promemoria-palloni'
@@ -251,6 +261,7 @@ export interface FileRouteTypes {
| '/partita/$id' | '/partita/$id'
| '/api/public/apri-sondaggio' | '/api/public/apri-sondaggio'
| '/api/public/csi' | '/api/public/csi'
| '/api/public/keepalive'
| '/api/public/notifica-personalizzata' | '/api/public/notifica-personalizzata'
| '/api/public/notifiche-attive' | '/api/public/notifiche-attive'
| '/api/public/promemoria-palloni' | '/api/public/promemoria-palloni'
@@ -274,6 +285,7 @@ export interface FileRouteTypes {
| '/partita/$id' | '/partita/$id'
| '/api/public/apri-sondaggio' | '/api/public/apri-sondaggio'
| '/api/public/csi' | '/api/public/csi'
| '/api/public/keepalive'
| '/api/public/notifica-personalizzata' | '/api/public/notifica-personalizzata'
| '/api/public/notifiche-attive' | '/api/public/notifiche-attive'
| '/api/public/promemoria-palloni' | '/api/public/promemoria-palloni'
@@ -298,6 +310,7 @@ export interface RootRouteChildren {
PartitaIdRoute: typeof PartitaIdRoute PartitaIdRoute: typeof PartitaIdRoute
ApiPublicApriSondaggioRoute: typeof ApiPublicApriSondaggioRoute ApiPublicApriSondaggioRoute: typeof ApiPublicApriSondaggioRoute
ApiPublicCsiRoute: typeof ApiPublicCsiRoute ApiPublicCsiRoute: typeof ApiPublicCsiRoute
ApiPublicKeepaliveRoute: typeof ApiPublicKeepaliveRoute
ApiPublicNotificaPersonalizzataRoute: typeof ApiPublicNotificaPersonalizzataRoute ApiPublicNotificaPersonalizzataRoute: typeof ApiPublicNotificaPersonalizzataRoute
ApiPublicNotificheAttiveRoute: typeof ApiPublicNotificheAttiveRoute ApiPublicNotificheAttiveRoute: typeof ApiPublicNotificheAttiveRoute
ApiPublicPromemoriaPalloniRoute: typeof ApiPublicPromemoriaPalloniRoute ApiPublicPromemoriaPalloniRoute: typeof ApiPublicPromemoriaPalloniRoute
@@ -407,6 +420,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ApiPublicCsiRouteImport preLoaderRoute: typeof ApiPublicCsiRouteImport
parentRoute: typeof rootRouteImport parentRoute: typeof rootRouteImport
} }
'/api/public/keepalive': {
id: '/api/public/keepalive'
path: '/api/public/keepalive'
fullPath: '/api/public/keepalive'
preLoaderRoute: typeof ApiPublicKeepaliveRouteImport
parentRoute: typeof rootRouteImport
}
'/api/public/notifica-personalizzata': { '/api/public/notifica-personalizzata': {
id: '/api/public/notifica-personalizzata' id: '/api/public/notifica-personalizzata'
path: '/api/public/notifica-personalizzata' path: '/api/public/notifica-personalizzata'
@@ -474,6 +494,7 @@ const rootRouteChildren: RootRouteChildren = {
PartitaIdRoute: PartitaIdRoute, PartitaIdRoute: PartitaIdRoute,
ApiPublicApriSondaggioRoute: ApiPublicApriSondaggioRoute, ApiPublicApriSondaggioRoute: ApiPublicApriSondaggioRoute,
ApiPublicCsiRoute: ApiPublicCsiRoute, ApiPublicCsiRoute: ApiPublicCsiRoute,
ApiPublicKeepaliveRoute: ApiPublicKeepaliveRoute,
ApiPublicNotificaPersonalizzataRoute: ApiPublicNotificaPersonalizzataRoute, ApiPublicNotificaPersonalizzataRoute: ApiPublicNotificaPersonalizzataRoute,
ApiPublicNotificheAttiveRoute: ApiPublicNotificheAttiveRoute, ApiPublicNotificheAttiveRoute: ApiPublicNotificheAttiveRoute,
ApiPublicPromemoriaPalloniRoute: ApiPublicPromemoriaPalloniRoute, ApiPublicPromemoriaPalloniRoute: ApiPublicPromemoriaPalloniRoute,
+25
View File
@@ -0,0 +1,25 @@
import { createFileRoute } from "@tanstack/react-router";
/**
* Chiamata dal Vercel Cron Job (vedi vercel.json) per tenere attivo il progetto Supabase
* free tier, che va in pausa dopo 7 giorni senza richieste API. Una lettura minima basta:
* nessun dato sensibile, nessun effetto collaterale, quindi nessuna autenticazione richiesta.
*/
export const Route = createFileRoute("/api/public/keepalive")({
server: {
handlers: {
GET: async () => {
const { supabaseAdmin } = await import("@/integrations/supabase/client.server");
const { error } = await supabaseAdmin
.from("giocatori_squadra")
.select("id", { count: "exact", head: true })
.limit(1);
if (error) {
console.error("keepalive", error);
return new Response("Errore", { status: 500 });
}
return new Response("ok");
},
},
},
});
+8
View File
@@ -0,0 +1,8 @@
{
"crons": [
{
"path": "/api/public/keepalive",
"schedule": "0 5 * * *"
}
]
}