Skip to main content

Parsers CSV

Depuis ADR-002, l'ingestion bancaire V1 se fait exclusivement via imports CSV. Les parsers vivent dans src/lib/parsers/.

Parsers existants

FichierBanque / SourceNotes
bourso.tsBoursoBank — compte courant / livret
bourso-pea.tsBoursoBank — PEAFormat distinct (investissements)
revolut.tsRevolutMulti-devise, FX explicite
trade-republic.tsTrade RepublicFormat germanique (virgule décimale)
detect.tsDétection autoDevine le parser à partir de l'entête CSV
types.tsTypes communsParsedTransaction, ParserResult, etc.

Source : src/lib/parsers/

Signature commune

Chaque parser expose une fonction pure qui prend le contenu brut CSV et retourne une liste normalisée de transactions :

import type { ParserResult, ParsedTransaction } from './types';

export function parseBourso(raw: string): ParserResult {
// 1. Split CSV (respecter les quotes et séparateurs de la banque)
// 2. Mapper chaque ligne vers ParsedTransaction
// 3. Retourner { transactions, errors, detectedCurrency }
}

Un ParsedTransaction est normalisé (format agnostique du CSV source) et prêt à être persisté via Prisma.

Détection auto

detect.ts analyse les premières lignes du fichier pour déterminer le parser à utiliser. Cette heuristique est appelée par la Server Action d'import (voir /docs/api/server-actions/import).

Ajouter un nouveau parser

  1. Écrire le test rouge dans src/lib/parsers/__tests__/<banque>.test.ts avec un échantillon CSV réel anonymisé
  2. Créer src/lib/parsers/<banque>.ts qui exporte parse<Banque>(raw: string): ParserResult
  3. Ajouter la détection dans detect.ts (signature distinctive dans l'entête)
  4. Exposer la valeur correspondante dans l'enum ImportSource du schéma Prisma (via migration)
  5. Documenter le format dans cette page + ajouter une entrée dans le guide utilisateur Import CSV
TDD obligatoire

Conformément à CLAUDE.md, aucun parser ne doit être implémenté sans test rouge préalable. Le test doit utiliser un échantillon CSV réel (anonymisé) pour couvrir les cas particuliers (lignes d'entête bruitées, caractères spéciaux, montants négatifs, devises).

Règles communes

  • Dédoublonnage : chaque transaction importée est hashée (SHA256) sur les champs signifiants (date + amount + description normalisée + accountId). Le hash est stocké dans Transaction.importHash avec une unique constraint → les réimports successifs ne créent pas de doublons
  • Signe : convention Patrimo → négatif = sortie, positif = entrée. Chaque parser applique cette normalisation si nécessaire
  • FX : si la transaction est en devise étrangère, stocker fxRate à la date de transaction (voir règles FX)
  • Décimale : toujours parser en Decimal (via decimal.js), jamais en number

Règles de gestion liées