Technical Test Submission — Software Engineer
Repository: https://github.com/ichsanx/dms-backend-cybermax-v6
-
Technical Test Evidence (PDF):
docs/evidence/DMS_Test_Evidence_Report.pdf
(Contains before/after proof for REPLACE, Notifications, and DELETE flows via Swagger captures) -
Evidence folder:
docs/evidence/ -
Klick Evidence : https://github.com/ichsanx/dms-backend-cybermax-v6/blob/main/docs/evidence/DMS_Test_Evidence_Report.pdf
This repository contains a backend implementation of a Document Management System (DMS) designed to simulate a production-grade workflow: document upload, controlled replacement/deletion via approval, and user notifications.
Tech Stack
- NestJS (TypeScript)
- Prisma ORM
- PostgreSQL
- JWT Authentication
- RBAC (USER / ADMIN)
- Multer (disk storage) for file uploads
- Swagger for API exploration
Core Idea
- Sensitive document changes (REPLACE / DELETE) are not executed immediately.
- A PermissionRequest is created and the document moves into a locked status (
PENDING_*). - Only an ADMIN can approve/reject.
- The system enforces transactional integrity: document update + request update + notification are committed atomically.
status:ACTIVE | PENDING_REPLACE | PENDING_DELETEversion: increments on approved REPLACE
type:REPLACE | DELETEstatus:PENDING | APPROVED | REJECTEDreplaceFileUrl: populated during request (for REPLACE)
- Stored in DB
- Created for workflow events (request created, approved/rejected)
- Read status supported (
mark as read)
- USER uploads/has an existing document
- USER requests replace with a new file
→ system createsPermissionRequest(REPLACE)
→ document becomesPENDING_REPLACE(locked) - ADMIN lists pending approvals and approves
→ transaction:- update document
fileUrl+ incrementversion+ setACTIVE - mark request
APPROVED - create notification for USER
- update document
- USER verifies:
/documentsshows updatedfileUrland incrementedversion/notificationscontains an “approved” message
- USER requests delete
→ system createsPermissionRequest(DELETE)
→ document becomesPENDING_DELETE - ADMIN approves
→ transaction:- delete document (or soft-delete if configured)
- mark request
APPROVED - create notification for USER
- USER verifies:
- document no longer exists (GET by id returns 404)
- notification exists
Approval execution uses a database transaction to prevent partial updates:
- prevents “request approved but document not updated”
- prevents “document updated but notification missing”
- Document state is locked via status transitions to
PENDING_* - Versioning provides a foundation for optimistic concurrency strategies
- JWT-protected endpoints
- RBAC gates ADMIN-only routes (approval listing / approval actions)
- File upload guarded by authentication and validation
- File storage can migrate to S3/MinIO with pre-signed URLs
- Notifications can move to async processing via queue + workers
- Approval events can become domain events (event-driven architecture)
- Node.js 18+
- PostgreSQL
- npm
npm installCreate .env:
DATABASE_URL="postgresql://postgres:password@localhost:5432/dms_db"
JWT_SECRET="your_super_secret_key"
PORT=3000Run migration:
npx prisma migrate dev(Optional) seed:
npx prisma db seedRun server:
npm run start:devServer: http://localhost:3000
Swagger: http://localhost:3000/api
docker-compose up --buildExplore full spec via Swagger (
/api)
POST /auth/registerPOST /auth/loginGET /auth/me
GET /documents?q=&page=&limit=GET /documents/:idPOST /documents(multipart/form-data)POST /documents/:id/request-replace(multipart/form-data)POST /documents/:id/request-delete
GET /approvals/requestsPOST /approvals/requests/:id/approvePOST /approvals/requests/:id/reject
GET /notificationsPOST /notifications/:id/read
- USER creates a document (upload)
- USER requests REPLACE → document becomes
PENDING_REPLACE - ADMIN approves REPLACE
- Verify:
- document
fileUrlchanged versionincrements- USER receives notification
- Evidence:
docs/evidence/DMS_Test_Evidence_Report.pdf
- document
- USER requests DELETE → document becomes
PENDING_DELETE - ADMIN approves DELETE
- Verify:
- document removed / cannot be fetched
- USER receives notification
- Evidence:
docs/evidence/DMS_Test_Evidence_Report.pdf
- USER cannot access
GET /approvals/requests→ expect 403 - USER cannot call approve endpoint → expect 403
- ADMIN can access approvals endpoints → expect 200/201
- Workflow intentionally separates request from execution to mirror real governance processes.
- The approval mechanism is designed to be transactional, auditable, and extensible.
- Evidence PDF is provided to validate mandatory scenarios quickly (REPLACE/DELETE/Notifications).
Ichsan Saputra