Files
RelaisSMS/doc/lot-0-decisions-techniques.md
T

12 KiB

RelaisSMS - Lot 0 - Decisions techniques

Date : 2026-06-11

Objectif du lot

Ce document fixe les decisions de cadrage avant le demarrage du socle applicatif. Il complete le cahier des charges et sert de reference pour les lots suivants.

Decisions actees

Sujet Decision Impact
Source CardDAV/Nextcloud CardDAV/Nextcloud est le premier systeme d'import/synchronisation distant a implementer. Le lot 3 porte sur CardDavSourceConnector et ne depend pas de Galette.
Source Galette Galette est prepare comme source future, mais le connecteur n'est pas implemente tant que l'instance n'est pas mise a jour. Galette est reporte au dernier lot. Le socle et CardDAV/Nextcloud avancent sans dependance Galette.
Nommage des sources CardDAV/Nextcloud et Galette sont deux sources separees, meme si Galette expose ou exporte un format vCard. Les connecteurs, configurations, cles de source et libelles UI restent distincts. Pas de regroupement sous un meme lot ou nommage.
Version Galette cible Galette 1.2.1 cote projet. La documentation latest consultee affiche 1.2.2. Les endpoints exacts seront revalides apres upgrade, avant implementation du dernier lot Galette.
Fournisseur SMS OVHcloud SMS via API REST OVH Europe. Le connecteur initial depend de l'API OVH, isole derriere SmsProviderInterface.
SDK OVH Ne pas imposer le SDK au lot 0. Preferer un adaptateur HTTP Laravel au demarrage, sauf validation explicite du SDK avec la version PHP cible. Moins de dependance externe et controle clair de la signature API.
Roles Un seul role applicatif au MVP : administrateur complet. Pas de RBAC fin au lot 1. Tous les utilisateurs authentifies ont les memes droits.
Suppression contacts synchronises Suppression logique par deleted_at, pas suppression physique. L'historique SMS reste auditable meme si un contact disparait d'une source.
Suppression contacts locaux Jamais supprimes par synchronisation. Un contact local reste sous controle applicatif.
Refus SMS Flag manuel sms_opt_out au niveau contact. Les contacts opt-out sont exclus au moment de la resolution des destinataires.
Limite d'envoi 100 SMS par envoi par defaut, configurable. Validation cote serveur obligatoire avant creation de campagne.
Conservation historique 3 ans par defaut, configurable. sms_campaigns.expires_at est calcule a la creation.
Programmation Prevue dans le modele, activee par configuration. Le lot 7 pourra utiliser le scheduler sans revoir le modele.

CardDAV/Nextcloud

Etat retenu

CardDAV/Nextcloud est la source distante prioritaire pour l'import/synchronisation. Elle est traitee comme un systeme autonome : son connecteur lit des carnets CardDAV, des vCards, des UID et des ETags, sans reutiliser le contrat Galette.

Contrat cible pour RelaisSMS

Le connecteur CardDAV devra fournir au cache local :

Donnee RelaisSMS Source CardDAV attendue
Identifiant distant UID vCard, complete par l'URL ou l'adresse du carnet si necessaire.
Nom affiche FN vCard.
Nom / prenom Champs structures vCard si presents.
Telephones Proprietes TEL, avec conservation du type si disponible.
Groupes Categories vCard si presentes.
Synchronisation incrementale ETag, ctag ou horodatage distant selon les capacites du serveur.

Decision : nommer cette source carddav ou carddav_nextcloud cote configuration/UI, jamais galette_vcard.

Galette

Etat retenu

Galette est laisse de cote pour l'implementation immediate, conformement au cadrage projet : l'upgrade est planifie mais pas encore effectif. Le lot 0 documente donc le contrat attendu sans figer un endpoint qui pourrait changer au moment de l'upgrade. Le connecteur Galette sera le dernier lot.

