System Architecture

The Leisure Bible — Platform Overview · v2 (June 2026)

Geocoding consolidated: RoutePlanner previously duplicated geocode() locally. Now uses geocodeAddress() from listingService — single Nominatim caller across all map features.
Auth hook canonical: useCurrentUser lives in src/lib/useCurrentUser.js; src/hooks/useCurrentUser.js re-exports it. All 30+ consumers use one implementation.
Notification system unified: bookingService.notify.send() and businessService.comms.markNotificationRead() both write to the single Notification entity — no parallel notification stores.
Admin pages consolidated: /admin/users, /admin/revenue, /admin/content now redirect to /admin?panel=X — all management surfaces live inside the Control Centre shell.
Service layer discipline: listingService, bookingService, businessService, marketplaceService, contentService each own their domain — no cross-domain entity calls from pages.
Denormalised counters (average_rating, review_count, listing_count) must be updated via service layer after mutations; no automatic triggers exist in a BaaS model — document all mutation sites.
BookingAvailability can grow unbounded at 1 record/listing/date — paginate writes via bulkCreate batches; filter queries by date range, not full table scans.
Scalability ceiling: Base44 entity filter() caps at 500 records per call. Queries with no selectivity (no filter field) on large entities (Listing, Booking, BusinessAnalytics) must specify date/owner filters at all times.
Security: all admin panels gate on user.role === 'admin' checked client-side. Base44 RLS enforces created_by_id at the data layer — admin-only entities should use service-role calls from backend functions for write operations.

The Leisure Bible is a React 18 SPA on Vite, backed entirely by Base44 BaaS. There is no custom backend server. All entity access is mediated through dedicated service modules — pages and components never call base44.entities directly.

Client Layer — Browser / PWA / Mobile
  • React 18 SPA (Vite) — 37 routes across src/pages/
  • React Router v6 — public | auth | business+ | admin tiers
  • TanStack Query — server state, caching, background refetch
  • Tailwind CSS + shadcn/ui — unified design system
  • Framer Motion — page transitions & micro-animations
  • Leaflet / react-leaflet — interactive maps (OSM tiles)
  • Recharts — analytics & revenue dashboards
HTTPS / Base44 SDK calls
Base44 BaaS Layer
  • Auth — email+OTP, Google OAuth, JWT sessions
  • Entity Service — hosted NoSQL JSON-schema DB (MongoDB-style queries)
  • File Storage — public & private upload (UploadFile / UploadPrivateFile)
  • AI — InvokeLLM (GPT-4o / Gemini / Claude), GenerateImage, GenerateSpeech, GenerateVideo, TranscribeAudio
  • Real-time — WebSocket entity subscriptions (Entity.subscribe)
  • Email — transactional SendEmail (booking confirms, team invites)
  • Analytics — base44.analytics.track() custom event tracking
Internal
Data Layer — 34 Entities across 7 Domain Groups
  • Core: User (built-in), Listing, Category, UserProfile
  • Reviews & Community: Review, Post, Question, Answer, Trip, Favourite, UserBadge, HelpfulVote, PostInteraction
  • Bookings: Booking, BookingConfig, BookingAvailability
  • Business Hub: BusinessProfile, BusinessSubscription, BusinessAnalytics, LeadEnquiry, AdCampaign, Promotion, Invoice, TeamMember, SubscriptionPlan
  • Marketplace: MarketplaceListing, MarketplaceStore, MarketplaceEnquiry, MarketplaceFavourite, MarketplaceReview, MarketplaceSavedSearch, MarketplaceReport
  • Content Hub: ContentArticle, ContentEvent, ContentCategory, ContentSaved, NewsletterSubscriber
  • Platform / Comms: Message, Notification, ClaimRequest, Report

Service modules are the only layer that touches base44.entities. Each service owns exactly one domain — cross-domain data needs are handled by composing service calls at the page level, never inside a service.

bookingService.js
  • generateBookingReference() — TLB-XXXX-XXXX
  • getAvailabilityForListing() → date-keyed map
  • isRangeAvailable() — pure, no I/O
  • calculatePrice() — pure pricing engine
  • createBooking / cancelBooking / updateBookingStatus
  • markDatesBooked / blockDates / markDatesAvailable
  • sendBookingNotification() → Notification entity
businessService.js
  • PLANS[] — single source of truth for plan tiers
  • planHasFeature() — pure feature-gate
  • getSubscription / upsertSubscription
  • getAnalytics / aggregateAnalytics — pure rollup
  • getLeads / createLead / updateLead — CRM
  • getCampaigns / createCampaign — advertising
  • getTeamMembers / inviteTeamMember — ROLE_PERMISSIONS
  • getInvoices / computeFinancialSummary — pure
  • getBusinessMessages / getUnreadNotifications
  • loadBusinessContext() — 6 parallel fetches
listingService.js
  • fetchListings() — 60s in-memory cache
  • fetchCategories() — session cache
  • geocodeAddress() — Nominatim (shared by RoutePlanner + Map)
  • distanceMiles() — Haversine, pure
  • applyFilters() — all filter types, pure
  • sortListings() — distance | rating | default, pure
  • getPinConfig() — category colour/emoji
marketplaceService.js
  • fetchListings / createListing / updateListing / deleteListing
  • 60s listing cache + invalidateMarketplaceCache()
  • applyClientFilters() — 14 filter dimensions, pure
  • sortListings() — price | newest | views | featured
  • toggleFavourite / isFavourited
  • sendEnquiry / replyToEnquiry / fetchThread
  • fetchStore / saveStore / fetchStoreListings
  • reportListing — writes MarketplaceReport
  • fetchSellerStats() — dashboard metrics
contentService.js
  • Article CRUD — full lifecycle management
  • Event CRUD — calendar & map integration
  • ContentCategory management
  • ContentSaved — reading list save/progress
  • NewsletterSubscriber — opt-in/unsubscribe
  • Served by ContentEditorModal + AdminContentPanel
aiService.js + communityService.js
  • aiService: BettyB LLM invocation wrapper
  • Trip itinerary planning (gemini_3_flash + internet)
  • Review summarisation (claude_sonnet for quality)
  • AI-generated business insights
  • communityService: Post, Question, Answer CRUD
  • HelpfulVote, PostInteraction, UserBadge
  • Report / moderation submission