S
SOLEENIA
SPEC v0.9 · FR

Spec technique — Soleenia

Plateforme d'opérateurs IA modulaires avec mémoire partagée. Document de référence pour l'équipe produit & ingénierie.

1 · Vision produit & modèle mental 2 · Architecture système 3 · Modèles de données 4 · API & contrats 5 · Machines à états 6 · Séquences clés 7 · Système de crédits 8 · Parrainage & commissions 8bis · Quêtes, récompenses & événements 9 · Sécurité, vie privée, IA responsable 10 · Critères d'acceptation MVP 11 · Canaux de communication 12 · Authentification & session 13 · Admin, observabilité, incidents 14 · [v2] Multi-tenant & Realms 15 · [v2] Facturation, markups & rev-share 16 · [v2] Data intelligence cross-realms 17 · [v2] Opérateurs privés & garde-fous MLM

1 · Vision produit & modèle mental

Métaphore : le téléphone. Chaque opérateur est un contact dans ton répertoire — tu l'appelles, tu raccroches, tu passes au suivant. Chaque conversation est isolée (comme un appel), mais l'utilisateur a un seul profil partagé (l'annuaire, les produits, les contacts, les préférences).

Principes directeurs

Persona principal

Marie, 38 ans, entrepreneure solo. A 2 enfants, un chien (Milo), vend des soins peau en ligne. Veut de l'aide intelligente sans gérer 12 apps. Paie 40-60 $/mois si la valeur est claire.

2 · Architecture système

// Vue haut niveau
[Mobile/Desktop client]
        │ HTTPS/WSS
        ▼
[API Gateway] ── [Auth/Identity]
        │
        ├──▶ [Orchestrator] ◀─▶ [Memory Service]
        │         │                   ├─ User profile (shared)
        │         │                   ├─ Operator context (isolated)
        │         │                   └─ Vector store (pgvector)
        │         │
        │         ├──▶ [Operator Runner] ◀─▶ LLM provider
        │         ├──▶ [Tool Executor]    ◀─▶ Integrations (email, calendar…)
        │         └──▶ [Guardrail Service]
        │
        ├──▶ [Billing & Ledger] ◀─▶ Stripe
        ├──▶ [Referral Service]
        └──▶ [Notification Hub] (push, email, SMS, in-app)

Décisions techniques clés

3 · Modèles de données

User & profil partagé

User {
  id, email, phone, locale ('fr'|'en'), timezone,
  quiet_hours_start, quiet_hours_end,
  preferred_channel ('in_app'|'email'|'sms'),
  credit_balance (integer, ✦),
  tier, created_at, deleted_at
}

UserProfile { // shared across all operators
  user_id,
  display_name, avatar_url,
  active_goals []{ id, text, target, progress },
  contacts []{ name, email, stage, channels, tags },
  products []{ name, price, sku, notes },
  documents []{ name, storage_url, tags, encrypted }
}

Opérateurs & instances

Operator { // catalogue — géré par admin
  id, slug, name_i18n, description_i18n,
  tier ('simple'|'standard'|'advanced'),
  monthly_price_cents,
  icon, color, gradient,
  system_prompt_i18n, greeting_i18n,
  tools [] (list of allowed tool IDs),
  credit_cost_per_1k_tokens,
  guardrails [],
  published_at, version
}

UserOperator { // activation d'un opérateur pour un user
  user_id, operator_id,
  status ('active'|'paused'|'trial'),
  activated_at, paused_at,
  custom_settings {}
}

OperatorSession { // un fil de conversation avec un opérateur
  id, user_id, operator_id,
  started_at, ended_at,
  message_count, credit_used,
  summary (résumé auto à la fermeture)
}

Message {
  id, session_id, role ('user'|'assistant'|'tool'),
  content, tokens_in, tokens_out,
  tool_calls [], redacted_at, created_at
}

Crédits & facturation

CreditTransaction {
  id, user_id,
  kind ('topup'|'monthly_include'|'usage'|'refund'|'gift'),
  amount (signed integer, ✦),
  balance_after,
  ref_type, ref_id, // session_id, stripe_charge_id, etc.
  created_at
}

Subscription {
  user_id, operator_id,
  stripe_subscription_id, status,
  current_period_start, current_period_end, canceled_at
}

Parrainage & badges

Referral {
  referrer_id, referee_id, code, depth (1|2|3),
  created_at, first_paid_at, churned_at
}

Commission {
  referrer_id, source_subscription_id, depth,
  amount_cents, period_month, paid_at
}

Badge { id, slug, name_i18n, rule, reward }
UserBadge { user_id, badge_id, progress, unlocked_at, reward_granted_at }

4 · API & contrats

REST — utilisateur

MéthodeRouteDescription
GET/api/v1/meProfil + opérateurs actifs + solde
GET/api/v1/operatorsCatalogue (filtrable par tier, locale)
POST/api/v1/user_operatorsActiver un opérateur — {operator_id}
DELETE/api/v1/user_operators/:idMettre en pause / désactiver
POST/api/v1/sessionsOuvrir une conversation — {operator_id}
POST/api/v1/sessions/:id/messagesEnvoyer un message (stream SSE)
PATCH/api/v1/sessions/:id/hangupRaccrocher — déclenche résumé async
GET/api/v1/inboxActions IA récentes (tous opérateurs)
POST/api/v1/credits/topup{pack_id} — retourne URL Stripe

WebSocket — chat live

Canal user:<id>. Events :

5 · Machines à états

Session opérateur

idle ──open──▶ active
active ──message──▶ active
active ──tool_call──▶ running_tool ──done──▶ active
active ──hangup──▶ closing ──summary_done──▶ closed
active ──timeout(30min)──▶ closing
closed is terminal. Une nouvelle session est créée pour continuer.

Opérateur (par user)

trial (14j) ──pay──▶ active
trial ──expire──▶ paused
active ──user_pause──▶ paused
active ──payment_fail──▶ past_due ──retry──▶ active | canceled
paused ──reactivate──▶ active
canceled is terminal (mémoire gelée, purgée après 90j).

Filleul

signup ──first_payment──▶ qualified (commissions démarrent)
qualified ──cancel_within_14d──▶ clawback (commission remboursée)
qualified ──churn──▶ ended (commissions stoppent)

6 · Séquences clés

Envoi d'un message (happy path)

Client ──POST /sessions/:id/messages──▶ Gateway Gateway ──authorize──▶ Orchestrator Orchestrator ──check_balance──▶ Ledger [✓ sufficient] Orchestrator ──fetch_context──▶ Memory [operator-scoped + shared profile] Orchestrator ──guardrail_in──▶ Guardrails [✓ pass] Orchestrator ──invoke──▶ OperatorRunner OperatorRunner ──stream──▶ LLM LLM ──tokens──▶ Client (via SSE) OperatorRunner ──guardrail_out──▶ Guardrails OperatorRunner ──write──▶ Memory (operator scope) OperatorRunner ──debit──▶ Ledger (tokens × rate) Orchestrator ──balance.changed──▶ Client

Activation opérateur & facturation

Client ──POST /user_operators──▶ API API ──create (trial)──▶ UserOperator API ──create_subscription──▶ Stripe (trial_period: 14d) Stripe ──webhook: invoice.paid──▶ API API ──mark active──▶ UserOperator API ──trigger commissions──▶ ReferralService API ──grant monthly credits──▶ Ledger (+2000 ✦)

7 · Système de crédits

Les crédits (✦) financent les actions coûteuses : tokens LLM, appels API externes, envois SMS, génération d'images.

Pricing

PackCréditsPrixCoût unitaire
Mini500 ✦4.99 $1.00 ¢/✦
Classique2 000 ✦14.99 $0.75 ¢/✦
Gros5 000 ✦29.99 $0.60 ¢/✦
Power15 000 ✦79.99 $0.53 ¢/✦

Consommation indicative

Règle anti-dérive

Hard cap par user configurable (défaut : 500 $/mois). Soft warning à 80% du cap via inbox. Auto top-up opt-in avec seuil personnalisable.

8 · Parrainage & commissions

Mécanique

Niveau% commissionCondition
L1 (direct)20%Filleul avec ≥1 abonnement payant actif
L27%Même condition, niveau -2
L33%Même condition, niveau -3

Période de grâce : 14 jours. Commissions réversibles si le filleul annule dans cette fenêtre.

Versement : mensuel, le 5 du mois suivant, après vérification churn.

Badges associés

8bis · Quêtes, récompenses & événements

Système de gamification dynamique entièrement piloté par l'admin. Les quêtes ne sont pas codées en dur : les admins les programment à l'avance via le back office, avec un calendrier d'événements saisonniers (Noël, Fête des Mères, lancement produit, etc.).

Taxonomie

Modèle de données

Quest {
  id, slug, title_i18n, description_i18n, icon,
  type (daily | weekly | monthly | event),
  target_count // ex: 3 conversations, 5 jours actifs,
  target_verb // chat_started | operator_activated | day_logged_in | referral_joined | business_plan_step,
  target_filter // { operator_id?, category?, min_duration? },
  reward_credits, reward_badge_id?, reward_operator_trial_id?,
  start_at, end_at,
  audience // all | premium | new_under_7d | inactive_30d | active_referrers | custom_segment_id,
  status (draft | scheduled | live | paused | ended),
  push_on_activation (bool), push_on_completion (bool),
  created_by (admin_id), created_at, updated_at
}

UserQuest {
  user_id, quest_id, progress (int), target_count,
  started_at, completed_at?, reward_granted_at?,
  state (available | active | completed | expired | claimed)
}

QuestEvent { user_id, quest_id, verb, payload, ts }
// Append-only log — source de vérité pour le calcul de progrès

Pipeline d'activation

// Cron horaire — QuestScheduler
every hour:
  for quest in quests where status == 'scheduled' and start_at <= now:
    quest.status = 'live'
    for user in audience(quest):
      create UserQuest(state='available')
      if quest.push_on_activation: enqueue push(user, quest)

  for quest in quests where status == 'live' and end_at < now:
    quest.status = 'ended'
    expire all UserQuest where state in ('available','active')

// Temps réel — QuestTracker (consomme events)
on event(user_id, verb, payload):
  for uq in UserQuest where state == 'active' and quest.target_verb == verb:
    if matches(quest.target_filter, payload):
      uq.progress += 1
      if uq.progress >= uq.target_count:
        uq.state = 'completed'
        Ledger.credit(user_id, quest.reward_credits, ref=uq.id)
        if quest.reward_badge_id: UserBadge.grant(...)
        if quest.push_on_completion: enqueue push(...)

API — user

API — admin (back office)

Calendrier admin

Le back office expose un calendrier mensuel (grille 7×5/6 jours type Google Calendar) où chaque quête apparaît comme un bandeau coloré étalé sur sa fenêtre start_at → end_at. Couleurs par type : 🟥 daily, 🟧 weekly, 🟩 monthly, 🟪 event. Les admins peuvent :

Streak & bonus de rétention

Au-delà des quêtes nommées, le système maintient une série quotidienne automatique : +25 ✦ par jour consécutif où l'user ouvre l'app et parle à ≥ 1 opérateur. Paliers : 7 j (+200 bonus), 30 j (+1500 + badge), 100 j (+5000 + badge doré). Reset si l'user rate un jour (grâce d'1 jour possible 2× par mois via crédit "sauvegarde série" à 100 ✦).

Événements saisonniers — runbook

L'équipe growth doit programmer les événements 4-6 semaines à l'avance en status draft, les faire relire par le DPO si collecte inhabituelle, puis passer en scheduled. Calendrier annuel type : Nouvel An, St-Valentin, Fête des Mères, Saint-Jean, rentrée, Halloween, Black Friday, Noël. Chaque événement : quête spéciale + push 48 h avant + visuel dédié en Home.

Anti-abus

9 · Sécurité, vie privée, IA responsable

Isolation mémoire

Invariant critique : la mémoire d'un opérateur A n'est jamais accessible par l'opérateur B. Le profil partagé est l'unique canal de partage, et chaque écriture y transite par un consent layer qui demande à l'utilisateur pour les données sensibles.

Chiffrement

Garde-fous IA

Conformité

Loi 25 (Québec), RGPD (UE). Droit à l'export (JSON signé) et à la suppression (purge 30j, logs anonymisés). DPO désigné, registre des traitements tenu.

10 · Critères d'acceptation MVP

MVP — must-have

  1. Inscription email + OTP, onboarding 3 écrans, choix initial d'au moins 1 opérateur.
  2. Catalogue de 5 opérateurs live (Lifestyle, Pets, Style, Companion, Business).
  3. Chat streaming fonctionnel avec isolation mémoire vérifiable (test E2E).
  4. Raccrocher = fermer la session, résumé généré, ledger débité.
  5. Inbox agrégée tous opérateurs, badge compteur dans l'icône home.
  6. Marketplace pour activer/désactiver, facturation Stripe immédiate au prorata.
  7. Crédits : solde visible, top-up 4 packs, auto top-up opt-in.
  8. Espace perso : profil + contacts + produits + docs, édition inline.
  9. Parrainage L1 opérationnel (L2/L3 en fast-follow).
  10. Quêtes quotidiennes & hebdomadaires : pipeline event → progrès → crédit ledger end-to-end. Back office avec calendrier et éditeur de quêtes.
  11. 3 badges actifs au lancement.
  12. FR par défaut, EN toggle partout.
  13. Back office : CRUD opérateurs, recherche users, ledger read-only, modération queue.
  14. Tous les garde-fous listés en §9 actifs, testés.

