diff --git a/.manus/db/db-query-1767974417009.json b/.manus/db/db-query-1767974417009.json new file mode 100644 index 0000000..d8892c6 --- /dev/null +++ b/.manus/db/db-query-1767974417009.json @@ -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 +} \ No newline at end of file diff --git a/.manus/db/db-query-1767975963635.json b/.manus/db/db-query-1767975963635.json new file mode 100644 index 0000000..ab7ca5f --- /dev/null +++ b/.manus/db/db-query-1767975963635.json @@ -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 +} \ No newline at end of file diff --git a/client/src/pages/InvoiceDetail.tsx b/client/src/pages/InvoiceDetail.tsx index 462df76..3022678 100644 --- a/client/src/pages/InvoiceDetail.tsx +++ b/client/src/pages/InvoiceDetail.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { useParams, useLocation } from "wouter"; import DashboardLayout from "@/components/DashboardLayout"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; @@ -29,7 +29,7 @@ export default function InvoiceDetail() { }); // Initialize form data when invoice loads - useState(() => { + useEffect(() => { if (invoice) { setFormData({ supplierName: invoice.supplierName || "", @@ -42,7 +42,7 @@ export default function InvoiceDetail() { totalAmount: invoice.totalAmount ? invoice.totalAmount.toString() : "", }); } - }); + }, [invoice]); const updateMutation = trpc.invoices.update.useMutation({ onSuccess: () => { diff --git a/server/routers.ts b/server/routers.ts index 67623ba..82c6921 100644 --- a/server/routers.ts +++ b/server/routers.ts @@ -109,10 +109,21 @@ export const appRouter = router({ // Decode base64 file data const fileBuffer = Buffer.from(input.fileData, "base64"); + console.log(`[Upload] Received file: ${input.fileName}, size: ${fileBuffer.length} bytes`); // Store source file const sourceFileKey = generateStorageKey(userId, input.fileName); - const { url: sourceFileUrl } = await localStoragePut(sourceFileKey, fileBuffer, "application/pdf"); + console.log(`[Upload] Generated storage key: ${sourceFileKey}`); + + try { + 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 const sourceFile = await createSourceFile({ diff --git a/storage/test/test-file.pdf b/storage/test/test-file.pdf new file mode 100644 index 0000000..a812de2 --- /dev/null +++ b/storage/test/test-file.pdf @@ -0,0 +1 @@ +Test PDF content \ No newline at end of file diff --git a/test-storage.mjs b/test-storage.mjs new file mode 100644 index 0000000..5041184 --- /dev/null +++ b/test-storage.mjs @@ -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); +} diff --git a/todo.md b/todo.md index ea60297..14e9792 100644 --- a/todo.md +++ b/todo.md @@ -115,3 +115,13 @@ - [x] Séparer la logique de sélection pour export et suppression - [x] Supprimer les restrictions disabled sur les checkboxes - [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