A full-stack team task management web application built with Spring Boot and React.
Create projects, invite team members, assign tasks, and track progress β all in one place.
Frontend: get-smark-task-manager.vercel.app
- OTP-based signup (email verification)
- JWT login (24hr token)
- Forgot password via OTP
- Create projects (creator becomes Admin)
- Add members by email:
- Registered user β directly added + notification email
- Unregistered user β invite email sent β shows as β³ Pending until accepted
- Cancel pending invites
- Remove members
- Create tasks with Title, Description, Due Date, Priority (Low / Medium / High)
- Assign tasks to confirmed members only (pending invites cannot be assigned)
- Status tracking: To Do β In Progress β Done
- Admin: full control (create, update, delete)
- Member: update status on assigned tasks only
- Total tasks, Tasks by status, Overdue count
- Per-user workload, 7-day activity trend
- Project health overview, Upcoming deadlines
- Auto-refreshes every 30 seconds
- OTP emails for signup and password reset
- Invite link email for unregistered users
- "You've been added" email for registered users
| Layer | Technology |
|---|---|
| Backend | Spring Boot 3.2.5, Java 21 |
| Database | MongoDB |
| Auth | JWT + BCrypt |
| Brevo SMTP (smtp-relay.brevo.com) | |
| Frontend | React 19, Vite 8, React Router v7 |
| HTTP | Axios |
| Deploy | Railway (backend + DB), Vercel/Railway (frontend) |
GetSmark---TaskManager/
βββ client/ # React Frontend
β βββ Dockerfile # Production build (Nginx)
β βββ nginx.conf # React Router + static serving
β βββ railway.toml # Railway config
β βββ vite.config.js # Dev proxy /api β localhost:8080
β βββ src/
β βββ App.jsx # Routes + PrivateRoute
β βββ context/AuthContext.jsx # JWT state
β βββ utils/api.js # Axios + token injection
β βββ pages/
β βββ Home.jsx
β βββ Login.jsx
β βββ Signup.jsx
β βββ Forgotpassword.jsx
β βββ Dashboard.jsx
β βββ Projects.jsx
β βββ ProjectDetail.jsx # Members, pending invites, tasks
β βββ Tasks.jsx
β βββ AcceptInvite.jsx # Invite link handler
β
βββ taskmanager/ # Spring Boot Backend
βββ Dockerfile # Production build
βββ railway.toml # Railway config
βββ src/main/java/com/taskmanager/
βββ controller/ # Auth, Project, Task, Dashboard
βββ service/ # Business logic + email
βββ repository/ # MongoDB repos
βββ model/ # User, Project, Task, Invitation, OtpStore
βββ security/ # JwtUtil, JwtFilter
βββ resources/
βββ application.properties # Local dev
βββ application-prod.properties # Railway production
- Java 21+
- Node.js 18+
- MongoDB running locally (
mongodb://localhost:27017) - Brevo account for emails (brevo.com β free 300 emails/day)
git clone https://github.com/23Amansharma/GetSmark---TaskManager.git
cd GetSmark---TaskManagerEdit taskmanager/src/main/resources/application.properties:
server.port=8080
app.url=http://localhost:5173
spring.data.mongodb.uri=mongodb://localhost:27017/taskmanager
jwt.secret=your_super_secret_key_here_must_be_at_least_32_chars
spring.mail.host=smtp-relay.brevo.com
spring.mail.port=587
spring.mail.username=YOUR_BREVO_SMTP_USERNAME
spring.mail.password=YOUR_BREVO_SMTP_API_KEY
app.mail.from=YOUR_VERIFIED_SENDER_EMAILcd taskmanager
# Windows
mvnw.cmd spring-boot:run
# Mac / Linux
./mvnw spring-boot:runBackend starts at http://localhost:8080
cd client
npm install
npm run devFrontend starts at http://localhost:5173
Vite automatically proxies /api β http://localhost:8080
Railway deploys directly from GitHub β no Docker installation needed on your machine.
Railway pulls code from GitHub and uses the Dockerfiles on its own servers.
Option A β Railway Plugin (easiest):
- Railway dashboard β New Project β Add Service β Database β MongoDB
- Click the MongoDB service β Variables tab β copy
MONGODB_URL
Option B β MongoDB Atlas (free):
- Go to mongodb.com/atlas β create free cluster
- Database Access β create a user (save username + password)
- Network Access β Add IP
0.0.0.0/0(allow all) - Connect β Drivers β copy the URI
Example:mongodb+srv://user:pass@cluster.mongodb.net/taskmanager
- Railway dashboard β New Project (or existing) β Add Service β GitHub Repo
- Select
23Amansharma/GetSmark---TaskManager - In service settings β set Root Directory to:
taskmanager - Go to Variables tab β add these:
| Variable | Value |
|---|---|
SPRING_PROFILES_ACTIVE |
prod |
MONGODB_URI |
(from Step 1) |
JWT_SECRET |
(any random 64+ char string) |
APP_URL |
(frontend URL β update after Step 3) |
MAIL_HOST |
smtp-relay.brevo.com |
MAIL_PORT |
587 |
MAIL_USERNAME |
(Brevo SMTP username) |
MAIL_PASSWORD |
(Brevo SMTP API key) |
MAIL_FROM |
(Brevo verified sender email) |
- Railway will detect the Dockerfile and deploy (~3-5 min for Maven build)
- Note your backend URL:
https://xxxx.railway.app
- Same Railway project β Add Service β GitHub Repo (same repo again)
- Set Root Directory to:
client - Go to Variables tab β add:
| Variable | Value |
|---|---|
VITE_API_URL |
https://your-backend.railway.app (from Step 2, no trailing slash) |
- Deploy (~2-3 min)
- Note your frontend URL:
https://xxxx.railway.app
- Backend service β Variables tab
- Update
APP_URL=https://your-frontend-url.railway.app - Backend auto-redeploys β invite emails will now have correct links β
- Open frontend URL in browser
- Signup β OTP email should arrive
- Login β Dashboard should load
- Create a project β Add a member β Check invite email
- Click invite link β Accept β member joins project β
Railway is connected to GitHub. Any git push auto-triggers redeploy:
git add .
git commit -m "your update"
git pushAll routes prefixed with /api
| Method | Endpoint | Description |
|---|---|---|
| POST | /auth/send-otp |
Send OTP for signup |
| POST | /auth/verify-otp |
Verify OTP |
| POST | /auth/complete-signup |
Create account, get JWT |
| POST | /auth/login |
Login, get JWT |
| POST | /auth/forgot-password |
Send password reset OTP |
| POST | /auth/reset-password |
Reset password with OTP |
| GET | /auth/health |
Health check (Railway uses this) |
| GET | /auth/invite-info |
Get invite details by token |
| Method | Endpoint | Description |
|---|---|---|
| GET | /projects |
My projects |
| POST | /projects |
Create project |
| GET | /projects/{id} |
Get project by ID |
| POST | /projects/{id}/members |
Add member / send invite |
| DELETE | /projects/{id}/members |
Remove member (admin) |
| GET | /projects/{id}/pending-invites |
Pending invites list (admin) |
| DELETE | /projects/{id}/pending-invites/{inviteId} |
Cancel invite (admin) |
| POST | /projects/accept-invite |
Accept invite with token |
| Method | Endpoint | Description |
|---|---|---|
| POST | /tasks |
Create task (admin) |
| GET | /tasks/project/{id} |
All tasks in a project |
| GET | /tasks/my |
My assigned tasks |
| PATCH | /tasks/{id} |
Update task (member: status only) |
| DELETE | /tasks/{id} |
Delete task (admin) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /dashboard |
Full stats and analytics |
_id, name, email, password (BCrypt), createdAt
_id, name, description, createdBy,
members: [{ userId, name, email, role }], β role: ADMIN / MEMBER
createdAt
_id, title, description, dueDate,
priority (LOW/MEDIUM/HIGH),
status (TODO/IN_PROGRESS/DONE),
projectId, assignedTo (userId), assignedToName, createdAt
_id, projectId, projectName, invitedEmail,
invitedByName, token (UUID), createdAt, expiresAt (+7 days)
(deleted when accepted or cancelled)
_id, email, otp, purpose (SIGNUP/RESET),
createdAt, expiresAt (+10 minutes)
β οΈ Important:application.propertiescontains real credentials.
Add it to.gitignorebefore pushing to a public repo.
# .gitignore
taskmanager/src/main/resources/application.propertiesAll production secrets are set via Railway Environment Variables β never hardcoded.
| Problem | Fix |
|---|---|
| OTP email not received | Check Brevo sender email is verified. Check spam folder. |
| Invite link not working | APP_URL not set correctly in Railway backend variables |
| API calls failing (local) | vite.config.js proxy must point to http://localhost:8080 |
| Railway build failing | Check Root Directory is set correctly: taskmanager for backend, client for frontend |
| MongoDB connection error | Check MONGODB_URI format. For Atlas, allow 0.0.0.0/0 in Network Access |
| 401 on all requests (prod) | JWT_SECRET env variable not set in Railway backend |
| Pending invite not visible | Only Admin can see pending invites section |
| User not in assign dropdown | Only confirmed members shown β pending invite must be accepted first |
Aman Sharma
GitHub: @23Amansharma