Hors-scope MVP (v1.1+)

Métriques de succès à 90j

MétriqueCible
Activation D1 (1er message envoyé)≥ 70%
Rétention D30≥ 45%
Opérateurs actifs moyens / user≥ 2.5
MRR par user (ARPU)≥ 18 $
NPS post-2 semaines≥ 40
Taux de parrainage (% users avec ≥1 filleul)≥ 15%

11 · Canaux de communication

Un opérateur n'est pas qu'un chatbot texte. Trois canaux, unifiés sur la même session et la même mémoire isolée.

Chat (défaut)

Appel vocal (WebRTC)

Session temps réel full-duplex. Pipeline : mic → VAD → STT streaming → LLM → TTS streaming → speaker. Latence cible < 800 ms perçue (first audio out).

Push & notifications

12 · Authentification & session

Méthodes

MéthodeUsageSécurité
Email + OTP 6 chiffresDéfaut, inscription & retourOTP valide 10 min, 5 essais, rate-limit IP
Magic linkAlternative desktopToken signé, valide 15 min, usage unique
Passkey (WebAuthn)Proposé après 1er loginPlatform authenticator, recovery via email
SSO Google / AppleFast-path mobileOAuth 2.0 PKCE, email vérifié obligatoire

Session

Récupération de compte

