# Spécification produit — Rubis Sur l'Ongle

> Version : 0.2 (MVP — blog + Stripe livrés) · Dernière maj : 2026-05-09

Ce document est la source de vérité produit. Il décrit ce qu'on fait, pour qui, comment, et **ce qu'on ne fait pas**. Quand un wireframe et ce document divergent, ce document gagne.

---

## 1. Vision

Rubis Sur l'Ongle libère le temps des dirigeants de TPE-PME en automatisant la relance des factures impayées. Là où les concurrents proposent des outils de "recouvrement" complexes pour DAF d'ETI, on propose un outil **émotionnellement orienté temps libéré**, conçu pour qu'un boulanger ou une consultante puisse l'utiliser en autonomie en moins de 5 minutes.

## 2. Cible

### Profil principal

- **Taille** : TPE-PME, 5 à 50 salariés
- **Volume** : 10 à 200 factures émises par mois
- **Décideur** : le dirigeant lui-même, ou son comptable interne (1 personne max)
- **Pas de** : crédit manager, DAF, équipe finance dédiée
- **Outils existants** : facturation déjà gérée ailleurs (Sage, Pennylane, Henrri, Excel) — **on ne remplace pas** le logiciel de facturation, on relance ce qui sort de là

### Persona type

> "Sophie, 42 ans, gérante d'une SARL de prestation B2B (5 salariés). Elle émet 30 factures/mois, 6 sont en retard à tout moment. Elle relance le lundi soir entre 19h et 20h, à la main, en pestant. Elle a essayé un Excel de suivi qui n'a pas tenu 3 mois. Elle gagne 80 €/h facturés. Sa douleur : ne pas pouvoir oublier les retards mentalement."

### Anti-persona

