rubis/CLAUDE.md
ordinarthur e449b708f3 docs(invoices): édition native + ADR-025 + roadmap Factur-X (Phase 5)
Documente la feature ajoutée en V1.1 dans toute la doc cadre :

- **CLAUDE.md** : "Pure-player relance" nuancé en "La relance reste
  l'âme du produit", extension douce assumée. Périmètre V1/IN
  enrichi avec l'éditeur de factures. Glossaire enrichi (facture
  native, numéro de séquence, snapshot, Factur-X). Stack : ajout
  @react-pdf/renderer + pointeurs vers pdf-templates et les routes
  /parametres/facturation et /factures/nouvelle.
- **docs/produit.md** : nouvelle section 4.2bis "Édition native des
  factures" — scope V1.1 minimal, snapshots immuables, numérotation
  strict séquentielle, roadmap Factur-X V1.5 / PDP V2.
- **docs/flow.md** : nouvelle section 11bis (3 sources d'une facture,
  flow utilisateur de création, génération PDF, numérotation,
  snapshots, cas limites). Tableau "Ce que Rubis ne fait PAS" mis à
  jour (édition oui mais pas devis/avoirs/Factur-X V1).
- **docs/decisions.md** : ADR-025 "Édition native des factures +
  roadmap Factur-X" (rationale extension douce, choix techniques
  notables, alternatives écartées).
- **docs/tech/architecture.md** : section 6.1bis (flow technique
  édition native, points d'attention numérotation atomique + lazy
  PDF regenerate), ajout @react-pdf à la stack, routes /native +
  /preview-pdf + /invoice-themes + /invoice-settings documentées.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 03:18:11 +02:00

