Appearance
BDD-146 - Colonnes numériques mal typées à l'export CSV et vides à l'export Excel
1. User Story
En tant qu'utilisateur exportant les données d'une source,
Je veux que les colonnes numériques soient correctement typées dans les fichiers exportés,
Afin de pouvoir utiliser directement les valeurs sans retraitement manuel.
2. Critères d'acceptance
- La prévisualisation d'une source affiche les valeurs numériques réelles (pas le type
number). - L'export CSV sérialise les nombres en format numérique (virgule décimale, reconnue par Excel fr-FR).
- L'export Excel place les valeurs dans des cellules de type nombre (non vides).
- Le correctif est validé sur plusieurs types numériques : entier, décimal, négatif.
3. Analyse des bugs
Bug 1 — Libellé "number" en anglais dans la page de consultation
Fichier : front/src/pages/admin/sources/AdminSourceDetailPage.vue
La fonction getColumnTypeLabel() retournait 'number' (anglais) pour les types PostgreSQL numériques (numeric, integer, bigint, double precision, real). Ce libellé s'affichait dans l'en-tête de chaque colonne numérique.
Bug 2 — Export CSV : nombres traités comme texte dans Excel fr-FR
Fichier : back/src/api/sources/sources.service.ts — méthode serializeCsvValue()
La méthode retournait un number JavaScript (ex. 1234.56). PapaParse l'écrivait avec le séparateur décimal anglais (point). Excel en locale française utilise la virgule comme séparateur décimal — il traitait donc 1234.56 comme texte.
Bug 3 — Export Excel : cellules numériques vides
Fichier : back/src/api/sources/services/source-data-format.util.ts — formatSourceTableCellValue()
Pour une colonne PostgreSQL NUMERIC, Prisma retourne un objet Decimal (decimal.js). La fonction ne traitait pas ce cas et retournait l'objet tel quel. SheetJS (XLSX.utils.json_to_sheet) ne sait pas sérialiser un objet Decimal → cellule vide.
4. Périmètre technique
Backend
| Fichier | Modification |
|---|---|
back/src/api/sources/services/source-data-format.util.ts | formatSourceTableCellValue : gestion des objets Decimal Prisma → number JS |
back/src/api/sources/sources.service.ts | serializeCsvValue : format décimal français (virgule) pour les number |
Frontend
| Fichier | Modification |
|---|---|
front/src/pages/admin/sources/AdminSourceDetailPage.vue | getColumnTypeLabel : 'number' → 'nombre' |
5. Détails d'implémentation
Correction formatSourceTableCellValue (Excel)
Ajout d'un bloc avant le return value final pour convertir les objets Decimal Prisma en number JavaScript :
typescript
if (typeof value === 'object') {
const primitive = (value as { valueOf?: () => unknown }).valueOf?.();
if (typeof primitive === 'number' && Number.isFinite(primitive)) return primitive;
if (typeof primitive === 'string') {
const n = Number(primitive.replace(',', '.'));
if (Number.isFinite(n)) return n;
}
}SheetJS reçoit un vrai number → cellule de type nombre dans Excel.
Correction serializeCsvValue (CSV fr-FR)
Remplacement de la branche number :
typescript
if (typeof value === 'number') {
if (!Number.isFinite(value)) return '';
if (Number.isInteger(value)) return String(value);
return String(value).replace('.', ','); // virgule décimale fr-FR
}PapaParse écrit 1234,56. Excel fr-FR reconnaît la virgule décimale → cellule nombre.
Correction getColumnTypeLabel (affichage)
javascript
if (normalizedType === 'numeric') return 'nombre'
if (normalizedType === 'integer') return 'nombre'
// ...6. Tests associés
Tests unitaires back
back/src/api/sources/services/source-data-format.util.spec.ts- Conversion objet Decimal décimal →
numberJS - Conversion objet Decimal entier →
numberJS - Conversion objet Decimal négatif →
numberJS - Conversion avec virgule décimale (
1234,56) →numberJS - Conversion quand
valueOf()retourne directement unnumber
- Conversion objet Decimal décimal →
back/src/api/sources/sources.service.spec.ts- Export CSV : colonnes décimales sérialisées avec virgule (
1234,56) - Export XLSX : cellules numériques de type
'n'(SheetJS) avec valeur correcte
- Export CSV : colonnes décimales sérialisées avec virgule (
Tests unitaires front
front/src/__tests__/pages/admin/sources/AdminSourceDetailPage.spec.jsgetColumnTypeLabel:numeric,integer,bigint,double precision,real→'nombre'- Aucun libellé
'number'(anglais) affiché
7. Liens
- Ticket Jira : BDD-146
- Doc export source existante : bdd-61-export-source.md