Flow : email vérifié → OTP → questions de sécurité (2/3) → déverrouillage. Si passkey seule configurée et device perdu, fallback magic link sur email de récupération (configurable). Lockout 24 h après 10 échecs.

13 · Admin, observabilité, incidents

Back office — rôles

RôleCapacités
Support L1Recherche user, lecture ledger, reset OTP, crédit compensatoire (≤ 500 ✦).
Support L2+ lecture résumés de session (pas les messages), remboursement Stripe, suspension compte 7 j.
Ops+ CRUD opérateurs, feature flags, gestion modération queue, incidents.
GrowthCRUD quêtes & événements (calendrier), segments d'audience, campagnes push, A/B tests pricing. Pas d'accès aux données user individuelles.
AdminAccès total, gestion rôles, purge RGPD manuelle, clés API.

Toute action admin sur un compte user est loggée avec raison obligatoire (audit trail immuable, append-only, 2 ans de rétention). L'user reçoit une notification pour toute action visible (crédit, suspension, reset).

Observabilité plateforme

Modération & signalements

Runbook incidents

  1. Détection (alerte ou signalement) → on-call ack < 5 min.
  2. Triage sévérité : S1 (panne totale), S2 (dégradation majeure), S3 (feature isolée), S4 (cosmétique).
  3. Communication : statuspage.soleenia.io mis à jour < 15 min pour S1/S2. In-app banner pour S1.
  4. Résolutionpost-mortem blameless publié sous 5 jours ouvrés (S1/S2).

Contrôle utilisateur sur ses données

Document vivant · v1.0 · Révision post-artefacts (auth, voix, admin)

14 · [v2] Multi-tenant & Realms

Soleenia n'est pas un produit — c'est une plateforme. Trois couches distinctes, trois populations, trois portails.

Les 3 layers

Modèle de données — hiérarchie

