Capstone Project Blueprints

Project Blueprints

Weak academic projects are the #1 resume rejection reason. Each blueprint gives the architecture, an 8-week build plan, ATS bullets with metric slots, and the defence answers interviewers probe.

CSE / IT

Enterprise Task Management System with RBAC, Microservices & Redis Caching

Hiring managers reject toy CRUD apps. This project demonstrates the three things service and product interviews probe: authorisation design, service decomposition, and cache-aware data access — all defensible at depth.

System architecture

architecture
[Client SPA]
     │ HTTPS
[API Gateway / Nginx]
     ├── auth-service (JWT issue/verify, refresh rotation)
     ├── task-service (CRUD, filters, assignments) ── Redis (lists, hot queries)
     ├── notification-service (email on assignment) ← queue
     └── audit-service (immutable activity log)
            └── all services → PostgreSQL (per-service schemas)

Data flow

Login → auth-service verifies credentials, issues short-lived JWT + refresh cookie. Client calls task-service with Bearer token; gateway verifies signature only (no DB hit). Task reads check Redis first (list cache keyed by user+filter, TTL 60s, invalidated on write). Assignment events publish to a queue consumed by notification-service. All state changes append to audit-service.

Stack & standards

Backend: Node.js/NestJS or Spring Boot · PostgreSQL · Redis · RabbitMQ/Redis Streams

Auth: JWT access (15 min) + refresh rotation · bcrypt password hashing · Role model: admin / manager / member

Infra: Docker Compose · GitHub Actions CI · Nginx gateway

Standards: OWASP Top 10 (auth, injection, session) · JWT best practices (RFC 7519) · RBAC per NIST model

Implementation milestones

Weeks 1–2 — Domain & auth core

  • Schema: users, teams, tasks, assignments, audit_log
  • auth-service with signup/login/refresh
  • Role model + guards/middleware

Weeks 3–4 — Task service

  • CRUD + filters (status, assignee, due date)
  • Assignment flow + notifications via queue
  • Pagination + indexes on (assignee, status)

Weeks 5–6 — Cache & hardening

  • Redis list caching with write-through invalidation
  • Rate limiting, input validation, audit trail
  • Load test (k6) and fix the top bottleneck

Weeks 7–8 — Ship & document

  • Dockerise all services
  • CI pipeline: lint → test → build → push images
  • README with architecture diagram + trade-offs

ATS resume bullets (copy with your real numbers)

Designed and implemented a 3-service task platform (NestJS + PostgreSQL + Redis) with role-based access control, reducing unauthorised-access surface by enforcing server-side permission checks on every route.

Cut p95 task-list latency 4× (380ms → 95ms) by caching filtered lists in Redis with write-through invalidation.

Built JWT access/refresh rotation with revocation, eliminating the session-fixation class of bugs found in the first security review.

Containerised the stack with Docker Compose and a GitHub Actions pipeline running lint, unit and integration tests on every push.

Load-tested with k6 at 200 rps, identified a missing composite index, and reduced DB CPU from 85% to 30%.

Top 5 interview defence questions

Why microservices for a student project — isn't that overkill?

It is, at this scale — and I say so. I kept three services only because auth, tasks and notifications have different scaling and failure modes (auth is CPU-light but security-critical; notifications are bursty). The honest answer plus the isolation reasoning scores better than pretending it's mandatory.

How do you prevent privilege escalation between roles?

Authorisation is enforced server-side per route via guards that resolve the role from the verified JWT — never from the request body. Managers can assign but not delete; deletion is admin-only and audit-logged.

Why cache lists and not individual tasks?

Reads are filter-shaped (my open tasks, team's overdue), so I cache at the query level. Individual task reads hit a primary-key lookup which is already fast. Invalidation on any write touches the affected user's list keys.

What happens if Redis dies?

The app degrades, not fails: reads fall through to PostgreSQL, writes continue, latency rises. Cache failure must never break correctness — that invariant drove the cache-aside choice.

How are JWTs revoked before expiry?

Access tokens aren't revoked (short 15-min life bounds the damage); refresh tokens are rotated and the old one is denylisted in Redis. Logout revokes the refresh chain.

Building it? Keep a decision log from day one — every "why did you choose X?" answer lives in it. Then practise the defence questions aloud before the AI mock interview.