Backend Architecture — Reza DocuHandshake
Overview
The live backend is a single Node.js Express application in server/.
There is no Supabase runtime in the current codebase. The backend is responsible for:
- magic-link token creation and verification
- session cookie issuance
- document metadata storage in PostgreSQL
- file persistence on the local filesystem
- admin document listing and updates
- signed-file uploads
- email notifications
- OpenAI-backed document analysis and signature helper endpoints
- shared admin signature preset storage
Runtime Components
| Concern | Current Implementation |
|---|---|
| HTTP server | Express 5 |
| Database | PostgreSQL via pg |
| Auth tokens | JWT via jsonwebtoken |
| Upload parsing | Multer in memory |
| File storage | Local filesystem under STORAGE_ROOT |
| Email delivery | Resend |
| AI analysis | OpenAI gpt-4o-mini |
| Signature helper endpoint | OpenAI gpt-image-1, SVG fallback |
Backend Module Map
server/index.ts- boots the API
- enables CORS and cookie parsing
- serves a small HTML utility page at
/ - mounts all
/api/*routers
server/config.ts- environment parsing and defaults
server/db.ts- PostgreSQL pool and query helper
server/middleware/auth.ts- session-required user middleware
- admin password validation helper
server/routes/auth.ts- magic-link request, verify, session, logout
server/routes/documents.ts- upload, owner/admin file streaming, public signed download
server/routes/admin.ts- admin listing, audit trail lookup, shared signature preset, document updates, signed-file upload, AI helpers
server/routes/notifications.ts- dispatches lifecycle emails
server/services/email.ts- Resend integration plus dev fallback logging
server/services/session.ts- JWT signing/verification for user sessions and download links
server/services/storage.ts- storage-root creation, safe path resolution, file writes/reads
Authentication Model
User Uploaders
- Email address is submitted to
POST /api/auth/magic-link/request - Backend stores a hashed token in
magic_link_tokens - Resend email links back to
/auth/verify?token=... - Successful verification sets the
rdh_user_sessioncookie - Protected user routes rely on
requireUser
Admin
- Frontend gate compares the entered password to
VITE_ADMIN_PASSWORD - Backend is the real enforcement layer and validates
ADMIN_PASSWORD - Admin password can be provided via JSON body, query string, or
x-admin-passwordheader depending on the endpoint
Request Lifecycles
Upload Flow
- User uploads a PDF through
POST /api/documents/upload - Multer reads the file into memory
- Backend validates session, MIME type, and file size
- File is written to disk under
documents/... - Metadata is inserted into
documents - Audit row is inserted into
document_audit_trail - Notification email to Reza is attempted
Signing Flow
- Admin fetches the current PDF through
GET /api/documents/:id/file - Browser signs the PDF with
pdf-lib - Final signed PDF is uploaded to
POST /api/admin/upload-signed-file POST /api/admin/update-documentupdatesstatus,signed_at,signature_data, andfile_path- Notification route emails the signed file back to the uploader
Rejection Flow
- Admin updates the document through
POST /api/admin/update-document - Current UI sets
status = 'completed' - Audit trail records
action = 'rejected' - Notification route emails the rejection reason
Database and Storage
PostgreSQL
The backend stores:
- document rows in
documents - audit events in
document_audit_trail - magic-link records in
magic_link_tokens - shared settings in
app_settings
documents.updated_at is maintained by a PostgreSQL trigger.
Filesystem Storage
Files are stored under the resolved STORAGE_ROOT path:
- originals:
documents/{timestamp}-{uuid}-{sanitized-name} - signed files:
signed/{documentId}/{timestamp}_{sanitized-name}
The backend never stores absolute paths in the database. It stores relative paths and resolves them through resolveStoragePath().
Integrations and Fallbacks
Resend
- Used for magic links, upload notifications, signed-document emails, and rejection emails
- In development, if
RESEND_API_KEYis missing, email sending is skipped and a warning is logged instead of crashing the request
OpenAI
POST /api/admin/analyze-documentsends extracted PDF text togpt-4o-miniPOST /api/admin/generate-signaturecan request a transparent signature image fromgpt-image-1- If no OpenAI key is configured,
generate-signaturefalls back to an inline SVG signature
Current Implementation Notes
- The backend root
/serves a simple HTML utility page for local inspection of key endpoints. - Signed files do not overwrite the original upload; a new signed file is written and
documents.file_pathis updated. analyze-document,generate-signature, andnotifications/sendare currently callable without admin authentication.- There is no dedicated
rejecteddocument status in the schema; the UI usescompletedplus an audit event.