Supabase - FactoriaF5-Asturias/project-p5-digital-academy-team3-restaurant-backend GitHub Wiki
Índice Supabase
Qué hace
El enunciado pide que el sistema genere de forma automática un resumen de ventas en PDF y lo guarde en un almacenamiento de objetos en la nube. Usamos Supabase Storage.
Cada noche, a las 00:05 (hora de Madrid), el backend genera el PDF de ventas del día anterior y lo sube al bucket sales-reports como:
daily/sales-report-AAAA-MM-DD.pdf
Es el mismo PDF que se descarga desde GET /api/v1/invoices/report/pdf, con las facturas del día y los totales.
Cómo funciona
| Clase | Paquete | Qué hace |
|---|---|---|
SupabaseStorageProperties |
storage |
Lee supabase.url, supabase.service-key y supabase.reports-bucket. La clave no sale nunca en el toString() |
SupabaseStorageClient |
storage |
Sube un fichero con un POST a {SUPABASE_URL}/storage/v1/object/{bucket}/{ruta} usando RestClient. Si el fichero ya existe lo sobrescribe (x-upsert). Timeouts: 5 s para conectar, 30 s para la respuesta |
SalesReportArchiveJob |
invoices.service |
Tarea @Scheduled: genera el PDF con SalesReportPdfService y lo sube. Si algo falla, lo escribe en el log y la app sigue funcionando |
SalesReportArchiveConfig |
config |
Crea las dos clases anteriores y activa @EnableScheduling, solo si SUPABASE_URL tiene valor |
No usamos la librería ni la CLI de Supabase: el backend habla con la API REST de Storage por HTTP.
Gracias a la condición de SalesReportArchiveConfig, quien no tenga las variables de Supabase arranca el backend y pasa los tests igual que siempre. La tarea simplemente no existe.
Configuración
1. Variables en el .env
SUPABASE_URL=https://humjxfnaqjxirkknngvf.supabase.co
SUPABASE_SERVICE_KEY=sb_secret_...
Opcionales:
| Variable | Por defecto | Para qué |
|---|---|---|
SUPABASE_REPORTS_BUCKET |
sales-reports |
Cambiar el bucket |
SALES_REPORT_ARCHIVE_CRON |
0 5 0 * * * |
Cambiar la hora (cron de Spring: segundos, minutos, horas, día, mes, día de la semana) |
IMPORTANTE: si rellenas SUPABASE_URL pero dejas vacía SUPABASE_SERVICE_KEY, el backend no arranca. Rellena las dos o ninguna.
En Docker (docker compose --profile app up) estas variables se pasan solas desde el .env. Ver Docker.
2. El bucket
sales-reports, privado y limitado a application/pdf. Ya está creado en el proyecto. Si hubiera que recrearlo: Storage → New bucket, nombre sales-reports, con Public bucket desactivado.
El bucket images (público) es otro, el de las imágenes de producto.
Comprobar que funciona
Al arrancar el backend con las variables puestas no se ve nada especial: la tarea espera a las 00:05.
Subirlo a mano (lo más rápido, y lo que usamos en la demo)
curl -X POST "http://localhost:8080/api/v1/invoices/report/archive?date=2026-10-05"
Sin date sube el de ayer. Respuesta:
{"date":"2026-10-05","path":"daily/sales-report-2026-10-05.pdf"}
| Código | Significa |
|---|---|
| 200 | Subido. Aparece en Storage → sales-reports → daily |
| 400 | La fecha no tiene el formato AAAA-MM-DD |
| 502 | Supabase ha rechazado la subida (clave mala, bucket inexistente...) |
| 503 | Faltan SUPABASE_URL o SUPABASE_SERVICE_KEY en el .env |
Solo está abierto con el perfil dev. Con la seguridad de roles será solo para ADMIN.
Probar la tarea programada
Para ver la tarea nocturna funcionando sin esperar, añade temporalmente esta línea al .env y arranca el backend como siempre (VS Code o Docker):
SALES_REPORT_ARCHIVE_CRON=*/15 * * * * *
En el log debe salir:
SalesReportArchiveJob : Resumen de ventas del 2026-10-01 subido a daily/sales-report-2026-10-01.pdf
Y en el panel de Supabase, Storage → sales-reports → daily, aparece el PDF. Después borra esa línea del .env y vuelve a arrancar para dejarlo a las 00:05.
Si falla, en el log sale No se pudo archivar el resumen de ventas del ... con el error debajo.
Limitaciones
- Solo se sube si el backend está encendido a las 00:05. En local, con el ordenador apagado esa noche, ese día no se sube.
- No hay reintentos. Si falla una noche, queda en el log y ese día no se sube solo.
- Si un día no hay ventas, el PDF se sube igual, con el texto "Sin ventas en el periodo".
- El contenedor de Docker usa
TZ=Europe/Madridpara que el "día anterior" sea el de España. Si arrancas el backend fuera de Docker, usa la zona horaria de tu ordenador.