Aller au contenu principal

Système d'import automatique de publications

Objectif

Récupérer automatiquement les publications (actualités, événements) depuis les sites web des mairies et les insérer dans la base DMV.

Architecture

ImportSource (config en DB)
└── ImportConnectorInterface (parsing HTML/RSS)
└── ImportRunnerService (orchestration, déduplication, insertion)
└── publications (table Supabase)

Connecteurs disponibles

parser_keyDescription
bessan_frAgenda/événements de bessan.fr (endpoint AJAX agenda)
bessan_fr_actuActualités de bessan.fr (endpoint AJAX actualités)

Modèle ImportSource

Chaque source est une ligne dans la table import_sources.

ChampTypeDescription
keystringIdentifiant court unique (ex : bessan_fr_actu)
parser_keystringConnecteur PHP à utiliser
commune_iduuidCommune cible
acteur_iduuidActeur associé aux publications créées
type_iduuidType de publication (actualité, événement…)
scopestringlocal / public
auto_publishboolAuto-publication si toutes les conditions sont remplies
require_imageboolPublication refusée si pas d'image valide
require_dateboolPublication refusée si pas de date_debut
schedule_cronstringExpression cron (ex : 0 6 * * *)

Logique de modération à l'import

ImportRunnerService::resolveModeration() retourne 'published' ou 'pending' selon les conditions suivantes. Toutes doivent être vraies pour auto-publier :

  1. auto_publish = true
  2. source_url présente dans l'item parsé
  3. acteur_id configuré sur la source
  4. type_id configuré sur la source
  5. Si require_image = true : image HTTP valide dans l'item
  6. Si require_date = true : date_debut présente dans l'item

Si moderation_status = 'pending' :

  • valide = false
  • publie_le = nullpublication invisible sur tous les fronts
attention

Les actualités mairie n'ont pas de date_debut. Si require_date = true sur la source, toutes les actualités seront créées en pending et resteront invisibles tant qu'elles ne sont pas validées manuellement dans le backoffice.

Déduplication

Stratégie configurée par dedupe_strategy sur la source. Le runner compare source_url des items entrants avec les publications existantes pour éviter les doublons à l'import.

Si deux imports successifs ont lieu (ex. import manuel + cron), des doublons de contenu peuvent apparaître en base avec des id différents. Le frontend DMV Public applique une déduplication de présentation par clé titre normalisé | date (voir section Frontend).

Endpoints admin

MéthodeRouteDescription
GET/api/v1/admin/import-sourcesListe toutes les sources
POST/api/v1/admin/import-sourcesCréer une source
GET/api/v1/admin/import-sources/{id}Lire une source
PATCH/api/v1/admin/import-sources/{id}Modifier une source
DELETE/api/v1/admin/import-sources/{id}Supprimer une source
POST/api/v1/admin/import-sources/{id}/runImport manuel (?dry_run=true pour test)
GET/api/v1/admin/import-sources/{id}/runsHistorique des runs
GET/api/v1/admin/import-sources/{id}/logs/{date}Log d'un run (YYYY-MM-DD)

Tous ces endpoints nécessitent identify.app + auth:sanctum + ensure.admin.

Le listing GET /api/v1/admin/import-sources renvoie en plus :

  • type_nom : libellé du type de publication lié
  • acteur_nom : libellé de l'acteur lié

Format d'un run log

2026-06-22 18:27:00 [INFO] === Import bessan_fr_actu → DMV ===
2026-06-22 18:27:00 [INFO] Source : Actualités Bessan (id=xxx)
2026-06-22 18:27:00 [INFO] auto_publish=true, require_image=false, require_date=false
2026-06-22 18:27:01 [INFO] 35 actualité(s) trouvée(s) sur la source.
2026-06-22 18:27:05 [INFO] [CRÉÉ] UN NOUVEAU SITE INTERNET — status=published
2026-06-22 18:27:05 [INFO] [SKIP] RÉSULTATS DES ÉLECTIONS — déjà en base
2026-06-22 18:27:06 [INFO] === Fin : 12 créé(s) | 23 skip(s) | 0 erreur(s) — success ===

Points de vigilance

  • acteur_id obligatoire pour l'auto-publication. S'il est absent, toutes les publications tombent en pending.
  • publie_le est fixé à now() seulement à la création si moderation_status = 'published'. Une validation manuelle ultérieure dans le backoffice le fixe également depuis le 2026-06-26.
  • Si une publication existe déjà pour la même source_url, le runner peut compléter image_url lorsqu'elle manque et réaligner type_id sur la configuration courante de la source.
  • Les imports multiples sur la même source peuvent créer des doublons si la déduplication par source_url ne fonctionne pas (URL absente ou modifiée).