Checkpoint: Correction du formulaire d'édition et ajout de logs pour diagnostic.

Modifications apportées :
- Le formulaire d'édition de facture pré-remplit maintenant correctement les valeurs existantes grâce à useEffect
- Ajout de logs détaillés dans la route upload pour diagnostiquer le problème de stockage des fichiers PDF
- Les valeurs ne sont plus perdues lors de l'édition d'une facture

Note : Le problème d'export PDF (404) persiste car les fichiers ne sont pas stockés physiquement. Des logs ont été ajoutés pour identifier la cause lors du prochain upload.
This commit is contained in:
Manus
2026-01-12 14:41:29 -05:00
parent 568403245a
commit d7d7d98940
7 changed files with 101 additions and 4 deletions

View File

@@ -0,0 +1,28 @@
{
"query": "SELECT id, fileName, fileUrl, fileKey FROM sourceFiles ORDER BY createdAt DESC LIMIT 5;",
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.bd4328423008 --database fo4DRyBgjsuiigFAgNLuWm --execute SELECT id, fileName, fileUrl, fileKey FROM sourceFiles ORDER BY createdAt DESC LIMIT 5;",
"rows": [
{
"id": "60001",
"fileName": "FACTURES FOURNISSEURS.pdf",
"fileUrl": "/storage/2026-01/1-fmxuQN06-FACTURES FOURNISSEURS.pdf",
"fileKey": "2026-01/1-fmxuQN06-FACTURES FOURNISSEURS.pdf"
},
{
"id": "30001",
"fileName": "FACTURES FOURNISSEURS.pdf",
"fileUrl": "/storage/2026-01/1-0n3DLF9m-FACTURES FOURNISSEURS.pdf",
"fileKey": "2026-01/1-0n3DLF9m-FACTURES FOURNISSEURS.pdf"
},
{
"id": "1",
"fileName": "FACTURES FOURNISSEURS.pdf",
"fileUrl": "/storage/2026-01/1-FSrFmQSC-FACTURES FOURNISSEURS.pdf",
"fileKey": "2026-01/1-FSrFmQSC-FACTURES FOURNISSEURS.pdf"
}
],
"messages": [],
"stdout": "id\tfileName\tfileUrl\tfileKey\n60001\tFACTURES FOURNISSEURS.pdf\t/storage/2026-01/1-fmxuQN06-FACTURES FOURNISSEURS.pdf\t2026-01/1-fmxuQN06-FACTURES FOURNISSEURS.pdf\n30001\tFACTURES FOURNISSEURS.pdf\t/storage/2026-01/1-0n3DLF9m-FACTURES FOURNISSEURS.pdf\t2026-01/1-0n3DLF9m-FACTURES FOURNISSEURS.pdf\n1\tFACTURES FOURNISSEURS.pdf\t/storage/2026-01/1-FSrFmQSC-FACTURES FOURNISSEURS.pdf\t2026-01/1-FSrFmQSC-FACTURES FOURNISSEURS.pdf\n",
"stderr": "",
"execution_time_ms": 56
}

View File

@@ -0,0 +1,31 @@
{
"query": "SELECT id, fileName, fileKey, fileUrl, processingStatus FROM sourceFiles ORDER BY createdAt DESC LIMIT 3;",
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.bd4328423008 --database fo4DRyBgjsuiigFAgNLuWm --execute SELECT id, fileName, fileKey, fileUrl, processingStatus FROM sourceFiles ORDER BY createdAt DESC LIMIT 3;",
"rows": [
{
"id": "60001",
"fileName": "FACTURES FOURNISSEURS.pdf",
"fileKey": "2026-01/1-fmxuQN06-FACTURES FOURNISSEURS.pdf",
"fileUrl": "/storage/2026-01/1-fmxuQN06-FACTURES FOURNISSEURS.pdf",
"processingStatus": "completed"
},
{
"id": "30001",
"fileName": "FACTURES FOURNISSEURS.pdf",
"fileKey": "2026-01/1-0n3DLF9m-FACTURES FOURNISSEURS.pdf",
"fileUrl": "/storage/2026-01/1-0n3DLF9m-FACTURES FOURNISSEURS.pdf",
"processingStatus": "completed"
},
{
"id": "1",
"fileName": "FACTURES FOURNISSEURS.pdf",
"fileKey": "2026-01/1-FSrFmQSC-FACTURES FOURNISSEURS.pdf",
"fileUrl": "/storage/2026-01/1-FSrFmQSC-FACTURES FOURNISSEURS.pdf",
"processingStatus": "completed"
}
],
"messages": [],
"stdout": "id\tfileName\tfileKey\tfileUrl\tprocessingStatus\n60001\tFACTURES FOURNISSEURS.pdf\t2026-01/1-fmxuQN06-FACTURES FOURNISSEURS.pdf\t/storage/2026-01/1-fmxuQN06-FACTURES FOURNISSEURS.pdf\tcompleted\n30001\tFACTURES FOURNISSEURS.pdf\t2026-01/1-0n3DLF9m-FACTURES FOURNISSEURS.pdf\t/storage/2026-01/1-0n3DLF9m-FACTURES FOURNISSEURS.pdf\tcompleted\n1\tFACTURES FOURNISSEURS.pdf\t2026-01/1-FSrFmQSC-FACTURES FOURNISSEURS.pdf\t/storage/2026-01/1-FSrFmQSC-FACTURES FOURNISSEURS.pdf\tcompleted\n",
"stderr": "",
"execution_time_ms": 48
}