201 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Rubis Sur l'Ongle
> **Le SaaS de relance de factures impayées pour TPE-PME françaises.** Drag-and-drop, OCR, plans de relance automatiques. 1 rubis = 10 minutes libérées.
Ce fichier est le contexte top-level. Il est court, dense, scannable. Pour les détails, voir `/docs/`.
---
## En une phrase
Vos factures se relancent toutes seules pendant que vous travaillez.
## Cible
TPE-PME françaises, 5 à 50 salariés, qui émettent 10 à 200 factures par mois, sans crédit manager dédié. Le décideur teste lui-même le produit (pas de cycle de vente long).
## Promesse de valeur
- **5 heures par semaine récupérées** (benchmark : 8h → <3h après automatisation).
- **Tonalité émotionnelle** : on vend du temps libéré, pas de la trésorerie. Le rubis gagné est la métrique-héros, pas le DSO.
- **2 à 3 clics maximum** pour lancer une relance sur une nouvelle facture.
## Principes produit (toujours valides)
1. **3 clics maximum** pour lancer une relance sur une facture neuve. Idéalement 2 si bien configuré.
2. **Mobile et desktop** la photo de facture depuis le téléphone est un usage clé.
3. **La relance reste l'âme du produit** c'est notre cœur de promesse. L'**édition native de factures**, ajoutée en V1.1 (cf. ADR-025), est une *extension douce* pour les utilisateurs sans outil de facturation existant. On reste sous-positionnés vs les vrais outils (Pennylane, Sellsy), pas concurrents frontaux. On ne fait toujours pas CRM ni comptabilité.
4. **Respectueux du client final** le ton monte avec le retard, jamais avant. Pas d'agressivité par défaut.
5. **Le rubis est une vraie devise produit** 1 rubis = 10 min libérées. La gamification doit être tangible et défendable.
## Identité de marque (TLDR)
| | |
|---|---|
| **Logo** | Direction A gem facetté géométrique. Le est un symbole produit autant qu'un logo. |
| **Couleur primaire** | `#9F1239` rubis profond légèrement violacé. *Anti-Coca-Cola.* |
| **Couleur secondaires** | `#771328` (deep), `#C9415C` (light), `#FBE4EA` (glow) |
| **Neutres** | Crème `#FAF7F2`, encre chaude `#1A1410`. Jamais de blanc pur, jamais de noir pur. |
| **Typo display** | Bricolage Grotesque (500800), self-hosted via `@fontsource-variable/bricolage-grotesque` |
| **Typo body** | Inter (400700), self-hosted via `@fontsource-variable/inter` |
| **Icônes** | Lucide (regular weight) |
| **Pas de** | or, bleu, vert, violet, emojis joaillerie 💎💰, mot "recouvrement" en com publique |
Voir `/docs/marque.md` pour la référence complète et `/docs/brand-identity.html` pour la présentation visuelle.
## Voix
Direct, concret, chaleureux, précis, empathique. *On parle comme un bon associé, pas comme une DAF.*
- "Vos factures relancées toutes seules."
- "Optimisez votre processus de recouvrement amiable."
## Glossaire
- **Rubis** : unité de gamification. **1 rubis = 10 minutes libérées** = 1 relance qu'on n'a pas eu à faire à la main.
- **Plan de relance** : cadence d'emails automatisés (ex. J+3, J+10, J+20). Chaque facture est associée à un plan.
- **Étape** : un email programmé dans un plan (ex. "J+10 relance ferme").
- **Confirmation** *(anciennement « check-in »)* : email envoyé **à l'utilisateur** (pas au client) pour confirmer si une facture a été payée avant l'envoi de la prochaine relance. Remplace l'intégration banking en V1.
- **Mise en demeure** : étape ferme du plan. **Toujours sous validation manuelle** via modale de confirmation, jamais auto.
- **Facture native** : facture **créée dans Rubis via l'éditeur** `/factures/nouvelle` (vs. facture importée par OCR/saisie manuelle). PDF généré côté serveur via `@react-pdf/renderer`, snapshots client + émetteur immuables figés à l'émission. Drapeau `invoices.is_native = true`.
- **Numéro de séquence** : compteur strict séquentiel par organisation (`invoices.sequence_number`), alloué à l'émission d'une facture native via verrou row-level. Conforme art. 242 nonies A du CGI (chronologie continue). Le numéro affiché est `<prefix><seq padé>` (ex. `FAC-2026-0042`). Brouillons exclus du compteur.
- **Snapshot** : copie figée des données du client (`client_snapshot`) et de l'émetteur (`issuer_snapshot`) au moment de l'émission d'une facture native. Garantit l'immutabilité légale : la facture reste intacte même si le client change d'adresse ou si l'org modifie ses settings.
- **Factur-X** : format de facturation électronique mixte PDF/A-3 + XML CII embarqué, conforme à la réforme française B2B (obligation d'émission au 1er septembre 2027 pour TPE-PME). Roadmap V1.5 pas en V1.
- **DSO** : Days Sales Outstanding. Métrique secondaire dans l'app, jamais dans la com publique.
- **LME** : loi de modernisation de l'économie (2008). Plafonne les délais de paiement à 60 jours (ou 45 jours fin de mois). Sanctions DGCCRF jusqu'à 2 M€.
## Périmètre V1
### IN
- Auth email/password + Google SSO + Microsoft SSO
- Onboarding 3 étapes (compte, entreprise, signature email)
- Upload drag-and-drop + OCR factures (PDF, PNG, JPG)
- Saisie manuelle (fallback)
- **Édition native de factures** (V1.1) éditeur `/factures/nouvelle` avec lignes structurées, 4 thèmes pré-faits (Classique, Moderne, Minimal, Élégant), couleur d'accent paramétrable, génération PDF côté serveur via `@react-pdf/renderer`. Settings de facturation sur `/parametres/facturation` (identité émetteur, RIB, mentions légales, numérotation strict séquentielle). PDF classique en V1, **Factur-X visé en V1.5** (Q3-Q4 2026), avant l'échéance d'émission TPE-PME au 1er sept 2027. Détails dans `/docs/produit.md` et ADR-025.
- Bibliothèque de plans (4 plans fournis par défaut : *Standard B2B*, *Rapide*, *Patient*, *Ferme*)
- Éditeur de plan (cadence + templates email avec variables)
- Confirmation par email à l'utilisateur (cadence configurable) confirme si payé relance ou stop. *Anciennement « check-in ».*
- Dashboard avec compteur rubis + KPIs (à relancer, encaissé, DSO)
- Liste filtrable des factures
- Détail facture avec timeline des relances
- Stripe billing (checkout, portal, webhook) + période de grâce post-signup
- Mode démo (sandbox in-app sans engagement)
- App mobile (web responsive)
- **Blog `rubis.pro/blog`** SSR par `apps/landing` (Astro 6), contenu en DB (`posts`) servi par `apps/api` via `/api/v1/posts/*`, admin de validation côté `app.rubis.pro/admin/blog`, génération hebdomadaire IA via cron (Sonnet 4.6) avec review humaine obligatoire. Détails dans `/docs/tech/architecture.md`.
- **Changelog `rubis.pro/changelog`** SSG par `apps/landing`, contenu en MD versionné dans `apps/landing/src/content/changelog/<version>.md` (Astro content collections, schéma Zod), RSS à `/changelog/rss.xml`. Toast SPA "Nouvelle version" déclenché par `apps/web/src/components/version-toast.tsx` quand `APP_VERSION` (`apps/web/src/version.ts`) diffère de `localStorage["rubis:last-seen-version"]`. Workflow release : `/push` (cf. `.claude/skills/push/SKILL.md`) bump la version + crée le .md + commit + push.
### OUT (V2 ou plus tard)
- **SMS** uniquement plan le plus cher en V2
- **Multi-utilisateurs** uniquement plans payants en V2
- **Intégration banking / réconciliation auto** l'architecture V1 doit l'anticiper, mais l'implémentation est V2+
- Multi-langues, multi-devises (FR/EUR only en V1)
- Intégration ERP/comptable (Sage, Pennylane, Quickbooks)
## Pricing (esquisse, à valider)
| Plan | Prix | Limite |
|---|---|---|
| **Free** | 0 | 5 factures actives en relance, 1 utilisateur |
| **Pro** | 19 €/mois | Factures illimitées, OCR illimité, 1 utilisateur |
| **Business** | 49 €/mois | + multi-utilisateurs, + branding email, + SMS (V2) |
Argument de vente : *"moins cher qu'une heure de votre temps mensuel"*.
## Décisions clés validées (résumé)
Voir `/docs/decisions.md` pour le log complet avec rationale.
- 1 rubis = 10 minutes libérées
- Logo direction A (gem facetté), wordmark à monter en parallèle plus tard
- Palette rubis chaude, sans or, sans bleu
- Typo Bricolage Grotesque + Inter
- Iconographie Lucide
- Mise en demeure : validation manuelle obligatoire (modale)
- SMS et multi-users : V2 + plans payants seulement
- Banking intégration : pas en V1, remplacée par check-in emails
- **Édition native de factures** : extension douce (V1.1), pas pivot vers facturation complète. Conformité Factur-X visée en V1.5, PDP partenaire évaluée en V2 si demandes clients (cf. ADR-025).
- **Numérotation strict séquentielle** : compteur par org alloué en transaction (verrou row-level), brouillons exclus du compteur choix vs flexible motivé par art. 242 nonies A du CGI.
## Stack technique
| Couche | Choix | Source |
|---|---|---|
| Backend (API) | **AdonisJS v7** (TS, MVC, Lucid ORM, auth & jobs intégrés) | ADR-014 |
| App SPA (`app.rubis.pro`) | **React 19 + Vite + TanStack Router/Query** | ADR-014 |
| Landing + blog (`rubis.pro`) | **Astro 6 SSR** (pages statiques prerenderées + blog en SSR) | |
| Design system | **`@rubis/ui`** Tailwind v4 tokens + composants TSX | |
| Base de données | **PostgreSQL** | ADR-014 |
| Hosting | **Proxmox + K3s** (perso) | ADR-014 |
| OCR provider | à benchmarker | ADR-020 (en attente) |
| Email outbound | à benchmarker | ADR-021 (en attente) |
| **Génération PDF (factures natives)** | **`@react-pdf/renderer`** côté API (Node), 4 templates dans `apps/api/app/pdf-templates/` | ADR-025 |
**Architecture** : monorepo Turborepo (`apps/api` AdonisJS, `apps/web` React SaaS, `apps/landing` Astro public, `packages/shared` types/schemas, `packages/ui` design system). API REST Bearer-auth, deux frontends qui consomment `@rubis/ui` pour un brand visuel unifié, PG et MinIO existants sur LXC Proxmox. Détails dans `/docs/tech/architecture.md`.
**Décisions cadres** : ADR-014 (stack), ADR-015 (monorepo), ADR-016 (PG Proxmox existant), ADR-017 (Bearer tokens), ADR-018 (MinIO existant).
### Conventions techniques (cross-cutting)
- **Identifiants : UUID partout.** Toutes les PK et FK applicatives sont des UUID v4 (PG `uuid` avec default `gen_random_uuid()`). **Jamais d'`increments`/`serial`**, même pour les tables internes (auth tokens, sessions, refresh tokens, etc.). Les UUID protègent de l'énumération, simplifient la fédération multi-tenant et évitent les fuites de volumes par incrément. Les transformers exposent les UUID directement en string pas de cast nécessaire.
## Documents associés
| Fichier | Rôle |
|---|---|
| `/CLAUDE.md` (ce fichier) | Contexte top-level, toujours en tête |
| `/apps/landing/` | Landing publique + blog (Astro 6 SSR) déployée sur `rubis.pro` |
| `/apps/landing/public/favicon.{svg,ico,png}` | Set complet de favicons + apple-touch-icon |
| `/apps/landing/public/site.webmanifest` | Manifest PWA (theme `#9F1239`, background `#FAF7F2`) |
| `/packages/ui/` | Design system partagé (tokens Tailwind v4 + composants TSX) |
| `/docs/produit.md` | Spec produit haut niveau (features, IN/OUT V1, pricing). Inclut la section "Édition native des factures". |
| `/docs/flow.md` | **Comportement produit deep-dive** : cycle de vie d'une facture, statuts + transitions, surfaces UI, mécanique de confirmation (check-in), mode démo, edge cases. Flow native = lignes structurées + snapshots immuables. |
| `/apps/api/app/pdf-templates/` | 4 templates `@react-pdf/renderer` (Classique, Moderne, Minimal, Élégant) + dispatcher. Génération PDF native côté serveur. |
| `/apps/web/src/routes/_app/parametres_.facturation.tsx` | Page de paramétrage de l'éditeur de factures (identité émetteur, RIB, mentions, numérotation, thème par défaut). |
| `/apps/web/src/routes/_app/factures_.nouvelle.tsx` | Éditeur split-view : édition à gauche, preview PDF live à droite (debounce 500 ms). |
| `/docs/marque.md` | Référence marque écrite (palette, typo, voix, do/don't) |
| `/docs/decisions.md` | Log de décisions avec rationale (format ADR-light) |
| `/docs/wireframes-mvp.html` | Wireframes low-fi des 13 écrans MVP |
| `/docs/brand-identity.html` | Présentation visuelle de la marque (4 logos, applications) |
| `/docs/munitions-marketing.md` | Stats marché, concurrents, positionnement, copy |
| `/docs/marketing/playbook.md` | Playbook acquisition premiers clients : ICP, Dream 100, channels, templates outreach |
| `/docs/tech/architecture.md` | Architecture technique : composants, flux, topologie, conventions |
| `/docs/tech/frontend.md` | Guide d'implémentation frontend (deps, Tailwind, TanStack, Tuyau) |
| `/Dockerfile` | Build nginx-alpine servant `/landing/` sur port 80 |
| `/k3s/` | Manifests Kubernetes (namespace, deployment, service) |
| `/.claude/deploy-memory.md` | Procédure de déploiement (Gitea CI ou manuel) |
| `/.claude/skills/push/SKILL.md` | Skill Claude Code `/push` release automatisée (bump version + entrée changelog + commit + push) |
| `/apps/landing/src/content/changelog/` | Une entrée Markdown par version (source de vérité du changelog public `/changelog`) |
| `/apps/web/src/version.ts` | Constante `APP_VERSION` déclenche le toast "Nouvelle version" dans la SPA |
## Déploiement
- **Domaine principal** : https://rubis.pro (landing + blog Astro) + https://app.rubis.pro (SaaS React)
- **Image landing** : `git.arthurbarre.fr/ordinarthur/rubis-landing:latest` (Astro Node SSR, port 4321)
- **Image API** : `git.arthurbarre.fr/ordinarthur/rubis-api:latest` (port 3333)
- **Image SPA** : `git.arthurbarre.fr/ordinarthur/rubis-web:latest` (nginx + proxy /api rubis-api)
- **Compat** : `rubis.arthurbarre.fr` / `app.rubis.arthurbarre.fr` redirigent en 301 vers `rubis.pro` / `app.rubis.pro` (config Traefik dans repo proxmox)
- Voir `.claude/deploy-memory.md` pour la procédure complète.
## Email infrastructure (`rubis.pro`)
Deux flux distincts qui cohabitent sur le même domaine via des sous-domaines DNS séparés :
| Flux | Provider | Adresse | DNS clés |
|---|---|---|---|
| **Sortant** (relances, check-in, auth) | Resend | `relances@rubis.pro` | `send.rubis.pro` (MX + SPF), `resend._domainkey` (DKIM), `_dmarc` |
| **Entrant** (humain) | OVH MX Plan | `contact@rubis.pro` (général + RGPD), `dev@rubis.pro` (notifs tech) | MX `@` `mx*.mail.ovh.net.` |
Détails dans `/docs/tech/backend.md` §12.5.
## Questions ouvertes
- **Conversion 1 rubis = 10 min** validée mais à confirmer en user testing après MVP
- **Wordmark "rubis" avec gem-i** (direction C) à monter en complément du logo A à un moment
- **Provider OCR** à benchmarker (Mindee, Document AI, Textract, Tesseract)
---
*Dernière mise à jour : 2026-05-09 · Maintenu par Arthur + Claude.*