- DAF d'ETI > 250 salariés (use case Dunforce/Upflow)
- Freelance unique avec 3 factures/mois (volume insuffisant pour ressentir la douleur)
- Pure facturation B2C (pas notre cas d'usage)

## 3. Principes UX

1. **3 clics maximum** pour lancer une relance sur une nouvelle facture. Idéal : 2 si plan par défaut bien configuré.
2. **Mobile first** sur le geste rapide (photo de facture en déplacement). Desktop pour la config et le suivi.
3. **L'OCR fait 90 %, l'humain 10 %** — l'utilisateur corrige, ne saisit pas.
4. **Plans pré-fournis** — 4 modèles par défaut, l'utilisateur n'arrive jamais sur une page blanche.
5. **Le ton monte progressivement** — rappel doux → relance ferme → mise en demeure (jamais auto).
6. **Toute action irréversible passe par une modale de confirmation** — envoyer une mise en demeure, supprimer un plan utilisé, archiver une facture en cours.

## 4. Fonctionnalités V1 (IN)

### 4.1 Authentification & onboarding

- Inscription email/password (2 champs minimum)
- Google SSO + Microsoft SSO en option (via Adonis Ally)
- Onboarding 3 étapes au max :
  1. Compte (email, mot de passe)
  2. Entreprise (nom, SIRET facultatif, secteur, volume mensuel via chips)
  3. Signature email (nom, fonction, coordonnées) — sera utilisée dans tous les emails de relance

### 4.2 Gestion des factures

- **Drag & drop** : zone d'upload acceptant PDF, PNG, JPG, jusqu'à 20 fichiers en simultané
- **OCR automatique** sur l'upload — extrait : client, email, numéro de facture, montant TTC, date d'échéance
- **Vérification OCR** : interface split (PDF à gauche, formulaire pré-rempli à droite). Tous les champs déjà remplis, l'utilisateur corrige uniquement
- **Saisie manuelle** : modale 6 champs avec recherche client autocomplete
- **Liste filtrable** : par statut (toutes, à relancer, en relance, encaissées, litige) via chips
- **Actions en lot** : checkboxes pour relancer manuellement, changer le plan, archiver

### 4.2bis Édition native des factures (V1.1, extension douce)

> **Cadre** : Rubis reste un *pure-player relance*. L'édition native s'adresse aux utilisateurs sans outil de facturation existant — ce n'est pas un pivot vers une concurrence frontale avec Pennylane/Sellsy. Voir ADR-025 pour le rationale et la roadmap Factur-X.

- **Éditeur split-view** `/factures/nouvelle` : panneau d'édition à gauche, preview PDF en live à droite (debounce 500 ms via `POST /api/v1/invoices/preview-pdf`).
- **Lignes structurées** : désignation, quantité (décimale autorisée pour heures/demi-jours), prix unitaire HT, taux de TVA (`0`, `2.1`, `5.5`, `10`, `20`). Le serveur recalcule HT/TVA/TTC + ventilation par taux ; les totaux côté client utilisent les mêmes règles d'arrondi pour feedback instantané.
- **Numérotation strict séquentielle** : préfixe + compteur incrémental par organisation (ex. `FAC-2026-0042`), alloué en transaction avec verrou row-level pour éviter les doublons sous concurrence. Brouillons exclus du compteur. Conforme art. 242 nonies A du CGI.
- **4 thèmes pré-faits** : *Classique* (sobre, cabinets/professions réglementées), *Moderne* (bandeau coloré, agences/studios), *Minimal* (noir & blanc, indépendants/designers), *Élégant* (Times Roman, boutiques premium). Couleur d'accent paramétrable. Galerie de sélection avec previews CSS miniatures dans `/parametres/facturation`.
- **Snapshots immuables** : à l'émission, le client (`client_snapshot`) et l'émetteur (`issuer_snapshot`) sont copiés dans la facture. Modifier ses settings ou le client n'altère jamais une facture déjà émise (exigence comptable).
- **Page paramètres** `/parametres/facturation` : 5 sections autonomes (chacune son Save) — identité émetteur (SIREN, SIRET, TVA intracom, RCS, capital, NAF, adresse structurée), RIB (IBAN normalisé + BIC + banque), numérotation (préfixe + compteur + padding avec aperçu live), mentions légales (délai par défaut + pénalités L441-10 + escompte L441-9 + texte libre), thème + accent.
- **Plan de relance optionnel** : si associé à l'émission, Rubis programme le check-in puis les relances à l'échéance — mécanique identique à l'OCR.
- **Brouillon** : créer une facture sans consommer le compteur (numéro éphémère `BROUILLON-XXXX`), pour préparer plusieurs factures avant d'émettre.
- **Génération PDF côté serveur** via `@react-pdf/renderer` (4 composants TSX dans `apps/api/app/pdf-templates/`). PDF stocké sur MinIO (`invoices/<orgId>/<uuid>.pdf`) et exposé via `GET /api/v1/invoices/:id/pdf`. Lazy regenerate si la génération initiale a échoué.
- **Roadmap conformité Factur-X** : V1 = PDF classique. **V1.5 (Q3-Q4 2026)** = Factur-X natif (PDF/A-3 + XML CII embarqué). **V2 (S1 2027)** = intégration PDP partenaire si demandes clients, avant l'échéance d'émission TPE-PME au 1er septembre 2027.

### 4.3 Plans de relance

- **Bibliothèque** : 4 plans pré-fournis par défaut (cf. `apps/api/app/services/default_plans.ts`)
  - *Standard B2B* (`standard-30j`) : J+3, J+10, J+25 — *amical → courtois → mise en demeure*
  - *Rapide* (`rapide-15j`) : J+1, J+7, J+15 — cadence resserrée pour récurrents / délais courts
  - *Patient* (`patient-60j`) : J+15, J+30 — clients de longue date, on laisse respirer
  - *Ferme* (`ferme-7j`) : cadence stricte pour clients à risque
- **Personnalisation** : l'utilisateur crée ses propres plans via `/plans/nouveau` (variantes / sur-mesure)
- **Éditeur** : cadence à gauche, contenu email à droite. Variables sous forme de chips drag-to-insert (`{{client.name}}`, `{{numero}}`, `{{amount}}`, `{{dueDate}}`, `{{signature}}`)
- **Tonalité** affichée comme tag visible — 4 valeurs : `amical`, `courtois`, `ferme`, `mise_en_demeure` (la dernière déclenche `requiresManualValidation: true`)

### 4.4 Check-in email (réconciliation V1)

> Remplace l'intégration banking en V1.

**Comment ça marche** :
1. L'utilisateur configure dans son plan : "Vérifier auprès de moi avant chaque relance" (oui/non + délai en jours, ex. T-2 jours avant la relance suivante)
2. À T-2 du prochain envoi prévu, Rubis envoie un email **à l'utilisateur** : *"Avez-vous été payé pour la facture F-2024-0042 (1 240 €, Boulangerie Martin) ?"* avec deux boutons : **Oui (stopper le plan)** / **Non (continuer la relance)**
3. Si l'utilisateur répond "Oui" → la facture est marquée encaissée, le plan est arrêté
4. Si l'utilisateur répond "Non" ou ne répond pas dans le délai → la relance part comme prévu

**Pourquoi cette mécanique** :
- Évite les relances "fantômes" sur des factures déjà payées hors plateforme
- Conserve l'utilisateur en boucle sans le surcharger
- Architecture compatible avec le futur banking : à terme, le check-in sera automatique via la banque, l'email user devient fallback

**À prévoir côté architecture V1** :
- Modèle d'événement réutilisable (`payment_status_check`) qui peut être déclenché par email-réponse OU plus tard par webhook bancaire
- Le statut de la facture (`pending`, `paid`, `awaiting_user_confirmation`, `cancelled`) doit être pivotable, pas spécifique au flow email

### 4.5 Mise en demeure

- **Toujours validation manuelle** via modale de confirmation. Pas de checkbox d'auto-envoi, c'est une décision produit forte.
- Modale affiche : montant, client, contenu de l'email, conséquences légales rappelées (loi LME)
- Utilisateur doit explicitement cliquer "Envoyer la mise en demeure" pour activer l'envoi
- Email envoyé en accusé de réception possible (option), pas par défaut

### 4.6 Dashboard & rubis

- **Hero** : compteur de rubis du mois en cours, conversion en heures libérées
- **KPIs** : factures à relancer, en relance, encaissé du mois, DSO moyen
- **Activité du jour** : flux des actions automatiques exécutées par Rubis
- **Top mauvais payeurs** : top 3 clients avec le plus de retards (interne uniquement, jamais visible côté client)

### 4.7 Détail facture

- Timeline mixant passé (plein) et futur (estompé) des étapes du plan
- Tracking d'ouverture des emails (X ouvertures)
- Bouton "Relancer maintenant" pour envoi manuel hors cadence
- Notes internes en libre

### 4.8 Mobile

- Responsive web (pas d'app native en V1)
- Action prioritaire : "Photo de facture" (use de la caméra → OCR)
- Tab bar 4 entrées max : Accueil · Factures · Plans · Réglages
- Le rubis reste hero du mobile

### 4.9 Changelog public et toast de version

- **Page publique** `rubis.pro/changelog` — timeline reverse-chrono des versions livrées, une carte par version (chip `v1.x.0` + date + highlights bulletés + body markdown narrative). Sticky rail desktop avec jump-nav, glow rubis sur la version la plus récente.
- **Tonalité** : produit-only, jamais tech (pas de "refactor", "stack", "monorepo"). On parle de ce que **l'utilisateur peut faire de nouveau**, pas de ce qu'on a codé. Une phrase d'attitude max par entrée.
- **Toast in-app** : à l'ouverture de la SPA, si `APP_VERSION` (constante versionnée dans `apps/web/src/version.ts`) diffère de la version stockée en `localStorage["rubis:last-seen-version"]`, on affiche un toast Sonner persistant `Nouvelle version v1.x.0 — Voir les nouveautés ↗`. Clic → ouvre `/changelog#1.x.0` dans un nouvel onglet.
- **Première visite** : silencieux, on enregistre la version sans toast (pas d'onboarding pollué).
- **RSS** : flux 2.0 dispo à `/changelog/rss.xml`, auto-discovered depuis le `<head>` de toutes les pages.
- **SEO** : `prerender = true`, JSON-LD `WebPage` + `mainEntity[TechArticle]` par version pour les rich snippets Google.

## 5. Fonctionnalités OUT (V2+)

### V2 (planifié)

- **SMS** : étape de relance par SMS, **réservé au plan le plus cher**
- **Multi-utilisateurs** : invitations, rôles (admin / éditeur / lecteur), **réservé aux plans payants**
- **Personnalisation avancée des emails** : signature HTML, logo client, branding sortant
- **Wordmark logo** (direction C) : à monter en complément du logo A

### V3+ (plus tard, à anticiper en archi)

- **Intégration banking** : Bridge / GoCardless / Tink, réconciliation automatique. Le check-in V1 devient un fallback
- **Intégrations comptable** : Sage, Pennylane, Quickbooks, Pennylane, Cegid
- **Multi-devises et multi-langues**
- **API publique** pour les ERP partenaires
- **App native** iOS/Android

### Hors scope définitif

- Émission de factures (on ne devient pas un Henrri-bis)
- CRM / pipeline commercial (on ne devient pas Sellsy)
- Gestion de trésorerie complète (on ne devient pas Agicap)

## 6. User flows clés (résumé)

### Flow 1 — Première facture (onboarding hot path)

1. Inscription (2 champs) → setup wizard 3 étapes → arrivée sur Factures (vide)
2. Drag PDF dans la dropzone → OCR → vérification 30 sec → "Valider"
3. Plan par défaut sélectionné → "Lancer la relance" → écran récompense rubis

**Cible** : moins de 4 minutes du début de l'inscription au premier rubis.

### Flow 2 — Routine hebdomadaire

1. Lundi matin, l'utilisateur reçoit un email check-in : "3 factures en attente — avez-vous été payé ?"
2. L'utilisateur clique "Oui" sur 1, "Non" sur 2 → les 2 relances partent automatiquement
3. Total temps utilisateur : <60 secondes

### Flow 3 — Mise en demeure

1. Étape J+20 d'un plan → notification dans l'app : "Brouillon prêt"
2. L'utilisateur ouvre la facture → relit le contenu → clique "Envoyer la mise en demeure"
3. Modale de confirmation avec rappel légal → confirme → envoi

## 7. Pricing (esquisse à tester)

| Plan | Prix | Cible | Limites | V1 |
|---|---|---|---|---|
| **Free** | 0 € | Freelance, test | 5 factures actives en relance, 1 utilisateur, plans standards seulement | ✓ |
| **Pro** | 19 €/mois | TPE 1-5 salariés | Illimité factures + OCR + plans, 1 utilisateur | ✓ |
| **Business** | 49 €/mois | PME 5-50 salariés | + multi-utilisateurs, + branding email, + SMS (V2) | partiel |

**Stratégie** : prix d'entrée agressif vs Sellsy/Axonaut (~30 €) défendable parce qu'on est mono-produit. Argument : *"moins cher qu'une heure de votre temps mensuel"*.

**Trial commercial** : 30 jours d'essai sans carte bancaire (CTA landing : *« Commencer l'essai 30 jours »*). Le code utilise actuellement une *« période de grâce 3 mois »* post-signup côté `apps/api/app/services/billing.ts` — incohérence à aligner sur 30 jours dans un PR séparé (cf. `docs/decisions.md`).

## 8. Notes architecture (à formaliser avec stack)

Quelques contraintes produit qui doivent guider l'architecture :

- **Statuts de facture pivotables** : `pending`, `awaiting_user_confirmation`, `paid`, `in_relance`, `litigation`, `cancelled` — pas hardcodés au flow email (cf. `packages/shared/src/constants/index.ts`)
- **Modèle d'événement abstrait** pour la confirmation : un `payment_status_check` peut être déclenché par email-réponse en V1, par webhook banking en V2 — l'app ne doit pas savoir d'où vient le signal
- **Multi-tenant dès le jour 1** : même si V1 est mono-user par compte, la structure DB doit supporter `organization` → `users` → `invoices` pour ne pas refactorer en V2
- **OCR** : provider abstrait derrière une interface — on doit pouvoir switcher Mindee → Document AI → Tesseract sans toucher au reste
- **Email outbound** : provider abstrait (Resend / Postmark / SendGrid) avec retry et tracking
- **Jobs/scheduler** : la cadence des relances et check-ins est un job persistant — préférer Inngest/Trigger.dev/queue dédiée à `setTimeout`

## 9. Métriques produit à instrumenter

- **Activation** : % d'utilisateurs ayant lancé leur 1ère relance dans les 7 jours suivant l'inscription
- **Engagement** : nombre de rubis gagnés par utilisateur par mois
- **Rétention** : MAU / WAU
- **Conversion business** : taux de passage Free → Pro
- **Satisfaction métier** : DSO moyen des comptes (avant/après Rubis)
- **Anti-métrique** : taux de "non" sur les check-in emails (si trop bas, on relance trop tôt et c'est inutile)
