Kompta · Documentation Technique & Fonctionnelle
Architecture, Fonctionnalités et Modèle Économique
Kompta est un SaaS de gestion administrative et comptable conçu exclusivement pour les artisans et TPE françaises, plombiers, électriciens, maçons, peintres, menuisiers. Là où les acteurs généralistes comme Pennylane ciblent les PME avec expert-comptable dédié et Indy les freelances, Kompta adresse le créneau laissé vacant : l'artisan solo ou avec 2–5 employés, terrain, mobile, sans comptable interne.
| Critère | Kompta | Indy | Pennylane | Cegid |
|---|---|---|---|---|
| Cible | Artisans TPE | Freelances | PME + compta | ETI/Grands comptes |
| Mobile-first | Natif | Partiel | Non | Non |
| IA extraction factures | Gemini | Basique | Partiel | Coûteux (module) |
| Notes de frais + IK | Oui, natif | Non | Oui | Oui |
| Signature devis en ligne | Oui | Non | Oui | Oui |
| Factur-X natif | Oui | Non | Partiel | Oui |
| Prix entrée | 0 €/mois | 9 €/mois | 49 €/mois | Sur devis |
Pricing & Plans
Architecture Freemium gérée nativement via lib/plans.ts et lib/plan-limits.ts, couplée à Stripe Billing (Checkout + Portal). Les quotas sont vérifiés côté serveur avant chaque création de document.
| Forfait | Prix | Quotas | Fonctionnalités |
|---|---|---|---|
| Gratuit | 0 €/mois | 2 devis + 2 factures/mois | Fournisseurs illimités · FEC · Notes de frais |
| Pro | 25 €/mois | Illimité | Multi-utilisateurs · RBAC · Support prioritaire |
Exemple, vérification de quota
export async function checkQuoteLimit(companyId: string): Promise<void> {
const plan = await getPlan(companyId); // "free" | "pro"
if (plan === "pro") return; // illimité
const { count } = await supabase
.from("quotes")
.select("id", { count: "exact", head: true })
.eq("company_id", companyId)
.gte("created_at", startOfMonth());
if (count !== null && count >= 2) {
throw new PlanLimitError(
"Limite de 2 devis/mois atteinte. Passez au plan Pro."
);
}
}RBAC, Hiérarchie des Rôles
Le contrôle d'accès est géré par lib/permissions.ts avec 4 niveaux hiérarchiques. Le cloisonnement est total : sidebar, nav mobile, prompts IA et routes API sont tous filtrés par rôle.
| Rôle | Permissions | Pages accessibles |
|---|---|---|
| Artisan | Accès total + abonnement Stripe + suppression entreprise | Toutes les pages |
| Admin | CRUD toutes données. Invitations membres. Sans facturation Stripe. | Toutes sauf abonnement |
| Comptable | Lecture seule + export FEC/CA3. | Achats · Transactions · TVA · FEC · Profil |
| Employé | Soumet et consulte ses propres notes de frais. | Accueil · Notes de frais · Profil |
Guard dans une Server Action
"use server";
import { requireWrite } from "@/lib/permissions";
export async function createQuote(data: QuoteInput) {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
const { data: profile } = await supabase
.from("profiles").select("role, company_id")
.eq("id", user!.id).single();
// Lève une erreur si role = "comptable" ou "viewer"
requireWrite(profile?.role);
// Vérifie le quota plan avant insertion
await checkQuoteLimit(profile!.company_id);
return supabase.from("quotes")
.insert({ ...data, company_id: profile!.company_id });
}Ventes, Order-to-Cash
Workflow
Devis
Signature client
Acompte Stripe
Facture Factur-X
Paiement carte
| Fonctionnalité | Description |
|---|---|
| Devis interactifs | Catalogue produits/services, TVA par ligne, acompte Stripe. Signature via URL publique tokenisée (/sign/[token]). |
| Conversion automatique | Devis accepté → facture générée en brouillon, prête à finaliser en fin de chantier. |
| Factures Factur-X | XML EN 16931 embarqué dans le PDF. Numérotation FAC-2026-NNNNN incassable (verrou PostgreSQL). |
| Avoirs | Numérotation AV-2026-NNNNN. Une facture envoyée ne peut jamais être supprimée, seul l'avoir annule légalement (art. 289 CGI). |
| Facturation récurrente | Modèles hebdo/mensuel/annuel. Job CRON crée automatiquement la facture à l'échéance. |
| Transmission B2Brouter | Kompta est Opérateur de Dématérialisation (OD) : les factures sont transmises via la PDP partenaire B2Brouter (routage B2B et dépôt Chorus Pro pour le B2G). |
Achats & Notes de Frais
Pipeline d'extraction IA
Lorsqu'un justificatif est uploadé (PDF, JPEG, PNG, WebP, HEIC, max 20 Mo), le pipeline décide automatiquement entre deux chemins :
- Si le fichier contient un XML
CrossIndustryInvoice→ parsing direct vialib/facturx-parse.ts(fiabilité 100%, sans IA) - Sinon → envoi à Gemini multimodal (
lib/gemini-extract.ts) avec schéma de réponse structuré
Exemple, réponse JSON de l'extraction
{
"invoice_number": "FAC-2026-00421",
"date": "2026-05-14",
"supplier_name": "Brico Pro SAS",
"supplier_siret": "82345678900012",
"total_ht": "248.50",
"total_tva": "49.70",
"total_ttc": "298.20",
"vat_breakdown": [
{ "rate": "20", "base_ht": "248.50", "tva": "49.70" }
],
"category": "Matériaux",
"confidence": 0.97
}Notes de frais employés
| Fonctionnalité | Description |
|---|---|
| Scan + IA mobile | L'employé scanne son ticket depuis son téléphone. L'IA pré-remplit tous les champs. Compression canvas avant upload (max 1600px, JPEG 82%). |
| Indemnités kilométriques | Barème DGFiP 2026 par puissance fiscale (CV). Calcul automatique de l'indemnité. Non soumis à TVA. Archivé par trajet. |
| Justificatifs cloud | Stockés dans Supabase Storage (bucket expense-receipts). URL signée 60 min générée à la demande. Conservés même après suppression de la note. |
| Workflow approbation | Statuts : En attente → Approuvé / Refusé. Boutons ✓/✗ pour l'artisan. Filtrage par employé. |
| Clôture mensuelle | L'employé clôture ses notes d'un mois. Action idempotente (impossible de clôturer deux fois). Notification email propriétaire. Bannière dismissable en base. |
Gestion d'Équipe & Multi-Entreprise
Invitations via token UUID envoyé par email (Resend). Expiration après 7 jours. Un comptable peut être membre de plusieurs entreprises simultanément, la source de vérité est la table company_memberships.
| Action | Qui peut ? | Effet |
|---|---|---|
| Inviter un membre | Artisan + Admin | Email avec lien tokenisé valable 7 jours |
| Changer le rôle | Artisan uniquement | Écrit dans company_memberships ET profiles.role |
| Retirer un membre | Artisan + Admin | Supprime company_memberships, redirige profiles.company_id |
| Accepter une invitation | Invité (nouveau ou existant) | Upsert company_memberships, login/signup automatique |
CREATE TABLE company_memberships ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE, role TEXT NOT NULL DEFAULT 'viewer', created_at TIMESTAMPTZ DEFAULT now(), UNIQUE(user_id, company_id) );
Espace comptable multi-clients
Un membre comptable accède à la page /dashboard/cabinet : vue d'ensemble de toutes les entreprises qu'il suit (CA du mois, impayés, dépenses), avec bascule rapide via switchCompany() et accès direct à l'export FEC de chaque client.
Export comptable automatique mensuel
Le cron /api/cron/monthly-accountant-export (5 du mois, 07:00) génère un CSV des écritures du mois écoulé (factures clients, factures fournisseurs, transactions) et l'envoie par email à chaque membre comptable. Activable/désactivable par l'artisan via companies.accountant_auto_export (page Équipe).
Intelligence Artificielle Embarquée
| Cas d'usage | Fichier | Description |
|---|---|---|
| Extraction factures | lib/gemini-extract.ts | OCR augmenté, numéro, dates, fournisseur, SIRET, HT/TVA/TTC, ventilation par taux, catégorie métier. |
| Rapprochement bancaire | lib/gemini-bank-extract.ts | Analyse les libellés obscurs de relevés bancaires et suggère les factures correspondantes. |
| Copilote conversationnel | lib/assistant-prompt.ts | 3 prompts distincts selon le rôle. Rate-limited à 40 messages/heure/utilisateur. |
| Rédaction de devis | /api/devis/ai-draft | L'artisan décrit son chantier en langage naturel. Gemini propose les postes, quantités et prix. |
Exemple, cloisonnement du prompt par rôle
const ASSISTANT_SYSTEM_PROMPT_VIEWER = `
Tu es l'assistant de l'application Kompta, pour un EMPLOYÉ.
Tu peux UNIQUEMENT répondre aux questions sur :
- La création et soumission de notes de frais
- La clôture mensuelle des notes de frais
- La consultation du profil
Tu ne mentionnes JAMAIS et ne réponds JAMAIS aux questions sur :
les devis, factures clients, TVA, FEC, transactions, clients,
chiffre d'affaires, paiements, abonnements.
`;
export function getSystemPrompt(role: string | null): string {
if (role === "comptable") return ASSISTANT_SYSTEM_PROMPT_COMPTABLE;
if (role === "viewer") return ASSISTANT_SYSTEM_PROMPT_VIEWER;
return ASSISTANT_SYSTEM_PROMPT; // artisan / admin
}Infrastructure de Paiement, Stripe Connect
Kompta opère comme une plateforme d'encaissement décentralisée. Les fonds ne transitent jamais par Kompta | ils arrivent directement sur le compte Stripe de l'artisan.
| Fonctionnalité | Route / Fichier | Description |
|---|---|---|
| Onboarding Embedded | app/api/stripe/connect | L'artisan connecte son Stripe depuis /dashboard/settings sans quitter l'application. |
| Paiement direct sur facture | app/api/stripe/payment-link | Email de facture avec lien sécurisé. Client paye par carte. Fonds sur le Stripe de l'artisan. |
| Acompte sur devis | app/api/stripe/deposit-checkout | Checkout Stripe généré depuis le devis. Facture d'acompte créée automatiquement. |
| Webhooks & Idempotence | app/api/stripe/webhook | Signature STRIPE_WEBHOOK_SECRET vérifiée. Factures marquées 'Payée' sur payment_intent.succeeded. |
E-Invoicing & Factur-X
Architecture conçue nativement pour la réforme e-invoicing 2026 (art. L163-1 LPFP 2022). Profil urn:factur-x.eu:1p0:basicwl conforme à la norme européenne EN 16931.
| Composant | Fichier | Rôle |
|---|---|---|
| Génération PDF hybride | lib/facturx-pdf.ts | Crée le PDF et y embarque le XML (XMP metadata + attachment) |
| Schéma XML | lib/facturx.ts | Structure CrossIndustryInvoice / EN 16931 / BasicWL |
| Parsing achat | lib/facturx-parse.ts | Extrait depuis le XML embarqué, sans OCR, fiabilité 100% |
| Route publique XML | /api/public/invoice/… | Téléchargement du XML seul, consommé par la PDP B2Brouter |
Exemple, structure XML générée
<rsm:CrossIndustryInvoice>
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:factur-x.eu:1p0:basicwl</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>FAC-2026-00089</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20260514</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:ApplicableHeaderTradeSettlement>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:TaxBasisTotalAmount>1200.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">240.00</ram:TaxTotalAmount>
<ram:GrandTotalAmount>1440.00</ram:GrandTotalAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>Architecture Technique
| Couche | Technologie | Rôle |
|---|---|---|
| Frontend | Next.js 14 App Router + TypeScript | SSR/SSG, Server Components, Server Actions |
| UI | TailwindCSS + shadcn/ui + Radix | Composants accessibles, dark mode ready |
| Base de données | PostgreSQL via Supabase | Multi-tenant par company_id, RLS natif |
| Auth | Supabase Auth | JWT, sessions cookies, MFA, invitations |
| Storage | Supabase Storage | Justificatifs, logos, documents PDF |
| Resend + React Email | Devis, factures, invitations, rappels | |
| Paiement | Stripe Connect + Billing | Checkout, Portal, Webhooks, Connect Embedded |
| IA | Google Gemini 2.5 Flash | Extraction factures, rapprochement, copilote |
| Hosting | Hostinger | Variables d'env gérées côté Hostinger |
| Crons | vercel.json | Weekly report lundi 08:00, rappels quotidien 09:00 |
Clients Supabase, 3 flavors
Ne jamais mélanger ces trois clients :
| Fichier | Contexte | Usage |
|---|---|---|
| lib/supabase/client.ts | Browser | Composants React client uniquement |
| lib/supabase/server.ts | Server | Server Components, Route Handlers, Server Actions (cookies) |
| lib/supabase/admin.ts | Serveur privilégié | Service-role. Webhooks, cron, ops admin. JAMAIS côté client. |
Sécurité & Conformité
Row Level Security (RLS)
Toutes les tables business filtrent sur company_id. Un utilisateur ne peut jamais lire ou écrire en dehors de son entreprise, même en cas de bug applicatif.
-- Appliqué sur toutes les tables business (quotes, invoices, transactions…)
CREATE POLICY "isolate_by_company" ON client_invoices
FOR ALL USING (
company_id IN (
SELECT company_id FROM profiles WHERE id = auth.uid()
)
);| Mécanisme | Fichier | Description |
|---|---|---|
| Row Level Security | Supabase (SQL) | Isolation multi-tenant au niveau base de données. |
| MFA, OTP email | lib/mfa-edge.ts | Code OTP à chaque connexion via Supabase Auth. |
| Audit Trail | lib/audit.ts | Chaque action critique horodatée dans un registre inaltérable. |
| Rate Limiting | lib/ratelimit.ts | Routes API et IA limitées par IP/utilisateur. |
| Numérotation légale | server actions | Verrou PostgreSQL, aucun trou possible (CGI art. 242 nonies A). |
| Suppression RGPD | /api/account/delete | Export données personnelles + suppression cascade. |
admin.ts (service_role) n'est jamais importé côté navigateur. Les mutations sensibles passent exclusivement par des Server Actions ou Route Handlers authentifiés côté serveur.Expérience Mobile & PWA
Kompta est conçu mobile-first, l'artisan terrain crée un devis, scanne une facture ou déclare un trajet depuis son téléphone en moins de 30 secondes.
| Fonctionnalité | Description |
|---|---|
| Bottom navigation adaptée | Artisan : Accueil · Devis · Factures · Frais. Employé : Accueil · Mes frais. Comptable : Accueil · Achats · Transactions · FEC. |
| Scanner natif | <input capture='environment'> ouvre directement la caméra arrière. Aucune app native requise. |
| Compression canvas | Images compressées côté client avant upload : max 1600px, JPEG 82%. Réduction d'environ 80% sans perte perceptible. |
| Formulaires terrain | Montant en grand format centré, catégories en chips tactiles, optimisé pour les gros doigts et l'usage terrain. |
| PWA installable | manifest.json + service worker (sw.js). Icônes 192px et 512px. Fonctionne hors-ligne pour la consultation. |
Roadmap 2026–2027
| Priorité | Fonctionnalité | Impact | Statut |
|---|---|---|---|
| P1 | Rentabilité par chantier (devis vs coûts réels) | Différenciateur #1 | Planifié |
| Livré | Attestation TVA réduite 5,5%/10% (Cerfa 13948) | Supprime une friction terrain majeure | Disponible |
| P2 | Sync bancaire automatique (Bridge/Powens) | Fin import CSV manuel | En cours |
| P2 | Planning chantier visuel (vue semaine) | Rétention + premium | Planifié |
| P2 | Portail client self-service | Moins d'emails entrants | Planifié |
| P3 | Sous-traitants + attestations URSSAF | Secteur BTP haute valeur | Idée |
| P3 | App mobile native (Expo/React Native) | PWA → App Store | Idée |
| P4 | Pages SEO par métier (/plombier…) | Acquisition organique | Idée |
Pour les investisseurs
Kompta combine des standards techniques de niveau entreprise, RLS PostgreSQL, RBAC granulaire, Factur-X EN 16931, Stripe Connect, audit trail inaltérable, avec une expérience utilisateur conçue pour le terrain. L'IA embarquée (Gemini) supprime les frictions de saisie qui découragent les artisans d'adopter les outils comptables.
MRR Model
Abonnement + Commission flux
Marché cible France
~1,2M artisans TPE
Avantage concurrentiel
Mobile + IA + Chantier intégré
kompta.pro · Documentation Technique V2.1 · Mai 2026 · Confidentiel