Skip to content

Latest commit

 

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Troology — Project Management System

A production-style MERN application where Admins manage users and projects, and Users view the projects assigned to them and update their progress. Built with a Next.js frontend and an Express + Prisma + MongoDB backend, both deployed to Vercel.

Default admin (after seeding): admin@troology.com / Admin@123


Features

Area What's implemented
Auth & RBAC JWT login, bcrypt password hashing, two roles (ADMIN / USER). Only admins create users; only admins create/update/delete projects; users may only update the status of projects assigned to them.
Project CRUD title, description, startDate, endDate, status (PENDING / IN_PROGRESS / COMPLETED), assignedUsers, attachments.
File upload Multer (memory storage) → Cloudinary, max 3 attachments per project.
Dashboard analytics Total users, total projects, project counts by status, projects ending within 7 days.
User module Admin CRUD + role changes; every user can update their own profile (incl. avatar).
Bonus Theme toggle, activity logs, search / filter / pagination, Vercel deployment.

Architectural note

The brief suggests Axios + Redux/Context API on the frontend. This app instead uses Next.js Server Actions (App Router, React Server Components) for data fetching and mutations, which removes the need for a client-side data-fetching library and a global store. This is a deliberate, modern choice — the same requirements (API integration, role-aware UI, auth) are fully met.


Repository layout

.
├── frontend/   # Next.js 16 App Router app (React 19, Tailwind v4, shadcn/ui)
├── backend/    # Express 5 API (TypeScript, Prisma 6, MongoDB, Cloudinary)
│   └── src/docs/troology.postman_collection.json   # Postman collection (also served live at /docs)
└── .env.example                                     # reference for all environment variables

There is no root workspace configfrontend/ and backend/ are independent, each with its own package.json. Run commands from inside the relevant folder.


Prerequisites

  • Node.js 20+ (and optionally Bun — the frontend ships a bun.lock)
  • A MongoDB instance with a replica set (Prisma requires it for writes; MongoDB Atlas works out of the box)
  • A Cloudinary account (for file/avatar uploads)

Environment variables

Copy .env.example and split it into the two app-specific files (both are git-ignored):

  • Backend → backend/.env
  • Frontend → frontend/.env.local
Variable App Notes
DATABASE_URL backend MongoDB connection string (replica set required). Only required var — server throws on startup without it.
PORT backend Defaults to 4000. Ignored on Vercel serverless.
NODE_ENV backend development / production.
CORS_ORIGINS backend Comma-separated allowlist, no trailing slash. Defaults to localhost:3000 + deployed frontend.
JWT_SECRET backend Long random string.
JWT_EXPIRES_IN backend Defaults to 7d.
CLOUDINARY_CLOUD_NAME / CLOUDINARY_API_KEY / CLOUDINARY_API_SECRET backend From your Cloudinary dashboard.
NEXT_PUBLIC_API_URL frontend Base URL of the backend, no trailing slash (e.g. http://localhost:4000).

Running locally

Backend

cd backend
npm install            # installs deps + runs `prisma generate` (postinstall)
npm run db:push        # sync the Prisma schema to MongoDB
npm run db:seed        # create the default admin (admin@troology.com / Admin@123)
npm run dev            # tsx watch → http://localhost:4000

Other backend scripts: npm run build/start, npm run typecheck, npm run db:studio (Prisma Studio), npm run db:generate.

Frontend

cd frontend
bun install            # or: npm install
bun run dev            # → http://localhost:3000

Other frontend scripts: bun run build, bun run start, bun run lint (Biome), bun run format.


API reference

Base URL: http://localhost:4000/api/v1 (or the deployed backend). All protected routes require an Authorization: Bearer <token> header obtained from POST /auth/login.

Response envelope

// success
{ "success": true, "message": "OK", "data": { /* ... */ } }
// paginated
{ "success": true, "message": "OK", "data": [ /* ... */ ], "meta": { "page": 1, "limit": 10, "total": 42, "totalPages": 5 } }
// error
{ "success": false, "message": "Invalid credentials", "error": [{ "fieldName": "email", "message": "No account found with that email" }] }

Endpoints

Method Path Access Body / Query
GET /health public — (DB ping)
POST /auth/login public { email, password }{ token, user }
GET /auth/me any user
GET /users admin ?page&limit&search&role
POST /users admin multipart: name, email, password, role, optional avatar file
GET /users/:id self or admin
PATCH /users/:id admin multipart: name, email, password?, role, optional avatar
PATCH /users/me any user multipart: name, email, password?, optional avatar
DELETE /users/:id admin
GET /projects any user ?page&limit&search&status (non-admins see only their assigned projects)
POST /projects admin multipart: title, description, startDate, endDate, status?, assignedUserIds?, up to 3 attachments files
GET /projects/:id admin or assignee
PATCH /projects/:id admin multipart (same fields as create; appends attachments)
PATCH /projects/:id/status admin or assignee { status }
DELETE /projects/:id admin
GET /dashboard admin — (analytics)
GET /activity admin ?page&limit (activity log)

assignedUserIds accepts a JSON array string, a comma-separated string, or repeated form fields.

Live docs & Postman

  • Browse: the backend serves an HTML API reference at /docs, rendered from the Postman collection.
  • Import: point Postman at https://troology-backend.vercel.app/docs/collection.json, or import the file directly from backend/src/docs/troology.postman_collection.json.

The collection includes every endpoint, uses a {{baseUrl}} variable, and auto-captures the JWT from the login request into a {{token}} variable (via a test script), so every other request is pre-authorized.


Tech stack

Frontend — Next.js 16 (App Router, React 19 Server Components + Server Actions), TypeScript (strict), Tailwind CSS v4, shadcn/ui (radix + lucide), react-hook-form + zod, sonner, recharts, next-themes, @better-fetch/fetch, Biome (lint/format).

Backend — Node.js, Express 5, TypeScript (CommonJS), Prisma 6 ORM on MongoDB, JWT (jsonwebtoken), bcryptjs, Multer (memory storage), Cloudinary, tsx.


Deployment

Both apps deploy as separate Vercel projects.

  • Frontend — standard Next.js deployment; set NEXT_PUBLIC_API_URL to the backend URL.
  • Backend — Express runs as a Vercel serverless function via @vercel/node (backend/vercel.json). The app is CommonJS (Vercel's native ESM loader requires explicit .js extensions, which the source doesn't use), exports the Express app as the handler, and skips binding a port when process.env.VERCEL is set. Prisma's rhel-openssl-3.0.x binary target is bundled for the serverless runtime. Set all backend env vars in the project's Settings → Environment Variables.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages