feat: ingestion automatique toutes les 6h + indicateur fraîcheur UI

- Symfony Scheduler (MainSchedule) : cron 0,6,12,18h UTC
- IngestionScheduleMessage + IngestionScheduleHandler : pipeline complet
  ingestion → forecasts → impact scores pour toutes les zones Antilles
- messenger.yaml : transport scheduler_main + async Redis (rs971_async)
- entrypoint.sh : 2 workers en background (scheduler_main + async)
- GET /api/status : date/heure de la dernière observation
- SargassesMap : badge "Données du JJ/MM à HH:MM" en bas à gauche

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gwadaking
2026-04-03 22:31:58 -04:00
parent 55caca001c
commit 48e6e5060c
9 changed files with 223 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Controller;
use Doctrine\DBAL\Connection;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
/**
* GET /api/status — fraîcheur des données pour l'indicateur UI
*/
#[Route('/api/status', name: 'api_status', methods: ['GET'])]
class StatusController extends AbstractController
{
public function __construct(private Connection $connection) {}
public function __invoke(): JsonResponse
{
$row = $this->connection->fetchAssociative(
'SELECT detected_at, source, coverage_area
FROM sargassum_observation
ORDER BY detected_at DESC LIMIT 1'
);
return $this->json([
'lastObservation' => $row !== false ? [
'detectedAt' => $row['detected_at'],
'source' => $row['source'],
'coverageKm2' => $row['coverage_area'] !== null ? (float) $row['coverage_area'] : null,
] : null,
]);
}
}