# ThrillWiki - Theme Park & Ride Encyclopedia ## Overview ThrillWiki is a comprehensive web application for discovering, reviewing, and tracking theme parks, rides, and related entities worldwide. Built as a community-driven encyclopedia, it allows users to explore parks, submit reviews, upload photos, and contribute content through a moderated submission system. **Core Purpose:** Provide enthusiasts with a centralized platform to research theme parks, roller coasters, and attractions while building a collaborative knowledge base through user contributions and reviews. **Tech Stack:** - Frontend: React + TypeScript with Vite - UI Framework: Radix UI + Tailwind CSS (shadcn/ui) - Backend: Supabase (PostgreSQL + Auth + Storage + Realtime) - Image Storage: Cloudflare Images (via Edge Functions) - Notifications: Novu (multi-channel notification system) - File Uploads: Uppy - State Management: TanStack Query (React Query) ## User Preferences Preferred communication style: Simple, everyday language. ## System Architecture ### Frontend Architecture **Component Structure:** - Layout components (Header, Footer, AdminHeader) provide consistent navigation - Page-level components for major routes (Parks, Rides, Profile, Admin) - Reusable UI components from shadcn/ui library - Custom domain components (parks, rides, manufacturers, reviews, moderation) **State Management:** - TanStack Query for server state and caching - React Context for authentication state (AuthProvider) - Custom hooks for business logic (useAuth, useUserRole, useSearch, useUnitPreferences) - Realtime subscriptions for live updates (moderation stats, submissions) **Routing:** - React Router v6 with nested routes - Dynamic slug-based routes for entities (parks/:slug, rides/:rideSlug) - Protected admin routes with role-based access control **Design System:** - HSL-based color system with CSS variables - Dark/light theme support via ThemeProvider - Custom gradients and effects for "thrill" aesthetic - Inter font family for typography - Responsive design with mobile-first approach ### Backend Architecture **Database Schema (Supabase PostgreSQL):** - Core entities: parks, rides, companies (manufacturers/designers/operators/property_owners) - Location system with hierarchical data (countries, states, cities) - Review and rating system with moderation - User profiles with privacy controls and preferences - Content submission workflow with approval queue - Image metadata tracking (linked to Cloudflare) - Notification preferences and templates **Authentication & Authorization:** - Supabase Auth for user management - Magic link and email/password authentication - Cloudflare Turnstile CAPTCHA for bot protection - Role-based access control (user, moderator, admin, superuser) - Row-level security (RLS) policies for data access - Profile field-level privacy controls **Content Moderation System:** - Two-tier submission workflow (submission → submission_items) - Dependency tracking for related entities (rides depend on parks) - Conflict resolution for duplicate/missing entities - Realtime updates for moderation queues - Automated slug generation with uniqueness checks - Status tracking (pending, approved, rejected) **Data Access Patterns:** - Security definer functions for privileged operations - Complex joins for entity relationships (parks with rides, operators, locations) - Aggregated data (ratings, review counts, ride counts) - Full-text search capabilities - Realtime subscriptions for live data updates ### Image Management **Cloudflare Images Integration:** - Upload via Supabase Edge Function proxy - Two-step upload process (get URL → upload file) - Multiple image variants for responsive display - Assignment system for entity images (banner, card, gallery) - Local preview support before upload - Image metadata stored in Supabase **Upload Workflow:** - Uppy dashboard for multi-file uploads - Image editor integration for cropping/adjustments - Progress tracking and status updates - Entity-specific galleries (parks, rides, companies) - Automatic resizing and optimization via Cloudflare ### Notification System (Novu) **Architecture:** - Multi-channel delivery (in-app, email, push, SMS planned) - Workflow-based templates (review replies, new followers, system announcements) - Per-workflow user preferences - Frequency controls and digest settings - Subscriber management via Supabase Edge Functions - Headless notifications with custom UI **Migration Strategy:** - Backward compatibility with legacy notification preferences - Automatic migration from old email/push settings - Granular channel and workflow controls - Delivery tracking and analytics ### Search & Discovery **Multi-Entity Search:** - Unified search across parks, rides, and companies - Autocomplete with debounced queries - Recent search history (localStorage) - Category and type filtering - Advanced filters (technical specs, stats, location) **Location Features:** - Automatic unit conversion (metric/imperial) - Geo-based preferences with auto-detection - Distance and measurement system preferences - Temperature unit preferences ### User Management **Profile System:** - Customizable usernames with validation - Display names and avatars (Cloudflare Images) - Bio and personal information - Privacy controls for fields (date of birth, location, pronouns) - Home park selection - Activity tracking (reviews, submissions) **User Blocking:** - Block/unblock functionality - Hidden content from blocked users - Privacy-respecting implementation **Role Management:** - Hierarchical permission system - Superuser can manage all roles - Admin can manage moderators - Moderator can manage content - Role-specific UI elements and routes ### Admin & Moderation **Moderation Queue:** - Realtime submission monitoring - Item-level approval/rejection - Dependency conflict resolution - Bulk actions support - Status tracking and filtering **Admin Settings:** - System-wide configuration (Novu integration, etc.) - Category-based settings organization - Audit trail for changes - Superuser-only access **Reports System:** - User-generated content reports - Status workflow (pending, reviewed, resolved) - Moderator actions tracking ## External Dependencies ### Third-Party Services **Supabase:** - PostgreSQL database with RLS - Authentication and user management - Real-time subscriptions - Edge Functions for serverless logic - Storage for metadata (images stored on Cloudflare) **Cloudflare:** - Cloudflare Images for media storage and transformation - Direct upload API integration - Automatic image optimization - Multiple variant support for responsive images **Novu:** - Multi-channel notification delivery - Workflow management and templates - Subscriber preferences - Headless notification center - Email, push, and in-app notifications **Uppy:** - File upload interface - Image editor integration - Progress tracking - Dashboard UI component - XHR upload transport **Additional Services:** - Cloudflare Turnstile for CAPTCHA - Google Fonts (Inter) - Radix UI for accessible components ### API Integrations **Supabase Edge Functions:** - `upload-image`: Proxy for Cloudflare Images upload - `trigger-novu-notification`: Send notifications via Novu - `sync-novu-subscriber`: Manage Novu subscribers - `sync-novu-preferences`: Sync notification preferences **Database Functions (PostgreSQL):** - `can_view_profile_field`: Privacy check for profile fields - `get_user_management_permissions`: Role-based permissions - Security definer functions for privileged operations - Trigger functions for automated tasks ### Environment Configuration **Required Variables:** - `VITE_NOVU_APPLICATION_IDENTIFIER`: Novu app ID - `VITE_NOVU_SOCKET_URL`: Novu WebSocket endpoint - `VITE_NOVU_API_URL`: Novu API endpoint - `VITE_CLOUDFLARE_ACCOUNT_HASH`: Cloudflare Images account hash for image URL construction - `VITE_SUPABASE_URL`: Supabase project URL (required for client initialization) - `VITE_SUPABASE_ANON_KEY`: Supabase anonymous key (required for client initialization) - `VITE_TURNSTILE_SITE_KEY`: Cloudflare Turnstile CAPTCHA site key (required for bot protection) - Cloudflare Images API credentials (stored in Supabase secrets for edge functions) **Feature Flags:** - Theme persistence via localStorage - Unit preferences (metric/imperial) - Auto-detection for location-based settings - Notification channel preferences ## Recent Changes ### Bug Fixes and Security Improvements (October 7, 2025) **Security Fixes:** - Migrated all hardcoded credentials to environment variables: - `src/integrations/supabase/client.ts`: Now uses `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY` with error handling - `src/components/auth/TurnstileCaptcha.tsx`: Now uses `VITE_TURNSTILE_SITE_KEY` with warning UI if missing - Previously migrated: Cloudflare account hash to `VITE_CLOUDFLARE_ACCOUNT_HASH` across 14 components - All sensitive credentials now properly managed through environment variables **Race Condition Fixes:** - `src/hooks/useEntityVersions.ts`: Added lifecycle tracking with mounted ref, channel ref for preventing duplicate subscriptions, comprehensive cleanup on unmount - `src/hooks/useAuth.tsx`: Added mounted ref, timeout tracking and cleanup, guarded all state updates to prevent updates after unmount, improved error handling with user feedback via toast notifications **Memory Leak Fixes:** - `src/components/upload/PhotoUpload.tsx`: Implemented comprehensive object URL tracking with ref-based tracking set, automatic cleanup on unmount, revocation on all success/error paths, prevents memory leaks in all scenarios **Input Validation Improvements:** - `supabase/functions/create-novu-subscriber/index.ts`: Added validation for subscriberId and email format with structured 400 error responses - `supabase/functions/upload-image/index.ts`: Added validation for all request methods (GET/POST/DELETE) with proper error handling - `supabase/functions/process-selective-approval/index.ts`: Added UUID validation for userId and submissionId, array validation for itemIds, comprehensive error messages **Error Handling Improvements:** - Profile fetch failures now show user-friendly toast notifications - Edge functions return structured error responses (400 for validation, 401 for auth, 500 for server errors) - All async operations properly handle errors with user feedback **Import Fixes:** - Fixed sonner.tsx to import `useTheme` from local `@/components/theme/ThemeProvider` instead of incorrect `next-themes` package ### Additional Bug Fixes and Security Improvements (October 7, 2025) **Security Enhancements:** - `supabase/functions/upload-image/index.ts`: Added authentication requirements for POST and GET operations to prevent unauthorized access to image uploads and status checks - All image operations now verify JWT tokens via Supabase auth before proceeding with Cloudflare API calls - Added TODO comments for restricting CORS to specific domains in production environments **Performance Optimizations:** - `src/components/upload/PhotoUpload.tsx`: Optimized session token fetching to retrieve once before polling loop instead of on every iteration, reducing unnecessary authentication calls and improving upload performance **Enhanced Input Validation:** - `supabase/functions/create-novu-subscriber/index.ts`: Comprehensive validation added for all fields: - Required fields: subscriberId and email with format validation - Optional fields: firstName/lastName (max 100 chars), phone (international format), avatar (valid URL), data (object type with 10KB size limit) - Graceful handling of malformed JSON with proper 400 error responses instead of 500 **Error Handling Improvements:** - `src/lib/versioningHelpers.ts`: Added `instanceof Error` checks before accessing `error.message` to prevent runtime crashes - `src/lib/notificationService.ts`: Added safe error message extraction with fallback for non-Error objects - All error handlers now provide user-friendly messages while maintaining detailed logging