rubis/CLAUDE.md
ordinarthur e5530930b3
Some checks failed
Build & Deploy API / build-and-deploy (push) Failing after 17s
Build & Deploy Web / build-and-deploy (push) Successful in 1m15s
Build & Deploy Landing / build-and-deploy (push) Failing after 3m43s
feat: refactor frontend en stack React unifiée (Astro + packages/ui)
Trois surfaces partagent désormais le même design system, Tailwind v4
et React 19 — au lieu d'avoir landing en HTML vanilla, app en React, et
blog en Adonis SSR :

* packages/ui — design system partagé (tokens Tailwind v4 + composants
  TSX) extrait depuis apps/web : Brand, Gem, Button, Card, Chip, Eyebrow,
  EmptyState. apps/web migre 41 imports vers @rubis/ui.

* apps/landing — nouvelle app Astro 6 SSR (rubis.pro), remplace l'ancienne
  landing nginx vanilla. Embarque :
  - Landing complète portée en sections React (Hero, Stats, Promise,
    HowItWorks, Gamification, Legal, Pricing, FAQ, FinalCTA, Footnotes)
  - Pages légales (mentions, confidentialité, CGV) via LegalLayout.astro
  - Blog SSR (/blog, /blog/:slug) qui consomme /api/v1/posts
  - sitemap.xml, blog/rss.xml, robots.txt en endpoints Astro
  - SEO complet (canonical, hreflang, OG, Twitter Card, JSON-LD
    Article/BreadcrumbList/Blog/SoftwareApplication)

* apps/api — BlogController réduit à 2 endpoints JSON (GET /api/v1/posts
  + GET /api/v1/posts/:slug). Suppression des templates SSR Adonis
  (apps/api/app/blog/), de l'alias #blog/*, des deps react-dom et
  @types/react-dom. PostTransformer + PostSummaryTransformer ajoutés.
  Le service blog_renderer + le seeder + les 3 articles fondateurs
  restent intacts (réutilisés par futurs admin + cron IA).

* Infra :
  - Dockerfile.landing (multi-stage Node 22 + tini, Astro standalone)
  - k3s/app/landing.yml (Deployment + Service rubis-landing:4321 +
    ConfigMap avec API_URL=http://rubis-api.rubis.svc.cluster.local:3333)
  - .gitea/workflows/deploy.yml mis à jour pour build rubis-landing
  - .gitea/workflows/deploy-web.yml + Dockerfile.web : prennent en
    compte packages/ui/ comme dépendance
  - Suppression du Dockerfile nginx legacy + k3s/{deployment,service}.yml
  - Suppression de landing/ (assets favicons migrés vers
    apps/landing/public/)

* Docs : architecture.md (vue d'ensemble + §4bis apps/landing complet,
  §3 endpoints JSON blog, layout monorepo), CLAUDE.md (stack technique,
  documents associés, déploiement).

Note infra : l'ancien Deployment "rubis" (nginx) et son Service ne sont
PAS supprimés par la CI — à nettoyer manuellement après validation que
Traefik a été repointé sur rubis-landing:4321 dans le repo proxmox.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 15:09:13 +02:00

10 KiB
Raw Blame History

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. Pure-player relance — on ne fait pas CRM, pas facturation, pas comptabilité. On fait une chose et on la fait bien.
  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), Google Fonts
Typo body Inter (400700), Google Fonts
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 /brand-identity.html pour la présentation visuelle (note : la mention de l'or accent dans ce fichier est obsolète, à ignorer).

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").
  • 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.
  • 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
  • Onboarding 3 étapes (compte, entreprise, signature email)
  • Upload drag-and-drop + OCR factures (PDF, PNG, JPG)
  • Saisie manuelle (fallback)
  • Bibliothèque de plans (4 plans fournis par défaut)
  • Éditeur de plan (cadence + templates email avec variables)
  • Check-in email à l'utilisateur (cadence configurable) → confirme si payé → relance ou stop
  • Dashboard avec compteur rubis + KPIs (à relancer, encaissé, DSO)
  • Liste filtrable des factures
  • Détail facture avec timeline des relances
  • 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 (à venir PR3), génération hebdomadaire IA via cron (Sonnet 4.6) avec review humaine obligatoire. Détails dans /docs/tech/architecture.md.

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

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)

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)
/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
/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)

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-07 · Maintenu par Arthur + Claude.