Graduation Thesis Project · Hanoi University of Architecture

Scientific Staff Research
Management System

A microservice-based platform built for academic research management — covering staff profiles, research registration, approval workflows, and real-time notifications.

Microservice Apache Kafka Redis PostgreSQL Docker Next.js React Native Socket.io JWT · RBAC · ABAC Cloudflare R2 GitHub Actions CI
0
Microservices
0
Kafka Topics
0
Isolated DBs
0
Client Platforms
Explore
📋

Project Note: This project is currently maintained as a private repository because it will be submitted for official academic evaluation as part of my graduation thesis. To provide recruiters and collaborators with an overview of the work, this showcase presents the system architecture, technologies, and core features without exposing the source code.

System Architecture

A layered architecture with a single entry point — Nginx as the sole internet-facing gateway, routing requests through an API Gateway to four independent microservices, each owning its own database.

🏗️
4-Layer Architecture Overview
Client → Nginx → API Gateway → Services → Data
System architecture diagram

The system is organised into three functional tiers plus one entry layer. The Client tier consists of a Next.js web application and a React Native mobile app — both access the system exclusively through an Nginx Reverse Proxy that handles HTTPS termination (Let's Encrypt), port 80/443, and acts as the sole internet-facing exposure point. Behind Nginx sits the API Gateway (Express, port 3000), which owns all cross-cutting concerns: request routing, JWT validation, RBAC permission checks, and rate limiting. The Business tier comprises four independently deployable microservices — Auth, Staff, Research, and Notification — running on ports 3001–3004. The Data tier follows a strict Database-per-Service pattern: each service owns a private PostgreSQL instance, enforcing complete data isolation.

⚠️ Currently deployed locally via Docker Compose — Nginx + VPS layer is planned for post-thesis production deployment
Nginx · Let's Encrypt JWT Validation RBAC + ABAC Rate Limiting DB per Service

Shared Infrastructure

Cross-service infrastructure components — event backbone, caching, file storage, email delivery, and real-time channels — that are shared across the system but kept outside any single service's domain.

⚙️
Shared Infrastructure Components
Kafka · Redis · Cloudflare R2 · Gmail SMTP · Socket.io
Shared infrastructure diagram

Apache Kafka serves as the system's event backbone. Three services — Auth, Staff, and Research — act as event publishers; Notification Service is the sole consumer, processing all incoming events to dispatch alerts. Redis is shared between Auth Service (storing refresh tokens, password-reset tokens, and login lock counters) and Notification Service (caching unread notification counts per user). Cloudflare R2 — S3-compatible object storage — holds research paper PDFs and staff avatar images, keeping binary assets out of PostgreSQL. Gmail SMTP is used exclusively by Notification Service to send transactional emails for significant system events. Finally, Socket.io maintains bidirectional connections from Notification Service to all connected clients, enabling real-time push notifications and force_logout events when an account is locked or revoked.

Kafka Producer × 3 Kafka Consumer × 1 Redis — Auth + Notif R2 Object Storage Socket.io Real-time Transactional Email

Kafka Event Flow

13 Kafka topics, each mapping to one business event type — named in kebab-case following <entity>-<action> convention, declared centrally in topics.ts, and referenced uniformly by all producers and the single consumer.

13 Business Event Topics
topics.ts · kebab-case · <entity>-<action>
Kafka event flow diagram

The system defines 13 Kafka topics, each corresponding to exactly one business event type. Topics follow the kebab-case convention with the structure <entity>-<action> — for example research-approved or user-blocked — so that each topic name is self-documenting and debuggable without needing supplementary docs. All topics are declared in a single topics.ts file owned by Notification Service. The three producer services (Auth, Staff, Research) import constants from this file, ensuring naming consistency across the entire event mesh. Notification Service, as the sole consumer, subscribes to all 13 topics and maps each to the appropriate notification handler.

research-approved research-rejected user-blocked staff-updated + 9 more topics topics.ts — single source of truth

Feature Showcase

A selection of key screens from the web interfaces. Full source code is not publicly available pending the official academic defence.


Technical Highlights

Key architectural and engineering decisions that shaped the system.

🧩
Microservice Architecture
Four independently deployable services — Auth, Staff, Research, Notification — each with its own codebase and deployment unit.
Event-Driven via Kafka
13 business-event topics enable fully decoupled communication — producers emit, Notification Service reacts.
🔐
JWT + RBAC + ABAC
Layered authorisation: role-based checks at the Gateway, attribute-based checks within each service for fine-grained resource control.
📦
Database per Service
Complete data isolation — each PostgreSQL instance is private to its service, preventing cross-service data coupling.
🔴
Redis Token Management
Refresh tokens, password-reset tokens, and login lock counters stored in Redis for fast, TTL-aware in-memory access.
🐳
Dockerised + CI Pipeline
All services run in Docker Compose locally. A GitHub Actions pipeline automates linting and build checks on every push.
📡
Real-time with Socket.io
Bidirectional channels push live notifications and force_logout commands to connected clients without polling.
☁️
Cloudflare R2 Storage
S3-compatible object storage for research PDFs and staff avatars — offloading binary assets from relational databases.
📱
Cross-platform Client
Next.js web admin and a React Native Expo mobile app share the same API Gateway interface, covering web and iOS/Android.