RMIT University — ISYS2101 Software Engineering Project Management
A social networking web application that helps young Vietnamese people find compatible roommates and safe, transparent shared housing — powered by AI compatibility matching and real-time communication.
- Overview
- Live Demo
- Team
- Features
- System Architecture
- Tech Stack
- API Documentation
- Getting Started
- Individual Contributions — Backend Lead
- Project Management
- Reflections
- Links
Broomate is a full-stack social networking website addressing a critical gap in Vietnam's shared rental market, where rental and deposit fraud has caused losses exceeding 5 billion VND. The platform provides a safe, transparent, and informative space for young people to:
- Find compatible roommates through AI-assisted compatibility testing (Gemini LLM)
- Browse verified room listings with AI-powered image fraud detection (Google Vision API)
- Communicate in real time via WebSocket-based messaging and group chats
- Make informed decisions through structured profiles, compatibility scores, and direct landlord contact
The project was delivered as a fully functional MVP within 12 weeks using a hybrid Waterfall-Scrum methodology, achieving an HD grade of 92.
| # | Name | Student ID | Role |
|---|---|---|---|
| 1 | Tran Dang Duong | S3979381 | Team Lead + Backend Developer |
| 2 | Jay Kim | S3726103 | Frontend Developer |
| 3 | Nguyen Pham Tan Hau | S3978175 | Backend Developer |
| 4 | Nguyen Doan Trung Truc | S3974820 | Fullstack / AI Integration |
Course: ISYS2101 Software Engineering Project Management
Lecturer: Ms. Anna Lyza Felipe | Class: Tut 01 — Monday 8:00–11:00, SGS
| Feature | Description |
|---|---|
| Secure Registration | Tenants and landlords register separately with role-specific onboarding flows |
| JWT Authentication | Stateless login with Spring Security + JWT; sessions secured throughout |
| Role-Based Access | RBAC enforces strict access boundaries between Tenant, Landlord, and Admin roles |
| Profile Management | Users update name, avatar, preferences, budget, location, and stay duration |
| Feature | Description |
|---|---|
| Profile Browsing & Swiping | Browse tenant profiles one at a time; swipe right (like) or left (skip) |
| AI Compatibility Check | Gemini LLM generates culturally aware lifestyle questions based on both users' profiles |
| Compatibility Scoring | System calculates and displays a compatibility score with a short explanation before the final swipe decision |
| Connection Approval | Mutual likes unlock a private 1-to-1 messaging channel |
| Feature | Description |
|---|---|
| Room Search & Filtering | Browse available rooms; filter by price range, district, stay length, and amenities |
| Room Detail View | Full room page with verified photos, pricing, location, and landlord contact |
| Bookmarking | Save and compare rooms for later review |
| Landlord Room Management | Landlords create, edit, and manage listings through a structured dashboard |
| AI Image Verification | Google Vision API detects fake, duplicate, internet-stolen, or AI-generated room photos |
| Feature | Description |
|---|---|
| 1-to-1 Messaging | Real-time private chat between matched tenants via WebSocket |
| Group Chat | Automatically created when two connected tenants both bookmark the same room — includes the landlord |
| Media Sharing | Exchange images and videos within defined size limits |
| Sub-1-second Delivery | WebSocket implementation achieves message delivery under 1 second |
| Notification System | Real-time notifications for new messages and connections |
┌─────────────────────────────────────────────────────────────────┐
│ CLIENT LAYER │
│ React (Vercel) — Responsive Web App │
└──────────────────────┬──────────────────────────────────────────┘
│ HTTPS (REST) + WebSocket
┌──────────────────────▼──────────────────────────────────────────┐
│ SERVER LAYER │
│ Java Spring Boot (Render Cloud Platform) │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌───────────────────────┐ │
│ │ Spring │ │ Swagger UI │ │ WebSocket │ │
│ │ Security │ │ API Docs │ │ (Real-time Messaging) │ │
│ │ JWT + RBAC │ │ │ │ │ │
│ └─────────────┘ └──────────────┘ └───────────────────────┘ │
└───────┬───────────────────────┬─────────────────────────────────┘
│ │
┌───────▼──────────┐ ┌────────▼──────────────────────────────┐
│ Firebase │ │ External AI Services │
│ Firestore │ │ ┌──────────────┐ ┌───────────────┐ │
│ (NoSQL DB) │ │ │ Gemini LLM │ │ Google Vision │ │
│ │ │ │ (Compat.) │ │ API (Images) │ │
│ Profiles, │ │ └──────────────┘ └───────────────┘ │
│ Matches, │ └───────────────────────────────────────┘
│ Messages │
└──────────────────┘ ┌───────────────────────────────────────┐
│ Supabase Storage │
│ (Media files — images, videos, │
│ documents via cloud bucket) │
└───────────────────────────────────────┘
- Stateless REST API on Spring Boot enables horizontal cloud scaling
- WebSocket handles all real-time messaging — bypassing REST overhead for low-latency delivery
- Firestore (NoSQL) chosen for its real-time sync capabilities and flexible schema for profiles, matches, and conversations
- Supabase storage bucket separates media from structured data to keep DB lean
- Swagger serves as the API contract between FE and BE teams, enforced from the start to prevent integration drift
- Environment variable configuration distinguishes dev vs. production — different API keys, CORS origins, and Firestore projects per environment
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | React, Vercel | Responsive UI, cloud deployment |
| Backend | Java Spring Boot | REST API server, business logic |
| Authentication | Spring Security + JWT | Stateless auth, RBAC enforcement |
| Database | Firebase Firestore (NoSQL) | Profiles, matches, messages, rooms |
| Media Storage | Supabase Cloud Bucket | Images, videos, documents |
| Real-Time | WebSocket (STOMP) | Messaging, notifications |
| AI — Compatibility | Google Gemini LLM API | Culturally aware compatibility questions |
| AI — Image Verification | Google Vision API | Fake/duplicate photo detection |
| API Documentation | Swagger / OpenAPI | FE-BE contract, dev documentation |
| Testing | JUnit + Mockito | Unit tests for profile matching algorithm |
| Hosting — Backend | Render | Spring Boot cloud deployment |
| Project Management | Jira (Scrum) | Sprint planning, burndown tracking |
| Design | Figma | UI/UX wireframes and prototypes |
Full Swagger API documentation is available at the backend server endpoint:
GET /swagger-ui/index.html
The API is organised around the following resource groups:
/auth— Registration, login, JWT token management/users— Profile CRUD, preferences, avatar upload/rooms— Room listing CRUD, filtering, bookmarking/matches— Swipe actions, compatibility scoring, connection management/messages— Chat history, group chat creation/ai— Compatibility question generation, image verification
All endpoints require a valid Bearer <JWT> header except public auth routes.
- Java 17+
- Maven 3.8+
- Node.js 18+ (for frontend)
- Firebase project with Firestore enabled
- Supabase project with storage bucket configured
# Clone the repository
git clone https://github.com/RMIT-Vietnam-Teaching/SEPM.git
cd SEPM/backend
# Configure environment variables
cp .env.example .env
# Fill in: FIREBASE_CREDENTIALS, SUPABASE_URL, SUPABASE_KEY,
# GEMINI_API_KEY, GOOGLE_VISION_KEY, JWT_SECRET
# Run in development mode
mvn spring-boot:run -Dspring.profiles.active=dev
# Run in production mode
mvn spring-boot:run -Dspring.profiles.active=prodcd SEPM/frontend
npm install
npm run dev # Development
npm run build # Production build| Variable | Dev | Prod |
|---|---|---|
CORS_ORIGIN |
http://localhost:3000 |
https://broomate2211.vercel.app |
FIREBASE_PROJECT |
broomate-dev |
broomate-prod |
LOG_LEVEL |
DEBUG |
WARN |
API_BASE_URL |
http://localhost:8080 |
Render backend URL |
Name: Tran Dang Duong (S3979381)
Role: Team Lead + Backend Developer
GitHub: github.com/RMIT-Vietnam-Teaching/SEPM
Period: October 2025 – January 2026
Architected and developed the core backend using Java Spring Boot, designing a clean layered structure (Controller → Service → Repository) that the entire team built on. Defined the API contract via Swagger/OpenAPI from day one, enabling the frontend team to mock and develop UI flows before backend endpoints were complete — significantly reducing integration delays.
Key API responsibilities:
- Designed and implemented all RESTful endpoints across auth, profiles, rooms, matches, and messaging resources
- Enforced consistent request/response schemas and HTTP status codes across the API surface
- Handled all server-side input validation and error response formatting
Implemented the complete authentication and authorisation system:
- JWT-based stateless auth — users receive a signed token on login, validated on every protected request without server-side session storage
- Spring Security filter chain — custom
OncePerRequestFilterextracts and validates JWT from theAuthorization: Bearerheader - Role-Based Access Control (RBAC) —
TENANT,LANDLORDroles enforced at the endpoint level using@PreAuthorizeannotations and Spring Security method security - Password encryption — BCrypt hashing for all stored credentials
- Edge cases handled: token expiry, invalid signature, missing roles, concurrent login invalidation
Utilised Firebase Firestore to handle all dynamic, relationship-heavy data:
- Designed Firestore collection/document schemas for users, rooms, swipe history, match records, and chat messages
- Implemented complex Firestore queries: compound filtering (e.g., available rooms by district + price range), subcollection traversal for message threads, and batch writes for atomic match creation
- Managed Firestore security rules to enforce data access by authenticated user UID
- Handled Firestore's eventual consistency model in the matching and chat flows
Implemented full-duplex WebSocket communication using Spring's STOMP support:
- Configured
WebSocketMessageBrokerConfigurerwith STOMP endpoint and message broker - Topic-based routing:
/topic/chat/{roomId}for group chats,/user/{userId}/queue/messagesfor private messages - Integrated real-time notifications for new messages and connection requests
- Achieved sub-1-second message delivery in testing under normal load
- Implemented graceful fallback and reconnection handling on the backend
Managed all media file operations via Supabase Storage:
- Implemented file upload pipeline: receive multipart file → validate type/size → upload to Supabase bucket → store public URL in Firestore
- Enforced file type allowlisting and filename sanitisation to prevent malicious uploads
- Configured bucket policies to separate tenant media, landlord room photos, and document attachments into logical prefixes
- Handled presigned URL generation for time-limited secure access
Wrote unit tests focused on the profile matching algorithm:
- Tested compatibility score calculation logic with mocked user preference inputs
- Used Mockito to mock Firestore and Gemini API responses, isolating the scoring logic from external dependencies
- Validated edge cases: identical profiles, completely opposing preferences, missing preference fields
@Test
void testCompatibilityScore_shouldReturnHighScore_whenPreferencesMatch() {
UserProfile userA = mockProfile("HCMC", 3_000_000L, "non-smoker");
UserProfile userB = mockProfile("HCMC", 2_800_000L, "non-smoker");
when(geminiService.generateQuestions(any(), any())).thenReturn(mockQuestions);
int score = matchingService.calculateCompatibility(userA, userB);
assertThat(score).isGreaterThanOrEqualTo(80);
}Configured Spring Profiles to distinguish dev and production environments:
- Separate
application-dev.propertiesandapplication-prod.propertieswith environment-specific values - Externalised all secrets (API keys, JWT secret, Firebase credentials) as environment variables — never hardcoded
- Configured CORS allowed origins per profile to prevent cross-origin issues in both local and deployed environments
- Set log levels and Firestore project targets per profile
- Maintained the Jira sprint board — created tickets, assigned story points, tracked burndown
- Led daily Scrum standups and weekly sprint review meetings with stakeholders
- Defined and enforced Git branching strategy (feature branches → PR → team lead review → main)
- Acted as Product Owner — maintained the product backlog and prioritised features using MoSCoW
- Coordinated FE-BE integration sessions to resolve API contract disputes early
- Managed scope and re-planned sprints when AI API limitations or deployment issues arose
- Waterfall phase (Weeks 1–2): Full planning, requirements analysis, UI/UX design, architecture design, and documentation
- Scrum phase (Weeks 3–12): 9 weekly sprints with daily standups, sprint reviews, and stakeholder demos
The project was completed 1 week ahead of schedule (January 5, 2026 vs. planned January 12). The burndown chart consistently tracked at or below the ideal line, with a brief plateau in early sprints during architecture spike investigations.
17 risks were identified and tracked throughout the project. Key risks that occurred and were mitigated:
| Risk | Outcome |
|---|---|
| FE-BE Integration Delay | Mitigated via Swagger API-first contract |
| AI LLM Policy Rejection | Mitigated via prompt engineering + rule-based fallback |
| Deployment Environment Conflict | Mitigated by switching from AWS to Render/Vercel |
| Sprint Overcommitment | Mitigated via velocity-based planning and WIP limits |
| Key Person Dependency | Mitigated via shared documentation and task redistribution |
- All core MVP features delivered within 12 weeks with a grade of HD 92
- AI integration (Gemini compatibility + Google Vision image verification) elevated the product significantly
- Swagger-first API development dramatically reduced FE-BE integration friction
- WebSocket messaging achieved the sub-1-second delivery target
- Hybrid methodology balanced planning rigour with sprint flexibility effectively
- Initial AWS deployment configuration proved too complex within budget constraints — migrated to Render/Vercel, which resolved the issue with minimal delay
- Inconsistent coding conventions across team members added code review overhead
- Free-tier API rate limits required careful usage monitoring and caching strategies
- Centralised user action history (currently device-bound via Firestore queries)
- Real-time dashboard updates without manual refresh
- Encrypted password storage for landlord accounts (plaintext is a known gap in the current MVP)
- AI-based chat content moderation (deferred due to privacy concerns and cost)
- Booking and rental agreement system for end-to-end rental flow
- Push notifications for mobile
| Resource | Link |
|---|---|
| 🌐 Live Application | broomate2211.vercel.app |
| 📁 GitHub Repository | RMIT-Vietnam-Teaching/SEPM |
| 🎥 Video Presentation | YouTube |
| 📐 Application Flow Diagram | Google Drive |
| 🏗️ Software Architecture Diagram | Draw.io |
| 📋 Work Breakdown Structure | Draw.io |
| 📊 Jira Sprint Board | Jira |
| 🎨 Figma UI/UX Design | Figma |
| 📊 Use Cases Diagram | Draw.io |
| 🗺️ Context Diagram | Draw.io |
RMIT University · ISYS2101 Software Engineering Project Management · HD 92
Built with Java Spring Boot, React, Firebase, WebSocket, and a lot of sprint planning.