Realm { id, name, slug, domain, brand (logo/colors/fonts),
        plan, billing_model, pricing_policy, reward_model,
        locale, created_at, status,
        enabled_operators[], private_operators[],
        guardrails_override{} // subset only — impossible d'assouplir les garde-fous plateforme }

RealmMembership { user_id, realm_id, role (member/admin/owner),
                  member_label // "collaborateur" | "distributeur" | "client",
                  joined_at, referral_source }

// Un user peut appartenir à plusieurs realms — données strictement cloisonnées par realm_id
// Le profil partagé (annuaire, produits, contacts) est scopé par (user_id, realm_id)

Isolation — règles non-négociables

Branding total

Chaque Realm personnalise : logo, palette (brand + dark variant), typographie (via whitelist de Google Fonts), labels ("collaborateurs" vs "distributeurs" vs "membres"), copy d'onboarding, catalogue d'opérateurs activés, domaine custom (CNAME + cert auto).

15 · [v2] Facturation, markups & rev-share

Catalogue wholesale Soleenia

Soleenia publie un catalogue d'opérateurs avec prix de gros (wholesale_price) et plancher retail (min_retail = wholesale × 1.15). Les Realms sélectionnent ceux qu'ils veulent activer et définissent leur markup.

OpérateurWholesalePlancher retailExemple markup Realm
Nola (lifestyle)3,20 $/user/mo3,68 $5,99 $ (markup 87%)
Rex (business)4,50 $/user/mo5,18 $7,99 $ (markup 78%)
Juno (companion)2,80 $/user/mo3,22 $4,99 $ (markup 78%)

Usage-based channels

Canaux facturés à l'usage (pas au forfait) : SMS sortant (0,008 $/msg wholesale), appel voix WebRTC (0,012 $/min), appel voix PSTN (0,045 $/min), email transactionnel (0,0008 $/msg). Soleenia marge 30-45% dessus.

Trois modèles de facturation Realm → Soleenia

  1. Consolidated (Enterprise). Soleenia facture le Realm une fois par mois sur (seats × wholesale) + usage. Le Realm gère sa facturation aux end-users comme il veut. Ex : Hydro-Québec — gratuit côté employé, facture unique à l'employeur.
  2. Direct-to-user + rev-share. Soleenia facture l'end-user au prix retail défini par le Realm. Le Realm touche un rev-share (typiquement 20-25% du net après coûts). Ex : Axolea — chaque distributeur paie, Axolea touche sa part.
  3. Starter pool (SMB / vertical). Forfait mensuel plafonné (ex : 199 $/mo jusqu'à 50 users + 3 opérateurs). Au-delà, bascule automatique vers modèle consolidé.

Invariants & garde-fous pricing

16 · [v2] Data intelligence cross-realms

Soleenia agrège des signaux strictement anonymisés à travers tous les Realms pour : alimenter la recherche produit, détecter des tendances d'usage, améliorer les opérateurs, vendre des insights de marché (futur).

Ce qui remonte

Ce qui ne remonte JAMAIS

Gouvernance

Revue trimestrielle par DPO + comité éthique externe. Rapport public annuel (agrégats + demandes d'accès légales honorées). k-anonymity ≥ 25 avant toute publication ou export vers un insights-buyer.

17 · [v2] Opérateurs privés & garde-fous MLM

Opérateurs privés Realm

Un Realm peut déployer des opérateurs custom, non-listés dans le catalogue Soleenia. Exemples : "Clara RH" (Hydro, répond aux questions politiques internes), "Vega" (Axolea, closer anti-démarchage).

Pipeline : le Realm fournit system prompt + knowledge base + tool manifest → Soleenia review (compliance, guardrails) → déploiement isolé. SLA review : 5 jours ouvrés.

Garde-fous MLM / affiliate (non-négociables)

Les Realms MLM sont une zone sensible (régulation FTC, loi 25, démarchage). Soleenia impose :

Critères d'acceptation v2 (extrait)

CapacitéCritère
Création RealmUn nouveau tenant est up en < 30 min (self-serve starter) ou < 5 jours (Enterprise).
IsolationPenetration test tiers trimestriel : 0 cross-realm data leak toléré.
FacturationRev-share versé aux Realms le 15 du M+1, < 0,5% d'écart avec breakdown auto-généré.
Compliance MLM100% des messages sortants Vega (ou équivalent) visibles dans le journal utilisateur, en < 60 s après envoi.
BrandingUn Realm peut théminer logo + palette + typo + 20 labels sans intervention Soleenia.
Document vivant · v2.0 · Ajout de la couche multi-tenant (Realms, facturation B2B2C, intelligence cross-realms)