Documentation consultee

  • Documentation Galette fournie : https://apidoc.galette.eu/en/latest/functions_m.html
  • La page consultee est une documentation Doxygen de classes PHP, pas une specification REST/OpenAPI.
  • Elements reperes utiles au cadrage :
    • Galette\Controllers\Crud\MembersController::list
    • Galette\Controllers\Crud\MembersController::ajaxList
    • Galette\Controllers\Crud\MembersController::show
    • Galette\Controllers\Crud\MembersController::vcard
    • Galette\Controllers\CsvController::membersExport

Contrat cible pour RelaisSMS

Le connecteur Galette devra fournir au cache local :

Donnee RelaisSMS Source Galette attendue
Identifiant distant ID adherent Galette, par exemple Numéro adhérent dans l'export actuel.
Nom Champ nom.
Prenom Champ prenom.
Structure Personne morale si presente.
Email Courriel.
Telephones Telephone et GSM, avec conservation du numero original.
Groupes/statuts Statut adherent au minimum ; groupes Galette a confirmer apres upgrade.
Date de modification Date de modification si exposee par API/export.

Endpoints a valider apres upgrade

Avant le lot 9, valider sur l'instance Galette 1.2.1 :

Usage Endpoint ou mecanisme attendu Statut
Liste complete des adherents Endpoint HTTP ou export membres base sur membersExport A confirmer
Detail adherent Route detail membre ou endpoint dedie A confirmer
Fiche/export vCard Galette Route vcard si exploitable dans le connecteur Galette Optionnel, sans lien avec CardDAV/Nextcloud
Groupes/statuts Route groupes ou champs presents dans la liste/export A confirmer
Authentification Session, jeton, basic auth ou autre mecanisme Galette A confirmer
Filtrage incremental Date de modification, ETag ou pagination A confirmer

Decision : ne pas coupler RelaisSMS a une route Galette non confirmee. Le connecteur sera concu avec un adaptateur remplacable : API JSON si disponible, export CSV authentifie en solution de repli. Une eventuelle route vCard Galette reste un mecanisme interne au connecteur Galette, pas une source CardDAV.

OVHcloud SMS

Documentation consultee

Endpoints retenus pour le MVP

Base API : https://eu.api.ovh.com/1.0

Usage Methode Endpoint Notes
Lister les services SMS GET /sms Permet de selectionner serviceName.
Lire le compte SMS GET /sms/{serviceName} Retourne notamment statut et credits restants.
Estimer un message POST /sms/estimate Parametres : message, noStopClause, senderType.
Envoyer un job SMS POST /sms/{serviceName}/jobs Parametres principaux : message, receivers, sender, noStopClause, tag.
Lire jobs en attente GET /sms/{serviceName}/jobs Utile pour debug et suivi.
Lire un job GET /sms/{serviceName}/jobs/{id} Suivi fin si necessaire.
Annuler un job DELETE /sms/{serviceName}/jobs/{id} A utiliser seulement tant que l'envoi est stoppable.
Historique sortant GET /sms/{serviceName}/outgoing Filtres disponibles : dates, destinataire, sender, tag, etc.
Detail sortant GET /sms/{serviceName}/outgoing/{id} Permet de recuperer les informations par SMS envoye.
Expediteurs autorises GET /sms/{serviceName}/senders Pour valider la configuration sender.

Les endpoints batch existent aussi (/sms/{serviceName}/batches) et supportent les envois differes via deferred. Decision MVP : demarrer avec /jobs pour l'envoi immediat et gerer la programmation cote RelaisSMS via queue/scheduler. Les batches restent une option a reevaluer au lot 7 si l'on veut deleguer le differe a OVH.

Credentials attendus

Configuration par variables d'environnement :

OVH_ENDPOINT=ovh-eu
OVH_APPLICATION_KEY=
OVH_APPLICATION_SECRET=
OVH_CONSUMER_KEY=
OVH_SMS_SERVICE_NAME=
OVH_SMS_SENDER=
OVH_SMS_NO_STOP_CLAUSE=true

Les secrets ne sont pas stockes en clair en base. L'interface pourra afficher l'etat de configuration sans exposer les valeurs.

