From efb8a1663b0d138b042e599c3679e891154d36ac Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Mon, 4 Aug 2025 23:22:23 +0700 Subject: [PATCH] feat: update CLAUDE.md --- CLAUDE.md | 279 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 238 insertions(+), 41 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 965b8b9..25bf824 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,59 +2,256 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. -## Project Overview +## ๐Ÿ‡ป๐Ÿ‡ณ VNGeoGuessr - Project Configuration -This is **vngeoguessr** - a Next.js 15 application built with React 19, TypeScript, and Tailwind CSS. The project appears to be a GeoGuessr-like application (based on the name), currently in initial development stage with the default Next.js template. +A Vietnamese location-guessing game built with Next.js, featuring interactive maps, real-time multiplayer, and scoring systems focused on Vietnam geography. -## Development Commands +## ๐Ÿ› ๏ธ Development Environment -### Core Development -- `npm run dev` or `pnpm dev` - Start development server with Turbopack (runs on http://localhost:3000) -- `npm run build` - Build the application for production -- `npm start` - Start production server -- `npm run lint` - Run ESLint for code quality checks +- **Language**: TypeScript (`^5.0.0`) +- **Framework**: Next.js 15 (App Router) +- **Styling**: Tailwind CSS v4 +- **Component Library**: shadcn/ui +- **State Management**: Zustand +- **Maps**: Google Maps JavaScript API +- **Backend**: Supabase (Database, Auth, Storage, Realtime) +- **Geo Calculations**: Turf.js +- **Testing**: Jest + React Testing Library +- **Linting**: ESLint with `@typescript-eslint` +- **Formatting**: Prettier +- **Package Manager**: `pnpm` (preferred) +- **Hosting**: Vercel +- **Analytics**: Vercel Analytics -### Package Management -The project uses both npm (package-lock.json) and pnpm (pnpm-lock.yaml). Prefer `pnpm` commands when available. +## โš™๏ธ Development Commands -## Architecture & Structure +- **Dev server**: `pnpm dev` (with Turbopack, runs on http://localhost:3000) +- **Build**: `pnpm build` +- **Start**: `pnpm start` +- **Lint**: `pnpm lint` +- **Format**: `pnpm format` +- **Test**: `pnpm test` +- **Type check**: `pnpm type-check` -### Tech Stack -- **Framework**: Next.js 15 with App Router -- **React**: Version 19.1.0 -- **TypeScript**: TypeScript 5 with strict mode enabled -- **Styling**: Tailwind CSS v4 with PostCSS -- **Fonts**: Geist Sans and Geist Mono from Google Fonts -- **Bundler**: Turbopack (enabled in dev mode) +## ๐Ÿ“‚ Project Structure -### Directory Structure ``` -src/ - app/ # Next.js App Router directory - layout.tsx # Root layout with font configuration - page.tsx # Home page component - globals.css # Global Tailwind styles -public/ # Static assets (SVG icons) +. +โ”œโ”€โ”€ app/ # App Router structure +โ”‚ โ”œโ”€โ”€ layout.tsx +โ”‚ โ”œโ”€โ”€ page.tsx +โ”‚ โ”œโ”€โ”€ game/ +โ”‚ โ”‚ โ”œโ”€โ”€ [gameId]/ +โ”‚ โ”‚ โ””โ”€โ”€ create/ +โ”‚ โ”œโ”€โ”€ leaderboard/ +โ”‚ โ”œโ”€โ”€ profile/ +โ”‚ โ””โ”€โ”€ api/ +โ”‚ โ”œโ”€โ”€ games/ +โ”‚ โ””โ”€โ”€ scores/ +โ”œโ”€โ”€ components/ # UI components +โ”‚ โ”œโ”€โ”€ ui/ # shadcn/ui components +โ”‚ โ”œโ”€โ”€ game/ # Game-specific components +โ”‚ โ”‚ โ”œโ”€โ”€ MapView.tsx +โ”‚ โ”‚ โ”œโ”€โ”€ GuessMarker.tsx +โ”‚ โ”‚ โ”œโ”€โ”€ ScoreDisplay.tsx +โ”‚ โ”‚ โ””โ”€โ”€ GameControls.tsx +โ”‚ โ”œโ”€โ”€ maps/ # Map-related components +โ”‚ โ””โ”€โ”€ auth/ # Authentication components +โ”œโ”€โ”€ stores/ # Zustand stores +โ”‚ โ”œโ”€โ”€ gameStore.ts +โ”‚ โ”œโ”€โ”€ userStore.ts +โ”‚ โ””โ”€โ”€ mapStore.ts +โ”œโ”€โ”€ hooks/ # Custom React hooks +โ”‚ โ”œโ”€โ”€ useSupabase.ts +โ”‚ โ”œโ”€โ”€ useGoogleMaps.ts +โ”‚ โ””โ”€โ”€ useGameLogic.ts +โ”œโ”€โ”€ lib/ # Utilities and configurations +โ”‚ โ”œโ”€โ”€ supabase/ +โ”‚ โ”‚ โ”œโ”€โ”€ client.ts +โ”‚ โ”‚ โ”œโ”€โ”€ auth.ts +โ”‚ โ”‚ โ””โ”€โ”€ realtime.ts +โ”‚ โ”œโ”€โ”€ maps/ +โ”‚ โ”‚ โ”œโ”€โ”€ googleMaps.ts +โ”‚ โ”‚ โ””โ”€โ”€ streetView.ts +โ”‚ โ”œโ”€โ”€ game/ +โ”‚ โ”‚ โ”œโ”€โ”€ scoring.ts +โ”‚ โ”‚ โ”œโ”€โ”€ distance.ts # Turf.js calculations +โ”‚ โ”‚ โ””โ”€โ”€ locations.ts +โ”‚ โ””โ”€โ”€ utils.ts +โ”œโ”€โ”€ types/ # TypeScript type definitions +โ”‚ โ”œโ”€โ”€ game.ts +โ”‚ โ”œโ”€โ”€ user.ts +โ”‚ โ””โ”€โ”€ maps.ts +โ”œโ”€โ”€ styles/ # Tailwind customizations +โ”œโ”€โ”€ tests/ # Unit and integration tests +โ”œโ”€โ”€ public/ +โ”œโ”€โ”€ .env.local.example +โ”œโ”€โ”€ .eslintrc.js +โ”œโ”€โ”€ tailwind.config.ts +โ”œโ”€โ”€ tsconfig.json +โ”œโ”€โ”€ postcss.config.js +โ”œโ”€โ”€ next.config.js +โ”œโ”€โ”€ package.json +โ””โ”€โ”€ README.md ``` -### Key Configuration -- **TypeScript**: Configured with path mapping (`@/*` โ†’ `./src/*`) -- **ESLint**: Next.js config with modern ESLint 9 -- **Target**: ES2017 with modern module resolution +## ๐Ÿ“ฆ Required Dependencies -### Current State -The application is currently using the default Next.js template with Tailwind CSS. The main page displays the standard Next.js welcome screen with deployment and documentation links. +```bash +# Core dependencies +pnpm add @supabase/supabase-js @supabase/auth-helpers-nextjs +pnpm add zustand +pnpm add @turf/turf @turf/distance @turf/helpers +pnpm add @googlemaps/js-api-loader -## Development Notes +# Development dependencies +pnpm add -D @types/google.maps +``` -### Font System -The app uses Geist font family (both Sans and Mono variants) loaded via `next/font/google` with CSS variables for consistent typography. +**Setup Requirements:** +- Tailwind CSS with PostCSS configuration +- shadcn/ui: `npx shadcn-ui@latest init` +- Google Maps API key in environment variables +- Supabase project with RLS policies configured -### Styling Approach -- Tailwind CSS v4 with modern configuration -- CSS variables for font families -- Dark mode support built into components -- Responsive design patterns (sm: breakpoints) +## ๐ŸŒ Environment Variables -### File Editing -The main entry point for development is `src/app/page.tsx`. The layout is configured in `src/app/layout.tsx` with global styles in `src/app/globals.css`. \ No newline at end of file +```bash +# Google Maps +NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=your_api_key_here + +# Supabase +NEXT_PUBLIC_SUPABASE_URL=your_supabase_url +NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key + +# Vercel Analytics (auto-configured on Vercel) +``` + +## ๐ŸŽฎ Game Logic Architecture + +### Scoring System +- Use Turf.js `distance()` for geographical calculations +- Exponential scoring: closer guesses = exponentially higher points +- Store scoring logic in `lib/game/scoring.ts` + +### State Management (Zustand) +- **GameStore**: Current game state, rounds, scores, guesses +- **UserStore**: Authentication state, user preferences, statistics +- **MapStore**: Map settings, current location, Street View state + +### Real-time Features +- Supabase Realtime for multiplayer game rooms +- Live game state updates and synchronization +- Connection state handling and reconnection logic + +## ๐Ÿ—บ๏ธ Google Maps Integration + +### Street View Implementation +- Random locations with Street View coverage verification +- Panorama controls and movement restrictions +- Street View availability checks before game start + +### Interactive Guessing Map +- World map for placing guesses with custom markers +- Distance visualization between guess and actual location +- Smooth animations and transitions between rounds + +## ๐Ÿ’พ Supabase Database Schema + +```sql +-- Games table +games ( + id uuid primary key, + created_by uuid references auth.users, + game_mode text, + max_rounds integer, + time_limit integer, + created_at timestamp, + status text +) + +-- Game rounds table +game_rounds ( + id uuid primary key, + game_id uuid references games, + round_number integer, + location_lat float, + location_lng float, + street_view_data jsonb +) + +-- Player guesses table +player_guesses ( + id uuid primary key, + game_id uuid references games, + player_id uuid references auth.users, + round_id uuid references game_rounds, + guess_lat float, + guess_lng float, + distance_km float, + score integer, + time_taken integer +) +``` + +## ๐Ÿงช Testing Strategy + +- **Framework**: Jest + React Testing Library +- **Mocking**: Google Maps API calls, Supabase client interactions +- **Focus Areas**: Game logic (scoring, distance calculations), component rendering +- **Integration Tests**: Full game flow with mocked external services + +## ๐Ÿ“ฑ Development Guidelines + +### Component Architecture +- Use shadcn/ui for base UI components (buttons, dialogs, forms) +- Game-specific components in `components/game/` +- Responsive design with mobile-first approach +- Handle loading states for maps and Street View + +### Performance Optimization +- Lazy load Google Maps API +- React.memo for expensive game components +- Optimize Supabase queries with proper indexing +- Image optimization for location thumbnails + +### Security Implementation +- Row Level Security (RLS) policies for all user data +- Server-side validation for all game inputs +- Rate limiting on game creation and submission endpoints +- Secure API routes with authentication middleware + +## ๐Ÿ’ก Common Development Patterns + +```typescript +// Game state management with Zustand +const useGameStore = create((set) => ({ + currentRound: 1, + score: 0, + guesses: [], + updateScore: (points) => set((state) => ({ score: state.score + points })) +})) + +// Distance calculation with Turf.js +import { distance } from '@turf/turf' +const calculateDistance = (guess: [number, number], actual: [number, number]) => { + return distance(guess, actual, { units: 'kilometers' }) +} + +// Supabase real-time subscription +const gameChannel = supabase + .channel('game-updates') + .on('postgres_changes', { event: '*', schema: 'public', table: 'games' }, + (payload) => handleGameUpdate(payload)) + .subscribe() +``` + +## ๐Ÿงฉ Custom Development Commands + +For future implementation in `.claude/commands/`: + +- `/create-game-component` - Scaffold game component with TypeScript +- `/setup-map-integration` - Configure Google Maps with Street View +- `/add-zustand-store` - Create new Zustand store with proper typing +- `/implement-scoring` - Add scoring logic with Turf.js calculations +- `/setup-realtime` - Configure Supabase Realtime features \ No newline at end of file