The Hub backend is built using hexagonal architecture (Ports and Adapters) with clearly separated modules. Each module is organized into domain, application, and infrastructure layers.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ccasro/hub/llms.txt
Use this file to discover all available pages before exploring further.
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