Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HomeFinder Portal

A full-stack real estate platform built with Spring Boot 3.3, Thymeleaf + Bootstrap 5, PostgreSQL, and Spring Security. Implements all 12 screens from the provided UI design, with full listing CRUD, role-based access control, two-factor authentication, transactional email notifications, image uploads, and a searchable audit log.


Tech Stack

Layer Technology
Backend Spring Boot 3.3 (Java 17)
Frontend Thymeleaf + Bootstrap 5 + Bootstrap Icons + Chart.js
Database PostgreSQL 14+
ORM Spring Data JPA / Hibernate
Auth Spring Security (BCrypt, form login, 2FA, role-based, single-session)
Testing JUnit 5 + Mockito + Spring Boot Test + H2 in-memory
Build Maven
Storage Cloudinary (production) / Local filesystem (development fallback)
Deployment Docker + Railway

Features

Screens (all 12 implemented)

Route Screen
/ Landing page — hero, search, features grid, stats band
/register Registration — password rules, GDPR consent, notification opt-ins
/login Login — single-session policy, 2FA flow
/listings Browse Listings — filters (location, price, type, bedrooms), sort, pagination
/listings/{id} Property Detail — gallery, agent card, inquiry & viewing modals
/saved Saved Properties — watchlist + clear all
/inquiries Inquiries & Viewings — tabbed view, KPI summary
/payment/{id} Premium Booking Payment — card / bank transfer, order summary + emailed receipt
/account/notifications Notification Preferences — GDPR-compliant toggles
/admin Admin Dashboard — KPIs, listing moderation (ADMIN)
/reports Supervisor Reports — Chart.js charts, top performers (SUPERVISOR / ADMIN)
/account Account & Privacy — profile, password, 2FA toggle, GDPR controls

Listing CRUD (/admin/listings)

Endpoint Action
GET /admin/listings/new Create form (ADMIN and AGENT)
POST /admin/listings Persist — AGENT creations land in PENDING_REVIEW; ADMIN auto-publishes
GET /admin/listings/{id}/edit Edit form with upload area and image grid
POST /admin/listings/{id} Save changes
POST /admin/listings/{id}/images Multipart image upload → Cloudinary or local /uploads
POST /admin/listings/{propertyId}/images/{imageId}/delete Remove image + delete blob
POST /admin/listings/{id}/delete Delete listing
POST /admin/listings/{id}/approve / reject Moderation (ADMIN only)

Image Storage — pluggable Strategy pattern

Cloudinary (production — backend-direct upload, secret stays server-side):

export CLOUDINARY_CLOUD_NAME=...
export CLOUDINARY_API_KEY=...
export CLOUDINARY_API_SECRET=...

Local filesystem (development fallback — works out-of-the-box, no credentials needed):

export LOCAL_UPLOAD_DIR=/var/homefinder/uploads   # optional override

Audit Log (/admin/audit)

Full searchable audit trail across authentication, user management, listing lifecycle, inquiries, payments, and image operations.

  • Filters: actor email (contains), action type, date range
  • Paginated table (25 entries/page)
  • Retention: 3 months

Events captured:

Category Events
Auth LOGIN_SUCCESS, LOGIN_FAILURE
Users USER_REGISTER, PASSWORD_CHANGE, TWO_FA_TOGGLE
Listings LISTING_CREATE, LISTING_UPDATE, LISTING_DELETE, LISTING_APPROVE, LISTING_REJECT
Interactions INQUIRY_CREATE, VIEWING_SCHEDULE, PAYMENT_PROCESS
Images IMAGE_UPLOAD, IMAGE_DELETE

Each entry records: actor email, action, target type + id, details, IP address, timestamp.

Email Notifications (Spring Mail)

EmailService sends HTML emails asynchronously (@Async / @EnableAsync):

  • Inquiry confirmation → user
  • Viewing confirmation → user
  • Payment receipt → user
  • New listing notification → subscribed users (Observer pattern)

Disabled by default — logs instead of sending. Enable with:

export MAIL_ENABLED=true
export MAIL_HOST=smtp.gmail.com
export MAIL_PORT=587
export MAIL_USERNAME=...
export MAIL_PASSWORD=...
export MAIL_FROM=no-reply@yourdomain.com

