From 2b5359e3cbfd1bd747150dc960209e0c8ffdeaca Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Sat, 16 Aug 2025 16:47:46 +0700 Subject: [PATCH] feat: update docs --- docs/features.md | 28 ++++++++++++++++------------ docs/game-flow.md | 36 +++++++++++++++++++----------------- docs/project-overview.md | 14 +++++++------- docs/project-structure.md | 19 +++++++++++-------- docs/tech-stack.md | 37 ++++++++++++++++++++++--------------- 5 files changed, 75 insertions(+), 59 deletions(-) diff --git a/docs/features.md b/docs/features.md index f6ef975..482a130 100644 --- a/docs/features.md +++ b/docs/features.md @@ -2,22 +2,25 @@ ## Location Coverage - **5 Vietnamese Locations**: Ha Noi, Da Nang, Ho Chi Minh, Da Lat, Duc Hoa (Long An) -- **Accurate Location Generation**: Nominatim API + Turf.js for precise city boundary detection +- **Bbox-based Location Generation**: Pre-defined city bounding boxes for accurate area targeting +- **Random Location Selection**: Server-side random coordinate generation within city boundaries ## Street View System -- **Mapillary Integration**: Panoramic street-level images -- **3-Tier Search Logic**: Progressive radius fallback (1km → 2km → 5km) -- **360° Panorama Viewer**: PhotoSphere Viewer with zoom and fullscreen controls +- **Mapillary Integration**: Panoramic street-level images via Mapillary API +- **Bbox Filtering**: Direct city bbox filtering for image search (no fallback tiers) +- **Panoramic Image Priority**: Filters for is_pano=true images when available +- **Thumbnail Display**: Currently uses thumb_original_url for image display ## Interactive Maps - **Leaflet Integration**: OpenStreetMap-based interactive mapping - **Click-to-Place**: Intuitive guess marker placement ## Anti-Cheat Security -- **Server-side Session Management**: Target coordinates never sent to client -- **Session Isolation**: Unique session IDs with automatic cleanup -- **30-minute Expiry**: Automatic session cleanup for security -- **Server-side Calculations**: All distance and scoring computed server-side +- **Redis Session Management**: Target coordinates stored server-side in Redis +- **UUID Session IDs**: Unique session identifiers using uuid v4 +- **30-minute Expiry**: Automatic Redis session cleanup for security +- **Server-side Calculations**: All distance and scoring computed server-side using Turf.js +- **Session Cleanup**: Automatic session deletion after guess submission ## Scoring System Distance-based points (0-5 scale): @@ -29,7 +32,8 @@ Distance-based points (0-5 scale): - **1km+**: 0 points ## Leaderboards -- **Redis-based Storage**: Persistent leaderboard data -- **Top 100 Players**: Maximum entry limit with auto-trimming -- **Highest Score Only**: Username + best score tracking -- **No Expiration**: Persistent storage across sessions +- **Redis Sorted Sets**: Persistent leaderboard data using Redis ZADD/ZRANGE +- **Top 200 Players**: Maximum entry limit with automatic trimming +- **Highest Score Only**: Only updates if new score exceeds existing score +- **Persistent Storage**: No expiration on leaderboard data +- **Real-time Ranking**: Dynamic rank calculation based on current standings diff --git a/docs/game-flow.md b/docs/game-flow.md index 250e03f..7fbe187 100644 --- a/docs/game-flow.md +++ b/docs/game-flow.md @@ -16,30 +16,31 @@ - Duc Hoa (Long An) ### 3. Session Creation -- Server generates unique session ID using UUID -- Server stores exact target location securely in session Map +- Server generates unique UUID v4 session ID +- Server stores exact target location securely in Redis with 30-minute expiry - Client receives session ID but never the target coordinates ### 4. Location Display Process -- **Boundary Detection**: Server uses Nominatim API + Turf.js for accurate city boundary detection -- **Image Search**: Mapillary API with 3-tier fallback logic: - 1. Search within 1km radius - 2. Fallback to 2km radius if no results - 3. Final fallback to 5km radius -- **Panorama Display**: PhotoSphereViewer renders 360° street view +- **Bbox Location Generation**: Server uses pre-defined city bounding boxes for random coordinate generation +- **Image Search**: Mapillary API searches within city bbox: + - Direct bbox filtering with is_pano=true preference + - Random selection from available panoramic images + - Fallback to non-panoramic images if needed +- **Image Display**: Thumbnail images displayed (thumb_original_url) - **Security**: Client never receives exact target coordinates ### 5. Guessing Phase -- **Panorama Interaction**: View 360° street-level image with PhotoSphereViewer controls +- **Image Interaction**: View street-level thumbnail image - **Map Interaction**: Place guess marker on interactive Leaflet map with OpenStreetMap - **Submission**: Click submit button to finalize guess ### 6. Server-Side Processing - **Input**: Client submits guess coordinates + session ID only -- **Retrieval**: Server retrieves exact location from secure session storage -- **Calculation**: Server calculates distance using Turf.js (prevents client-side cheating) +- **Retrieval**: Server retrieves exact location from Redis session storage +- **Validation**: Server validates coordinate ranges and session existence +- **Calculation**: Server calculates distance using Turf.js distance function - **Scoring**: Server-side score calculation with distance-based points -- **Cleanup**: Session destroyed after submission for security +- **Cleanup**: Redis session deleted after successful submission ### 7. Scoring System Distance-based points (0-5 scale): @@ -58,13 +59,14 @@ Distance-based points (0-5 scale): - Compare guess vs actual location on map ### 9. Leaderboard Management -- **Redis Storage**: Persistent storage with no expiration +- **Redis Sorted Sets**: Persistent storage using ZADD/ZRANGE operations - **Top 200 Limit**: Automatic trimming to maintain top performers only -- **Score Updates**: Only update if new score is higher than existing -- **Data Structure**: Username + highest score tracking +- **Score Updates**: Only update if new score is higher than existing (using ZSCORE check) +- **Real-time Ranking**: Dynamic rank calculation using ZREVRANK +- **Persistent Storage**: No expiration on leaderboard data ### 10. Continue or Exit - Option to start next round with new session and location - Option to return to city selection for different city -- Option to view full leaderboard -- Session cleanup ensures fresh start for each round \ No newline at end of file +- Option to view full leaderboard with pagination +- Redis session cleanup ensures fresh start for each round \ No newline at end of file diff --git a/docs/project-overview.md b/docs/project-overview.md index 9b40f3d..f84173b 100644 --- a/docs/project-overview.md +++ b/docs/project-overview.md @@ -1,19 +1,19 @@ # Project Overview -VNGeoGuessr is a GeoGuessr clone focused on Vietnamese locations, supporting 6 major cities with accurate boundary detection and anti-cheat security. Built with Next.js 15.4.6, React 19, and Tailwind CSS 4. +VNGeoGuessr is a GeoGuessr clone focused on Vietnamese locations, supporting 5 major cities with bbox-based location generation and anti-cheat security. Built with Next.js 15.4.6, React 19, and Tailwind CSS 4. ## Key Characteristics - **Location Coverage**: 5 Vietnamese locations - Ha Noi, Da Nang, Ho Chi Minh, Da Lat, Duc Hoa (Long An) -- **Accurate Location Generation**: Nominatim API + Turf.js for precise city boundary detection -- **Anti-Cheat Security**: Server-side session management, no client-side target coordinates +- **Bbox-based Location Generation**: Pre-defined bounding boxes for accurate city area targeting +- **Anti-Cheat Security**: Redis-based session management, server-side coordinate storage - **Persistent Storage**: Redis-based leaderboards with top 200 players - **Interactive Gameplay**: Click-to-guess map interface ## Game Mechanics -- **Street View**: Mapillary panoramic images with 3-tier search fallback -- **360° Viewer**: PhotoSphere Viewer with zoom and fullscreen controls +- **Street View**: Mapillary panoramic images using city bbox filtering +- **360° Viewer**: Thumbnail images with planned PhotoSphere Viewer integration - **Interactive Maps**: Leaflet + OpenStreetMap for guess placement -- **Distance-based Scoring**: 0-5 point scale based on accuracy -- **Session Isolation**: Server-side target coordinates for security \ No newline at end of file +- **Distance-based Scoring**: 0-5 point scale based on accuracy (Turf.js calculations) +- **Session Isolation**: Redis-stored sessions with 30-minute expiry for security \ No newline at end of file diff --git a/docs/project-structure.md b/docs/project-structure.md index 71b16ff..c1dc786 100644 --- a/docs/project-structure.md +++ b/docs/project-structure.md @@ -26,16 +26,18 @@ Next.js 15 App Router structure: - `debug/page.js` - Development debugging tools #### API Routes (`src/app/api/`) -- `new-game/route.js` - Creates new game sessions -- `guess/route.js` - Processes guess submissions -- `leaderboard/route.js` - Leaderboard data management -- `debug/mapillary/route.js` - Mapillary API debugging +- `new-game/route.js` - Creates new game sessions with Redis storage +- `guess/route.js` - Processes guess submissions and calculates scores +- `leaderboard/route.js` - Leaderboard data management with Redis +- `skip/route.js` - Skip current round functionality +- `debug/mapillary/route.js` - Mapillary API debugging and testing #### React Components (`src/app/components/`) - `GameClient.js` - Main game client component - `LeafletMap.js` - Interactive map for guess placement - `PanoramaViewer.js` - 360° street view display - `UsernameModal.js` - Username input modal +- `DonateQRModal.js` - Donation QR code modal ### Reusable Components (`src/components/`) @@ -60,10 +62,11 @@ Next.js 15 App Router structure: ### Utility Libraries (`src/lib/`) - `utils.js` - Utility functions including `cn()` for class name merging -- `game.js` - Game logic and session management -- `leaderboard.js` - Leaderboard operations with Redis -- `mapillary.js` - Mapillary API integration -- `nominatim.js` - Geographic boundary detection +- `game.js` - Game logic, scoring, distance calculations, and city definitions +- `leaderboard.js` - Leaderboard operations with Redis sorted sets +- `mapillary.js` - Mapillary API integration for street view images +- `session.js` - Redis-based session management with expiry +- `redis.js` - Redis client connection and configuration ## Documentation (`/docs/`) - `project-overview.md` - Project overview and key characteristics diff --git a/docs/tech-stack.md b/docs/tech-stack.md index 9a78de7..57dabee 100644 --- a/docs/tech-stack.md +++ b/docs/tech-stack.md @@ -2,39 +2,46 @@ ## Frontend Framework - **Next.js 15.4.6**: React-based full-stack framework with App Router -- **React 19**: Latest React version for component architecture +- **React 19.1.0**: Latest React version for component architecture - **Tailwind CSS 4**: Utility-first CSS framework for styling ## Street View & Mapping -- **Mapillary API**: Panoramic street-level imagery provider -- **PhotoSphere Viewer**: 360° panorama viewer with zoom and fullscreen -- **Leaflet**: Interactive mapping library +- **Mapillary API**: Panoramic street-level imagery provider (thumbnail URLs) +- **Leaflet**: Interactive mapping library for guess placement - **OpenStreetMap**: Map tile provider for base maps +- **@photo-sphere-viewer/core**: 360° panorama viewer (planned integration) ## Geographic Processing -- **Nominatim API**: OpenStreetMap geocoding service for city boundaries -- **Turf.js**: Spatial operations library for point-in-polygon detection and distance calculations -- **Geospatial Logic**: Server-side coordinate validation and boundary checking +- **@turf/turf**: Spatial operations library for distance calculations and point processing +- **Bbox-based Location**: Pre-defined city bounding boxes for location generation +- **Server-side Calculations**: All geographic processing on backend ## Data Storage & Session Management -- **Redis**: Persistent leaderboard storage with automatic trimming -- **In-Memory Map**: Server-side session storage with 30-minute expiry -- **Session Isolation**: Secure target coordinate storage per game session +- **Redis**: Complete session and leaderboard storage +- **Redis Sorted Sets**: Leaderboard ranking with automatic trimming +- **UUID v4**: Session identifier generation +- **30-minute Session Expiry**: Automatic Redis-based cleanup ## UI Components & Styling -- **shadcn/ui**: Component library with "new-york" style +- **shadcn/ui**: Complete component library with "new-york" style +- **Radix UI**: Headless component primitives - **Lucide React**: Icon library - **class-variance-authority**: Component variant management - **tailwind-merge + clsx**: Dynamic class name handling -- **CSS Variables**: Theme-based styling system + +## Form Handling & Validation +- **react-hook-form**: Form state management +- **@hookform/resolvers**: Form validation resolvers +- **zod**: Schema validation ## Development & Analytics - **ESLint**: Code linting with Next.js configuration - **Turbopack**: Development server bundler -- **Vercel Analytics**: User analytics tracking -- **Vercel Speed Insights**: Performance monitoring +- **@vercel/analytics**: User analytics tracking +- **@vercel/speed-insights**: Performance monitoring ## Key Dependencies -- **UUID**: Unique session identifier generation +- **uuid**: v11.1.0 for unique session identifier generation +- **redis**: v5.8.0 for data persistence - **JavaScript Only**: No TypeScript - pure JavaScript implementation - **Individual Parameters**: Functions use separate parameters instead of object destructuring \ No newline at end of file