Architecture Overview
The backend follows Domain-Driven Design (DDD) principles with hexagonal architecture:- Domain Layer: Contains business logic, entities, value objects, and domain ports
- Application Layer: Orchestrates use cases and defines DTOs/commands
- Infrastructure Layer: Implements adapters for persistence, APIs, and external services
All modules are located in
backend/src/main/java/com/ccasro/hub/modules/Core Technology Stack
Framework
Spring Boot 3.5.10
Language
Java 21
Database
PostgreSQL with PostGIS
ORM
Spring Data JPA + Hibernate Spatial
Module Structure
Each module follows a consistent structure:Modules
Booking Module
Booking Module Details
Booking Module Details
Purpose: Manages court bookings and payment processingLocation:
modules/booking/Domain Entities:Booking- Core booking aggregate with lifecycle managementPayment- Payment tracking and status
BookingId,PaymentIdBookingStatus- PENDING_PAYMENT, CONFIRMED, CANCELLED, PENDING_MATCHPaymentStatus- PENDING, PAID, FAILED, REFUNDED
BookingConfirmedEventBookingCancelledEventBookingExpiredEvent
CreateBookingService- Create new bookings with payment holdsConfirmBookingPaymentService- Confirm payment and activate bookingCancelBookingService- Handle user-initiated cancellations (24h rule)AdminBookingService- Admin override for cancellationsExpirePaymentHoldsJob- Background job to expire unpaid bookingsGetMyBookingsService- Retrieve user’s bookingsGetOwnerBookingsService- Retrieve owner’s venue bookings
- Bookings must be paid within hold duration (configurable)
- Cancellations require 24 hours notice for refunds
- Slot overlap prevention (enforced at database level)
- Match bookings have different lifecycle (PENDING_MATCH status)
BookingRepositoryPort- Booking persistencePaymentRepositoryPort- Payment persistencePaymentPort- External payment provider integrationResourceValidationPort- Validate resource availabilityBookingNotificationPort- Send booking notifications
Venue Module
Venue Module Details
Venue Module Details
Purpose: Manages padel venues owned by venue operatorsLocation:
modules/venue/Domain Entities:Venue- Venue aggregate with location and imagesVenueImage- Venue photos with ordering
VenueId,VenueNameAddress- Street, city, country, postal codeCoordinates- Latitude/longitude for geographic queriesVenueStatus- PENDING_REVIEW, ACTIVE, REJECTED, SUSPENDED
CreateVenueService- Register new venue (requires approval)UpdateVenueService- Modify venue detailsGetVenueService- Public venue detailsGetMyVenuesService- Owner’s venue listSearchVenuesService- Geographic and filter-based searchVenueImageService- Manage venue images- Admin approval/rejection workflows
- Venues require admin approval before going public
- Only owners can modify their venues
- Updates to active venues trigger re-review
- Geographic search uses PostGIS
VenueRepositoryPort- Venue persistence with geo queries
Resource Module
Resource Module Details
Resource Module Details
Purpose: Manages bookable resources (courts) within venuesLocation:
modules/resource/Domain Entities:Resource- Court/facility aggregateDaySchedule- Operating hours per day of weekResourceImage- Resource photos
ResourceId,ResourceNameResourceType- PADEL_COURT, TENNIS_COURT, etc.ResourceStatus- PENDING_REVIEW, ACTIVE, REJECTED, SUSPENDEDSlotDuration- Booking slot length (e.g., 60, 90 minutes)SlotRange- Start and end times for a booking slotPriceRule- Dynamic pricing by day type and time rangeDayType- WEEKDAY, WEEKEND, MONDAY, TUESDAY, etc.DayOfWeek- Business enum for days
CreateResourceService- Add new court to venueUpdateResourceService- Modify resource detailsGetResourceService- Public resource detailsSearchResourcesService- Find available courtsGetAvailabilityService- Get available slots for a dateManageScheduleService- Set opening/closing hoursManagePricingService- Configure dynamic pricing rules- Admin approval workflows
- Resources belong to exactly one venue
- Schedules define availability by day of week
- Pricing rules support time-based and day-type variations
- Slot generation based on schedule and duration
- Resources require admin approval
ResourceRepositoryPort- Resource persistenceBookedSlotsPort- Query booked time slotsSlotAvailabilityPort- Check slot availabilityResourceCountPort- Statistics queries
Matching Module
Matching Module Details
Matching Module Details
Purpose: Facilitates finding and organizing matches with other playersLocation:
modules/matching/Domain Entities:MatchRequest- Match organization aggregateMatchPlayer- Player participation in matchMatchInvitation- Invitation to join match
MatchRequestId,InvitationTokenMatchStatus- AWAITING_ORGANIZER_PAYMENT, OPEN, FULL, CANCELLED, EXPIREDMatchFormat- SINGLES, DOUBLES (defines team structure)MatchSkillLevel- BEGINNER, INTERMEDIATE, ADVANCEDPlayerRole- ORGANIZER, GUESTPlayerTeam- TEAM_A, TEAM_BGeoPoint- Search center coordinatesMatchInvitationStatus- PENDING, ACCEPTED, DECLINED
MatchFullEvent- Triggered when match reaches capacityMatchInvitationsEvent- Sent to eligible players
CreateMatchRequestService- Organize new matchJoinMatchService- Join an open matchLeaveMatchService- Leave before match startsCancelMatchService- Cancel match (organizer only)InvitePlayersService- Send invitations to eligible playersRespondToInvitationService- Accept/decline invitationCheckInService- Player check-in at venueReportAbsenceService- Report no-show playerFindEligiblePlayersService- Geographic and skill-based matchingExpireMatchRequestsJob- Auto-expire old matches
- Organizer pays first, then match opens to players
- Geographic radius search for nearby players
- Skill level filtering for balanced matches
- Team assignment (singles: all TEAM_A, doubles: A/B split)
- Cooldown period between match creations
- Max active matches per user
- No-show tracking and banning system
- Match closes 24 hours before start time
MatchFullException,TeamFullExceptionPlayerAlreadyJoinedExceptionMatchCreationCooldownExceptionTooManyActiveMatchesExceptionPlayerMatchBannedExceptionPlayerTimeConflictException
MatchRequestRepositoryPort- Match persistenceMatchInvitationRepositoryPort- Invitation trackingEligiblePlayerPort- Find matching players by criteriaMatchNotificationPort- Send match notifications
IAM Module
IAM Module (Identity & Access Management) Details
IAM Module (Identity & Access Management) Details
Purpose: User profile management and authentication integrationLocation:
modules/iam/Domain Entity:UserProfile- User account and preferences
Auth0Id- External identity provider IDEmail,DisplayName,PhoneNumberSkillLevel- BEGINNER, INTERMEDIATE, ADVANCEDSportPreference- PADEL, TENNIS, SQUASH, BADMINTONOwnerRequestStatus- NONE, PENDING, APPROVED, REJECTED
GetOrCreateUserService- Sync with Auth0 on loginUpdateProfileService- Edit profile informationUploadAvatarService- Change profile pictureRequestOwnerRoleService- Request venue owner privilegesGetUserStatsService- Retrieve user statistics- Admin user management (approve owner requests, ban users)
- Users auto-created on first Auth0 login
- Default role: PLAYER
- Owner role requires admin approval
- Onboarding completed when display name and city set
- No-show tracking for match reliability
- Temporary bans after 3 no-shows (30 days)
- Match notification preferences
UserProfileRepositoryPort- User persistenceUserStatsPort- Aggregated statistics
Media Module
Media Module Details
Media Module Details
Purpose: Centralized media upload and managementLocation:
modules/media/Domain Value Objects:UploadContext- Context information for uploadsUploadPurpose- VENUE_IMAGE, RESOURCE_IMAGE, USER_AVATAR
UploadImageService- Upload to cloud storage (Cloudinary)DeleteImageService- Remove from cloud storage- Image validation and optimization
- Cloudinary integration for CDN delivery
- Image transformation and optimization
- Purpose-based upload policies
- Public ID management for deletion
cloudinary-http5library
Admin Module
Admin Module Details
Admin Module Details
Purpose: Administrative operations and dashboard statisticsLocation:
modules/admin/Use Cases:GetAdminStatsService- Dashboard metrics- Admin actions for venue/resource approval
- User management operations
- Platform-wide statistics aggregation
- Cross-module administrative operations
- Approval workflows for content moderation
AdminStatsPort- Aggregate statistics from all modules
Security Module
Security Module Details
Security Module Details
Purpose: Authentication and authorization configurationLocation:
modules/security/Key Components:- JWT token validation (Auth0 integration)
- Spring Security configuration
- Role-based access control (PLAYER, OWNER, ADMIN)
- Method-level security annotations
- Frontend obtains JWT from Auth0
- Backend validates JWT signature and claims
- User profile loaded/created on first access
- Security context populated with user details
@PreAuthorizeannotations on endpoints- Role hierarchy: ADMIN > OWNER > PLAYER
- Resource ownership checks in services
Cross-Cutting Concerns
Shared Domain
Location:
shared/domain/UserId- User identifier (UUID)ImageUrl- Image URL with public IDCountryCode- ISO country codesUserRole- PLAYER, OWNER, ADMINMoneyUtils- Currency and decimal handling
Event-Driven Communication
Modules communicate via:- Domain Events - Published after successful transactions
- Application Events - Spring’s event publishing mechanism
- Ports - Cross-module dependencies via interfaces
Data Consistency
Strategies used:- Database constraints (foreign keys, exclusion constraints)
- Domain-level validation in aggregates
- Optimistic locking for concurrent updates
- Transactional boundaries at use case level
Ports and Adapters
The hexagonal architecture uses ports and adapters to maintain separation:Related Documentation
Domain Model
Deep dive into domain entities and value objects
Database Schema
Complete database structure and migrations