View File

@@ -1,4 +1,4 @@
import { useState } from "react"; import { useState, useEffect } from "react";
import { useParams, useLocation } from "wouter"; import { useParams, useLocation } from "wouter";
import DashboardLayout from "@/components/DashboardLayout"; import DashboardLayout from "@/components/DashboardLayout";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
@@ -29,7 +29,7 @@ export default function InvoiceDetail() {
}); });
// Initialize form data when invoice loads // Initialize form data when invoice loads
useState(() => { useEffect(() => {
if (invoice) { if (invoice) {
setFormData({ setFormData({
supplierName: invoice.supplierName || "", supplierName: invoice.supplierName || "",
@@ -42,7 +42,7 @@ export default function InvoiceDetail() {
totalAmount: invoice.totalAmount ? invoice.totalAmount.toString() : "", totalAmount: invoice.totalAmount ? invoice.totalAmount.toString() : "",
}); });
} }
}); }, [invoice]);
const updateMutation = trpc.invoices.update.useMutation({ const updateMutation = trpc.invoices.update.useMutation({
onSuccess: () => { onSuccess: () => {

View File

@@ -109,10 +109,21 @@ export const appRouter = router({
// Decode base64 file data // Decode base64 file data
const fileBuffer = Buffer.from(input.fileData, "base64"); const fileBuffer = Buffer.from(input.fileData, "base64");
console.log(`[Upload] Received file: ${input.fileName}, size: ${fileBuffer.length} bytes`);
// Store source file // Store source file
const sourceFileKey = generateStorageKey(userId, input.fileName); const sourceFileKey = generateStorageKey(userId, input.fileName);
console.log(`[Upload] Generated storage key: ${sourceFileKey}`);
try {
const { url: sourceFileUrl } = await localStoragePut(sourceFileKey, fileBuffer, "application/pdf"); const { url: sourceFileUrl } = await localStoragePut(sourceFileKey, fileBuffer, "application/pdf");
console.log(`[Upload] File stored successfully at: ${sourceFileUrl}`);
} catch (error) {
console.error(`[Upload] FAILED to store file:`, error);
throw error;
}
const sourceFileUrl = `/storage/${sourceFileKey}`;
// Create source file record // Create source file record
const sourceFile = await createSourceFile({ const sourceFile = await createSourceFile({

View File

@@ -0,0 +1 @@
Test PDF content

16
test-storage.mjs Normal file
View File

@@ -0,0 +1,16 @@
import { localStoragePut } from "./server/localStorage.ts";
const testBuffer = Buffer.from("Test PDF content");
const result = await localStoragePut("test/test-file.pdf", testBuffer, "application/pdf");
console.log("Storage test result:", result);
// Check if file exists
import fs from "fs/promises";
import path from "path";
const fullPath = path.join(process.cwd(), "storage", "test/test-file.pdf");
try {
await fs.access(fullPath);
console.log("✓ File exists at:", fullPath);
} catch {
console.log("✗ File does NOT exist at:", fullPath);
}

10
todo.md
View File

@@ -115,3 +115,13 @@
- [x] Séparer la logique de sélection pour export et suppression - [x] Séparer la logique de sélection pour export et suppression
- [x] Supprimer les restrictions disabled sur les checkboxes - [x] Supprimer les restrictions disabled sur les checkboxes
- [x] Ajouter validation pour export PDF (seulement score 100%) - [x] Ajouter validation pour export PDF (seulement score 100%)
## Diagnostic problème 404 persistant
- [ ] Vérifier si les fichiers sont stockés dans le dossier storage
- [ ] Vérifier les URLs générées dans la base de données
- [ ] Vérifier la configuration Express pour servir les fichiers statiques
- [ ] Corriger le chemin d'accès aux fichiers PDF
## Correction formulaire d'édition
- [x] Pré-remplir les valeurs existantes dans le formulaire d'édition de facture
- [x] Utiliser useEffect pour initialiser les valeurs du formulaire