CSV Manager is a two-service TypeScript monorepo. The backend is an Express 5 server running on port 3000 that accepts CSV file uploads, parses them into JSON, and holds the resulting records in memory. The frontend is a React 19 application bundled by Vite, served on port 4000, that gives users a file-picker form to upload a CSV and a live search interface once the upload succeeds. Both services are written entirely in TypeScript and are started independently — the frontend talks to the backend over plain HTTP using hardcodedDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/titobrian97/Prueba-tecnica-ts-node---gestion-de-csv/llms.txt
Use this file to discover all available pages before exploring further.
http://localhost:3000 base URLs.
Data Flow
When a user interacts with CSV Manager the request passes through five distinct stages before search results are visible on screen.File selection
The user picks a
.csv file in the React frontend. The App component transitions its state to ready_upload and enables the upload button.Multipart upload
On form submission,
SendCsv(file) builds a FormData object and POSTs it to POST /api/files on the Express backend. multer intercepts the request and holds the raw file bytes in req.file.buffer — nothing is written to disk.CSV parsing
The backend decodes the buffer to a UTF-8 string and passes it to
csvToJson.fieldDelimiter(",").csvStringToJson(rawCsv), which returns an Array<Record<string, string>>. That array is stored in the module-level usersData variable, replacing any previously uploaded data.Success response
The endpoint responds with
{ data: json, message: "El archivo se cargo correctamente" }. The frontend receives this, stores data in React state, shows a toast notification, and transitions appStatus to ready_usage, unmounting the upload form and rendering <Search>.Live search
As the user types in the search box,
useDebounce waits 300 ms before calling useSearch({ searchParam }), which fetches GET /api/users?q=<term>. The backend filters usersData with Object.values(row).some(v => v.toLowerCase().includes(search)) and returns the matching rows for the frontend to render.Services at a Glance
Backend
Express 5 REST API — handles multipart CSV uploads via
multer, parses records with convert-csv-to-json, and exposes a fuzzy-search endpoint over the in-memory dataset.Frontend
React 19 + Vite SPA — drives UI through an
APP_STATUS state machine, debounces search input, and communicates with the backend using simple fetch service functions.Key Technical Decisions
| Decision | Rationale |
|---|---|
| In-memory storage | No database dependency; usersData is a plain module-level array. Simple to run locally but resets on every server restart. |
multer with memoryStorage | Keeps uploaded bytes in a Buffer on the request object rather than writing a temp file, which simplifies parsing and avoids cleanup concerns. |
convert-csv-to-json | Single-purpose library that converts a CSV string to a typed Array<Record<string, string>> with one call. |
| CORS enabled globally | app.use(cors()) allows the Vite dev server on port 4000 to reach the Express server on port 3000 without proxy configuration. |
| TypeScript end-to-end | Both services use TypeScript — the backend via ts-node, the frontend via Vite’s native TS pipeline — ensuring consistent type safety across the stack. |
ts-node for the backend | Eliminates a compile step in development; server.ts is executed directly. |
| Vite for the frontend | Sub-second HMR and instant cold starts during development; vite --port=4000 pins the dev server to a known port. |
Both services must be running at the same time for the application to work. Start the backend first (
npm run dev inside /backend) so that port 3000 is available, then start the frontend (npm run dev inside /frontend). If the backend is not reachable the upload and search calls will both fail silently in the browser console.