You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# CodeTracker Pro
CodeTracker Pro is a Next.js 14 competitive programming question manager with:
- App Router + TypeScript
- Tailwind CSS
- custom shadcn-style UI primitives
- Zustand for client UI state
- Prisma + PostgreSQL for persistence
- Auth.js Google sign-in with Prisma-backed users and sessions
- OpenRouter-powered AI analysis with free models
- predefined topic library for consistent tagging
- platform account linking with Codeforces sync
- Recharts for stats
- SheetJS for Excel export
## Setup
1. Create the app shell if you want to reproduce manually:
```bash
npx create-next-app@latest codetracker-pro --typescript --tailwind --app
cd codetracker-pro
```
2. Install dependencies:
```bash
npm install next react react-dom zustand xlsx recharts lucide-react clsx tailwind-merge @prisma/client
npm install -D prisma
```
3. Add environment variables in `.env.local`:
```env
DATABASE_URL="your_neon_postgres_url_here"
OPENROUTER_API_KEY="your_openrouter_api_key_here"
OPENROUTER_MODEL="openrouter/free"
GOOGLE_CLIENT_ID="your_google_client_id_here"
GOOGLE_CLIENT_SECRET="your_google_client_secret_here"
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your_random_secret_here"
AUTH_SECRET="your_random_auth_secret_here"
```
4. Generate the Prisma client and push the schema:
```bash
npx prisma generate
npx prisma db push
```
5. Run the app:
```bash
npm run dev
```
## Database
The project uses Prisma with PostgreSQL. The schema lives in [prisma/schema.prisma](/d:/yourcp/codetracker-pro/prisma/schema.prisma:1).
Google sign-in is powered by Auth.js and Prisma models for:
- `User`
- `Account`
- `Session`
- `VerificationToken`
- `QuestionRecord`
- `PlatformAccount`
Question data is persisted in the `QuestionRecord` table and each question belongs to a signed-in user. CRUD is exposed through:
- `GET /api/questions`
- `POST /api/questions`
- `PATCH /api/questions/[id]`
- `DELETE /api/questions/[id]`
Platform account linking and sync is exposed through:
- `GET /api/platform-accounts`
- `POST /api/platform-accounts`
- `PATCH /api/platform-accounts/[id]`
- `DELETE /api/platform-accounts/[id]`
- `POST /api/platform-accounts/[id]/sync`
## AI Analysis
The analyze route is [app/api/analyze/route.ts](/d:/yourcp/codetracker-pro/app/api/analyze/route.ts:1). It sends the problem URL or description to OpenRouter using free models, defaulting to `openrouter/free` and falling back across a few free options when needed.
## Platform Sync
The dashboard now includes a platform account section where users can save handles for LeetCode, Codeforces, CodeChef, AtCoder, HackerRank, and GeeksforGeeks.
- Codeforces sync is live using the official public API
- solved Codeforces submissions are imported into the main tracker and mapped into the predefined topic library
- other platforms currently support handle storage and UI scaffolding so additional sync adapters can be added cleanly
## Prisma Client
The shared Prisma client now lives in [lib/prismaclient.ts](/d:/yourcp/codetracker-pro/lib/prismaclient.ts:1). The legacy [lib/prisma.ts](/d:/yourcp/codetracker-pro/lib/prisma.ts:1) file simply re-exports it for compatibility.
## Project Structure
```text
codetracker-pro/
├── app/
│ ├── api/
│ │ ├── analyze/route.ts
│ │ └── questions/
│ │ ├── route.ts
│ │ └── [id]/route.ts
│ ├── dashboard/page.tsx
│ ├── stats/page.tsx
│ ├── tracker/page.tsx
│ ├── globals.css
│ ├── layout.tsx
│ └── page.tsx
├── components/
│ ├── ui/
│ ├── AddQuestionModal.tsx
│ ├── AppProviders.tsx
│ ├── ConfidenceStars.tsx
│ ├── ExportButton.tsx
│ ├── FilterBar.tsx
│ ├── HintDrawer.tsx
│ ├── Navbar.tsx
│ ├── QuestionCard.tsx
│ ├── QuestionTable.tsx
│ └── StatsPanel.tsx
├── constants/platforms.ts
├── lib/
│ ├── analyzeQuestion.ts
│ ├── exportToExcel.ts
│ ├── prisma.ts
│ ├── questionDb.ts
│ └── utils.ts
├── prisma/schema.prisma
├── store/useTrackerStore.ts
└── types/index.ts
```
# Yourcp