Quota et garde-fous

  • Le compte OVH expose creditsLeft via GET /sms/{serviceName}.
  • RelaisSMS applique sa propre limite de 100 SMS par campagne par defaut.
  • Avant envoi, le connecteur doit refuser une campagne si :
    • aucun serviceName n'est configure ;
    • aucun expediteur valide n'est configure quand necessaire ;
    • la liste finale depasse la limite applicative ;
    • OVH retourne des destinataires invalides.

Numeros de telephone

Echantillon Galette

Fichier analyse : doc/tmp/liste_adherents_filtree.csv

  • 179 lignes adherents.
  • 86 numeros presents dans Telephone ou GSM.
  • Exemples fictifs de formats : 06 11 11 11 11, 0622222222, (+33) 6 33 33 33 33, +33 (0)6 44 44 44 44, fixes francais, numeros internationaux.

Regex portable par defaut

La regex par defaut detecte les mobiles francais bruts avant normalisation :

^\s*(?:(?:\(\s*\+33\s*\)|\+33|0033)\s*(?:\(0\)\s*)?|0)\s*[67](?:[\s.-]*\d{2}){4}\s*$

Elle accepte notamment :

  • 06 11 11 11 11
  • 0622222222
  • 07 55 55 55 55
  • (+33) 6 33 33 33 33
  • +33 (0)6 44 44 44 44
  • 0033 6 11 11 11 11

Elle exclut les fixes francais (01, 02, 03, 04, 05, 09) et les numeros mobiles non francais. Le pays par defaut est FR.

Decision importante : cette regex sert a classifier les portables. La normalisation E.164 reste separee et devra etre faite avec giggsey/libphonenumber-for-php au lot 2.

Parametres applicatifs par defaut

Cle Valeur par defaut Source
default_country FR Cadrage projet
mobile_phone_regex Regex ci-dessus Echantillon Galette
max_sms_per_campaign 100 Cahier des charges
history_retention_years 3 Cahier des charges
scheduled_sends_enabled true MVP
active_sms_provider ovh Fournisseur cible
galette_sync_enabled false Upgrade Galette non fait
carddav_sync_enabled false Active a partir du lot 3

Impacts pour les lots suivants

Lot 1

  • Initialiser Laravel sans dependance Galette active.
  • Authentification simple.
  • Tous les utilisateurs authentifies sont administrateurs.
  • Prevoir app_settings ou configuration equivalente pour les parametres non secrets.

Lot 2

  • Stocker raw_number, normalized_number, is_valid, is_mobile.
  • Utiliser la regex configurable pour is_mobile.
  • Ajouter sms_opt_out sur les contacts.
  • Prevoir deleted_at sur contacts synchronises.
  • Prevoir des cles de source distinctes pour local, carddav et galette.

Lot 3

  • Implementer CardDavSourceConnector.
  • Synchroniser les vCards depuis Nextcloud/CardDAV avec UID et ETag si disponibles.
  • Mapper les categories vCard en groupes importes CardDAV.

Lot 5

  • Implementer OvhSmsProvider via client HTTP signe.
  • Journaliser reponse OVH brute et IDs retournes.
  • Utiliser le champ tag OVH pour relier les SMS a une campagne RelaisSMS.

Lot 9

  • Revalider Galette 1.2.1 apres upgrade.
  • Choisir entre API JSON, export CSV authentifie ou route Galette dediee.
  • Mapper les statuts Galette en groupes applicatifs importes.
  • Garder un nommage Galette explicite, separe de CardDAV/Nextcloud.

Points ouverts

Sujet Question A trancher avant
Galette auth Quel mecanisme d'authentification sera disponible apres upgrade ? Lot 9
Galette groupes Les groupes sont-ils exposes directement ou seulement les statuts ? Lot 9
CardDAV categories Les categories Nextcloud sont-elles renseignees et suffisantes comme groupes ? Lot 3
OVH sender Expediteur alphanumerique valide ou numero reponse ? Lot 5
STOP OVH noStopClause=true est-il conforme a l'usage AFPMA non publicitaire ? Lot 5
Numeros internationaux Faut-il envoyer aux mobiles non francais presents dans les sources synchronisees ? Lot 4