PRISME France 2030 · Culture & IA

SPEC — Architecture fédérée (multi-instance, sync, fédération)

Vérifier la maturitéSpecDoc. générale

Périmètre : SPEC_ARCHITECTURE_FEDEREE

Références :

Références :

Références : §3.2

Date : 2026-06-05

Statut : Spécification technique v1

Contexte : L'application doit pouvoir interroger et synchroniser des données provenant de sources multiples : Baserow (base centralisée), instances fédérées (associations partenaires), cache local, services externes (Vespa, etc.). Chaque source a son propre domaine, ses propres règles d'authentification et son propre modèle de données. RAPPORT_ANALYSE_GAPS §3.2 identifie le besoin d'une doc topologie multi-instance, protocole sync, fédération identités.

Conformité au schéma directeur :

§ SchémaSection du document
1. Contexte & Objectif§1
2. Description Fonctionnelle§2
3. Architecture & Références§3
4. Spécifications Techniques Détaillées§4
5. Dépendances & Interactions§5
6. Plan d'Implémentation§6
7. Résultats Attendus§7

1. Contexte & Objectif

1.1 Résumé du besoin

L'application calendrier-agenda doit supporter un modèle multi-instance où plusieurs déploiements indépendants (associations, partenaires) peuvent :

1.2 Objectif métier

ObjectifValeur
DécouplageChaque instance reste autonome ; une panne n'impacte pas les autres
Sync sélectiveLes instances choisissent quels jeux de données partager (événements publics, ressources partagées)
Fédération progressiveAjout d'une nouvelle instance sans arrêt ni migration
PerformanceLes requêtes cross-instance sont parallélisées avec agrégation côté gateway
SécuritéChaque instance contrôle ses propres règles d'accès ; les tokens sont échangés via OAuth2

1.3 Périmètre

InclusExclu
Topologie multi-instance (hub-and-spoke)Migration des données existantes vers le modèle fédéré
Découverte dynamique d'instances via registre BaserowSynchronisation en temps réel (WebSocket cross-instance)
API Gateway avec routage, agrégation, cache, circuit breakerRéplication complète de toutes les tables
Fédération des identités via OIDC / OAuth2 client-credentialsInterface d'administration de la fédération
Schéma canonique des événements partagésSynchronisation bidirectionnelle temps réel
Cache local (IndexedDB) + TTLOutil de monitoring de l'état des fédérations
Résolution de conflits (priorité source)

2. Description Fonctionnelle

2.1 Topologie hub-and-spoke

                    ┌──────────────────┐
                    │ Hub central │
                    │ (Baserow + Auth) │
                    └────────┬─────────┘
                             │ HTTPS
              ┌──────────────┼──────────────┐
              │ │ │
     ┌────────▼───┐ ┌──────▼──────┐ ┌───▼────────┐
     │ Instance A │ │ Instance B │ │ Instance C │
     │ (Assoc. 1) │ │ (Assoc. 2) │ │ (Assoc. 3) │
     │ Baserow+Qwik│ │ Baserow+Qwik │ │ Baserow+Qwik│
     └─────────────┘ └─────────────┘ └────────────┘

Le Hub central héberge :

Chaque instance spoke :

2.2 Découverte dynamique

Les instances s'enregistrent via une API REST :

POST /api/federation/register
Content-Type: application/json
Authorization: Bearer <hub-token>

{
  "instanceId": "assoc-1",
  "name": "Association culturelle A",
  "baseUrl": "https://agenda.assoc-a.fr",
  "apiVersion": "1.0",
  "publicKey": "-----BEGIN PUBLIC KEY-----...",
  "capabilities": ["events:read", "resources:read", "contacts:read"],
  "status": "active"
}

Le registre central est stocké dans une table Baserow instances_federees avec les champs :

2.3 Synchronisation des données

Mode Pull (Hub vers Spoke) : Le Hub interroge périodiquement chaque instance pour récupérer les événements publics modifiés depuis la dernière sync.

Mode Push (Spoke vers Hub) : L'instance notifie le Hub via webhook quand des données partagées sont modifiées.

GET /api/federation/events?since=2026-01-01T00:00:00Z
Response:
{
  "events": [
    {
      "id": "evt-assoc-a-123",
      "title": "Concert de printemps",
      "start": "2026-04-15T20:00:00Z",
      "end": "2026-04-15T23:00:00Z",
      "location": "Salle des fetes",
      "source": "assoc-a",
      "checksum": "sha256-abc123"
    }
  ],
  "nextSince": "2026-01-02T00:00:00Z"
}

2.4 Regles metier

  1. Souverainete : chaque instance reste proprietaire de ses donnees ; le Hub n'a qu'une copie cache
  2. Opt-in : le partage est active table par table, instance par instance
  3. Checksum : chaque evenement partage a un checksum SHA-256 pour detecter les conflits
  4. Horodatage : chaque modification porte un updatedAt pour tri et resolution de conflits
  5. TTL cache : les donnees agregees expirent apres 5 minutes (configurable par table)
  6. Heartbeat : chaque instance envoie un signal de vie toutes les 60 secondes ; apres 3 missed heartbeats -> statut inactive
  7. Retention : les evenements passes (date de fin < J-30) ne sont pas synchronises
  8. Rate limiting : max 100 requetes/minute par instance spoke

3. Architecture & References

3.1 Schema d'architecture

                    +--------------------------------------+
| API Gateway |
| (Edge Worker / Qwik Route) |
| +----------+ +------------------+ |
| Router | | Federation Proxy | |
| +----+-----+ +--------+---------+ |
| +----v------------------v---------+ |
| Service Registry (cache) | |
| +---------------------------------+ |
                    +----------+---------------------------+
          +--------------------+--------------------+
   +------v------+ +-------v-------+ +-------v-------+
| Baserow | | Instance A | | Instance B |
| (REST API) | | (REST API) | | (REST API) |
| token API | | OAuth2 CC | | OAuth2 CC |
   +--------------+ +---------------+ +---------------+

3.2 Flux d'une requete cross-instance

1. Client Qwik -> GET /api/events?federation=true
2. Gateway recoit la requete
3. Gateway verifie le JWT client (Authentik OIDC)
4. Gateway consulte le registre des instances actives (cache 60s)
5. Gateway calcule les endpoints a interroger :
   - Baserow local : GET /api/baserow/database/rows/table/548/
   - Instance A : GET https://agenda.assoc-a.fr/api/federation/events
   - Instance B : GET https://agenda.assoc-b.fr/api/federation/events
6. Gateway parallelise les appels (Promise.allSettled)
7. Gateway normalise chaque reponse dans le schema canonique

---

*Synthèse PRISME — 383 lignes dans la source complète.*

**Voir aussi PRISME :** IA fédérée Marty · Protocole PRISME-Mesh
  1. Client Qwik -> GET /api/events?federation=true
  2. Gateway recoit la requete
  3. Gateway verifie le JWT client (Authentik OIDC)
  4. Gateway consulte le registre des instances actives (cache 60s)
  5. Gateway calcule les endpoints a interroger :
  1. Gateway parallelise les appels (Promise.allSettled)
  2. Gateway normalise chaque reponse dans le schema canonique

Synthèse PRISME — 383 lignes dans la source complète.

Voir aussi PRISME : IA fédérée Marty · Protocole PRISME-Mesh