SWSAI is a full-stack document upload application for uploading, storing, downloading, and tracking PDF documents. It supports single-file uploads, bulk uploads, per-file progress tracking, real-time bulk upload notifications, and a persistent notification center backed by MongoDB.
- Single PDF upload and bulk PDF upload
- Drag-and-drop and file picker support
- Per-file progress, status, size, and type display
- MongoDB-backed file storage using
Buffer - Uploaded document list with size, upload date, and download action
- Smart bulk upload behavior for more than 3 files
- Real-time notifications with Socket.IO
- Persistent notification center stored in MongoDB
- Unread notification badge
- Mark individual notifications as read
- Mark all notifications as read
Frontend
- React 19
- Vite
- Socket.IO Client
- Livvic font
- Plain CSS
Backend
- Node.js
- Express 5
- MongoDB Atlas
- Mongoose
- Multer
- Socket.IO
SWSAI/
backend/
config/
db.js
socket.js
controllers/
documentController.js
notificationController.js
middlewares/
multer.js
models/
Document.js
Notification.js
routes/
documentRoutes.js
notificationRoutes.js
services/
notificationService.js
index.js
package.json
frontend/
src/
App.jsx
App.css
index.css
main.jsx
package.json- Users select or drop one or more PDF files.
- The frontend validates PDF files before upload.
- For 3 or fewer files, each file uploads individually and shows inline progress.
- For more than 3 files, the frontend sends one bulk upload request and shows a background-processing banner.
- The backend receives files through Multer memory storage.
- Files are stored directly in MongoDB as binary buffers.
- Metadata is stored with each document record.
- Uploaded documents appear in the document table and can be downloaded.
- When more than 3 files are uploaded, the frontend sends a
notificationId. - The backend stores the files in MongoDB.
- After successful processing, the backend creates a success notification in MongoDB.
- The backend emits a
bulk-upload:completeSocket.IO event. - The frontend receives the event, updates the upload queue, refreshes documents, and updates the notification center.
- Notifications are stored in MongoDB with:
messagetypetimestampread
- The frontend fetches notifications from the backend on page load.
- The header bell shows the unread count.
- Users can mark a notification as read or mark all as read.
- Notifications persist across page refreshes because they are fetched from MongoDB.
cd backend
npm installCreate backend/.env:
PORT=5000
MONGO_URL="your_mongodb_connection_string"
CLIENT_URL=http://localhost:5173Start the backend:
npm run devThe backend runs on:
http://localhost:5000cd frontend
npm installOptional frontend environment file:
VITE_API_URL=http://localhost:5000/api
VITE_SOCKET_URL=http://localhost:5000Start the frontend:
npm run devThe frontend runs on:
http://localhost:5173GET /api/documentsReturns uploaded document metadata. File buffers are excluded from this response.
POST /api/documents/uploadForm data:
| Field | Type | Required | Description |
|---|---|---|---|
documents |
File or File[] | Yes | PDF files to upload |
notificationId |
String | No | Used by bulk uploads to match Socket.IO events |
fileCount |
Number | No | Used for failure notification counts |
Limits:
- Maximum 20 files per request
- Maximum 15 MB per file
- PDF files only
GET /api/documents/:id/downloadDownloads a document from MongoDB.
GET /api/notificationsReturns:
{
"notifications": [],
"unreadCount": 0
}POST /api/notificationsBody:
{
"message": "System maintenance scheduled",
"type": "info"
}Allowed notification types:
successerrorinfo
PATCH /api/notifications/:id/readPATCH /api/notifications/read-allEmitted after a bulk upload completes successfully.
{
"_id": "notification_id",
"message": "4 files uploaded successfully",
"type": "success",
"read": false,
"timestamp": "2026-05-07T00:00:00.000Z",
"count": 4,
"notificationId": "client_batch_id",
"documents": []
}Emitted when an upload fails.
{
"_id": "notification_id",
"message": "4 files failed to upload",
"type": "error",
"read": false,
"timestamp": "2026-05-07T00:00:00.000Z",
"notificationId": "client_batch_id",
"error": "Only PDF files are allowed."
}Emitted when a system notification is created through the API.
This project stores PDF file data directly inside MongoDB documents as Buffer values. MongoDB has a 16 MB document size limit, so the backend caps file uploads at 15 MB per PDF.
For larger production documents, consider moving file bytes to object storage such as S3, Firebase Storage, or GridFS while keeping metadata in MongoDB.
If MongoDB Atlas rejects the connection, check:
- Atlas Network Access IP allowlist
- Username and password
- Cluster status
MONGO_URLvalue inbackend/.env
Backend syntax checks:
cd backend
node --check index.js
node --check controllers/documentController.js
node --check controllers/notificationController.js
node --check services/notificationService.jsFrontend checks:
cd frontend
npm run build
npm run lint- Authentication and user-specific notifications are not implemented yet.
- Notifications are global to all connected clients.
- Files are stored directly in MongoDB and should stay below the configured 15 MB limit.
- Upload progress reflects network upload progress; server-side processing completion is confirmed by Socket.IO for bulk uploads.
This project is currently private/internal. Add a license before public distribution.