Security

  • BCrypt password hashing
  • Role-based authorization: USER, AGENT, ADMIN, SUPERVISOR
  • Mandatory two-factor authentication (2FA) via 6-digit email token
  • Single active session — new login invalidates previous session
  • CSRF enabled (Thymeleaf forms get tokens automatically)
  • @EnableMethodSecurity@PreAuthorize on sensitive controller methods

Getting Started

1. Prerequisites

  • JDK 17+
  • Maven 3.9+
  • PostgreSQL 14+

2. Create the database

CREATE USER homefinder WITH PASSWORD 'homefinder';
CREATE DATABASE homefinder OWNER homefinder;
GRANT ALL PRIVILEGES ON DATABASE homefinder TO homefinder;

Override defaults with environment variables if needed:

export DB_URL=jdbc:postgresql://localhost:5432/homefinder
export DB_USER=homefinder
export DB_PASSWORD=homefinder

3. Run

mvn spring-boot:run

App runs at http://localhost:8080.

4. Demo Accounts

The DataSeeder runs in two passes on every boot:

  • Admin bootstrap — runs every restart, never duplicates. 2FA is disabled on this account so demo logins don't require an SMTP-delivered token.
  • Demo content — runs only on a fresh install (zero properties in DB). Seeds supervisor / agent / user accounts, 2 agents, 7 properties (mixed sale/rent, one premium), 1 inquiry, and 1 viewing.
Email Password Role 2FA Notes
admin@homefinder.com Admin123! ADMIN off bootstrapped on every start
supervisor@homefinder.com Super@123 SUPERVISOR on demo seed only
agent@homefinder.com Agent@123 AGENT on demo seed only
jane.doe@example.com Demo@1234 USER on demo seed only

Override bootstrap admin without touching code:

export HOMEFINDER_ADMIN_EMAIL=you@example.com
export HOMEFINDER_ADMIN_PASSWORD='your-strong-password'

After login, users are redirected based on role:

Role Lands on
ADMIN /admin
SUPERVISOR /reports
AGENT /listings
USER /listings

Disable all seeding with homefinder.seed.enabled=false.

5. Run Tests

mvn test

Tests run against an in-memory H2 using src/test/resources/application-test.properties.

Unit Tests (no Spring context)

Area Class
Registration validation RegisterFormValidationTest
User registration service UserServiceTest
2FA token issue / verify / expiry TwoFactorServiceTest
Browse filters → repository PropertyServiceTest
Bedroom range parsing ListingBedroomFilterTest
Inquiries / viewings InquiryServiceTest
Supervisor KPI model ReportServiceTest
Local storage upload / delete LocalStorageServiceTest

Integration Tests

Area Class
JPA + public property search PropertyAndInquiryRepositoryIT
Spring context sanity check HomeFinderApplicationTests
Security / role enforcement / CSRF SecurityIntegrationTest

Surefire reports: target/surefire-reports/ after mvn test.

6. Package as JAR

mvn clean package
java -jar target/homefinder.jar

Project Structure

homefinder/
├── pom.xml
├── README.md
├── TESTING.md
└── src/
    ├── main/java/com/homefinder/
    │   ├── HomeFinderApplication.java
    │   ├── config/         (SecurityConfig, StorageConfig, AsyncConfig, DataSeeder)
    │   ├── controller/     (HomeController, AuthController, ListingController, ...)
    │   ├── dto/            (RegisterForm, ListingForm, PropertySearchCriteria, ...)
    │   ├── entity/         (User, Property, Inquiry, Viewing, Payment, AuditLog, ...)
    │   ├── repository/     (Spring Data JPA interfaces)
    │   ├── security/       (CustomUserDetailsService, TwoFactorAuthenticationSuccessHandler)
    │   └── service/        (UserService, PropertyService, TwoFactorService, AuditService, ...)
    │       ├── observer/   (PropertyObserver, PropertySubject, NewListingEmailObserver)
    │       └── storage/    (StorageService, CloudinaryStorageService, LocalFilesystemStorageService)
    ├── main/resources/
    │   ├── application.properties
    │   ├── static/         (css/, js/, img/)
    │   └── templates/      (12 Thymeleaf views)
    └── test/java/com/homefinder/

Design Patterns

Pattern Implementation Purpose
Observer PropertySubjectPropertyObserverNewListingEmailObserver Automated email notifications on new listings (RE-10)
Strategy StorageServiceCloudinaryStorageService / LocalFilesystemStorageService Pluggable image storage selected at runtime
Singleton AuditService (@Service Spring bean) Centralised audit logging with 3-month retention (RE-14)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages