This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
StudySync is an AI-powered educational platform that transforms passive note-taking into active learning through AI-generated flashcards, quizzes, and study guides. Built as a Turborepo monorepo.
# Start all services (frontend + backend)
npm run dev
# Run single workspace
npm run dev --workspace=@studysync/web # Frontend on :3000
npm run dev --workspace=@studysync/api # Backend on :3001
# Database (requires Docker services running first)
docker-compose up -d # Start PostgreSQL, Redis, MinIO
npm run db:push # Push schema changes
npm run db:generate # Generate Prisma client
npm run db:studio # Open Prisma GUI
npm run db:migrate # Run migrations
# Testing and linting
npm run lint # Lint all packages
npm run test # Run all tests
npm run test --workspace=@studysync/api # Test single package
# Build
npm run build # Build all packages
npm run clean # Remove build artifacts and node_modulesapps/
web/ # Next.js 14 frontend (@studysync/web) - src/app/ uses App Router
api/ # Express.js backend (@studysync/api)
packages/
database/ # Prisma schema and client (@studysync/database)
auth/ # JWT authentication logic (@studysync/auth)
shared/ # Shared utilities (planned)
ui/ # Shared UI components (planned)
@studysync/web → (calls API endpoints)
@studysync/api → @studysync/auth → @studysync/database
packages/auth/src/index.ts- Validation schemas (Zod), password hashing (bcrypt), JWT utilitiesapps/api/src/routes/auth.routes.ts- Auth endpoints with stricter rate limiting (10 req/15min)apps/api/src/middleware/auth.middleware.ts-authenticateToken,optionalAuth,requireSubscriptionmiddlewareapps/api/src/controllers/auth.controller.ts- Full auth implementation
Token expiration: Access 7 days, Refresh 30 days. Sessions stored in database.
POST /api/auth/register- User registrationPOST /api/auth/login- Login with email/passwordPOST /api/auth/refresh- Refresh access tokenPOST /api/auth/logout- Invalidate session (protected)GET /api/auth/me- Get current user (protected)PUT /api/auth/me- Update profile (protected)PUT /api/auth/me/password- Change password (protected)DELETE /api/auth/me- Delete account (protected)POST /api/auth/forgot-password- Request password resetPOST /api/auth/reset-password- Reset with tokenGET /api/auth/verify-email/:token- Email verification
Key models in packages/database/prisma/schema.prisma:
User- Subscription tiers: FREE, PREMIUM, STUDENT_PLUS, UNIVERSITYSession- JWT refresh tokens and verification tokensUpload- Processing status: PENDING → PROCESSING → COMPLETED/FAILEDFlashcardSet/Flashcard- Spaced repetition with EASY/MEDIUM/HARD difficultyQuiz/Question/Answer- Types: MULTIPLE_CHOICE, TRUE_FALSE, SHORT_ANSWER, ESSAYNote/NoteConnection- Knowledge graph for concept relationships
All inputs validated with Zod schemas. Auth schemas exported from @studysync/auth.
Stripe integration for subscription management with feature gating.
Backend Components:
apps/api/src/config/stripe.ts- Stripe client initializationapps/api/src/config/pricing.ts- Subscription tiers and feature limitsapps/api/src/services/stripe.service.ts- Customer, subscription, payment operationsapps/api/src/controllers/subscription.controller.ts- Subscription endpointsapps/api/src/controllers/webhook.controller.ts- Stripe webhook handlersapps/api/src/middleware/subscription.middleware.ts- Usage limit enforcement
Frontend Components:
apps/web/src/contexts/subscription-context.tsx- Global subscription stateapps/web/src/lib/subscription-api.ts- Subscription API clientapps/web/src/components/subscription/FeatureGate.tsx- Premium feature wrapperapps/web/src/components/subscription/UpgradeDialog.tsx- Upgrade prompt modalapps/web/src/app/pricing/page.tsx- Pricing page with checkout flowapps/web/src/app/(dashboard)/subscription/page.tsx- Subscription managementapps/web/src/app/checkout/success/page.tsx- Checkout success pageapps/web/src/app/checkout/cancel/page.tsx- Checkout cancel page
Subscription Tiers:
- FREE: 1 course, 3 flashcard sets, 5 quizzes, basic AI
- PREMIUM ($9.99/mo): Unlimited everything, knowledge graph, analytics
- STUDENT_PLUS ($14.99/mo): Premium + exam prediction, AI tutoring, 7-day trial
- UNIVERSITY: Custom enterprise pricing
Subscription API Endpoints:
GET /api/subscriptions/plans- Get all plans (public)GET /api/subscriptions/current- Current subscription statusPOST /api/subscriptions/checkout- Create Stripe checkout sessionPOST /api/subscriptions/portal- Create Stripe billing portalPUT /api/subscriptions/cancel- Cancel subscriptionPUT /api/subscriptions/reactivate- Reactivate canceled subscriptionGET /api/subscriptions/invoices- Invoice historyGET /api/subscriptions/usage- Usage statisticsPOST /api/subscriptions/promo- Validate promo codePOST /api/subscriptions/webhook- Stripe webhook receiver
Feature Gating:
- Knowledge graph routes require PREMIUM tier or higher
- Flashcard/quiz/upload creation checks tier limits
requireSubscription(tiers)middleware for tier enforcementrequireFeature(feature)middleware for feature access- Usage limits enforced via
checkFlashcardSetLimit,checkQuizLimit,checkUploadLimit
Required (see .env.example):
DATABASE_URL- PostgreSQL connectionJWT_SECRET/JWT_REFRESH_SECRET- Auth tokensREDIS_URL- CachingOPENAI_API_KEY- AI featuresSTRIPE_SECRET_KEY- Stripe API secret keySTRIPE_WEBHOOK_SECRET- Stripe webhook signing secretNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY- Stripe publishable keySTRIPE_PRICE_PREMIUM_MONTHLY- Stripe price ID for Premium monthlySTRIPE_PRICE_PREMIUM_YEARLY- Stripe price ID for Premium yearlySTRIPE_PRICE_STUDENT_PLUS_MONTHLY- Stripe price ID for Student Plus monthlySTRIPE_PRICE_STUDENT_PLUS_YEARLY- Stripe price ID for Student Plus yearly
Ports: Frontend :3000, API :3001, PostgreSQL :5432, Redis :6379, MinIO :9001
GitHub Actions (.github/workflows/ci.yml):
- Lint → 2. Tests (with PostgreSQL) → 3. Build → 4. Security scan
- PRs: Deploy preview
- Main branch: Deploy production
To ensure CI/CD checks pass on the first push, follow these rules when writing code:
- No unused variables: Remove any variable that is declared but never used
- No unused imports: Remove imports that aren't used in the file
- Use Prisma enums directly: When working with Prisma enum fields (like
SubscriptionStatus,SubscriptionTier), import and use the enum from@prisma/client:import { SubscriptionStatus, SubscriptionTier } from '@prisma/client'; // CORRECT const status = SubscriptionStatus.ACTIVE; // WRONG - will fail TypeScript const status = 'ACTIVE';
- Wrap
useSearchParams()in Suspense: Any component usinguseSearchParams()must be wrapped in a Suspense boundary:// CORRECT function PageContent() { const searchParams = useSearchParams(); // ... } export default function Page() { return ( <Suspense fallback={<Loading />}> <PageContent /> </Suspense> ); }
- Client components: Add
"use client"directive at top of files using React hooks - Avoid
anytypes: Use proper TypeScript types instead ofany
- No
@typescript-eslint/no-unused-varserrors: Check all imports and variables are used - Avoid
@typescript-eslint/no-explicit-any: Use specific types orunknowninstead - Run
npm run lintlocally before committing to catch issues early
- Stripe SDK: Use the API version that matches the installed SDK types
// Check package.json for stripe version, use matching apiVersion apiVersion: '2025-11-17.clover' // Must match SDK types
- Type casting for SDK changes: When SDK types don't match runtime properties:
// Cast to add missing properties const sub = subscription as Stripe.Subscription & { current_period_end: number; };
Before pushing code, run these commands locally:
npm run lint # Must pass with no errors (warnings OK)
npm run build # Must complete successfully
npm run test # All tests must pass| Error | Fix |
|---|---|
'X' is defined but never used |
Remove the unused import/variable |
Type 'string' is not assignable to type 'EnumType' |
Import and use the Prisma enum directly |
useSearchParams() should be wrapped in suspense |
Wrap component in <Suspense> |
Property 'X' does not exist on type |
Add type cast or update to correct API |
Unexpected any |
Replace any with proper type or unknown |
- Always import enums from Prisma for database operations
- Use type assertions for Stripe webhook event data
- Match Stripe API version to SDK types in
apps/api/src/config/stripe.ts - Use
discountsarray instead of deprecatedpromotion_codeproperty
docker-compose.yml provides PostgreSQL 15, Redis 7, MinIO (S3-compatible storage).
API Dockerfile uses multi-stage build with non-root user.
This section documents the standard process for creating GitHub issues and implementation plans from Linear issues.
- Fetch Linear Issue - Get details from Linear API
- Create Implementation Plan - Write comprehensive
docs/SSC-XX-IMPLEMENTATION-PLAN.md - Create GitHub Issue - Create issue with standardized format
- Commit & Push - Commit implementation plan so links work
- Update Meta Tracker - Update issue #3 with new links
- Verify CI/CD - Ensure all checks pass
curl -s -X POST https://api.linear.app/graphql \
-H "Content-Type: application/json" \
-H "Authorization: $LINEAR_API_KEY" \
-d '{"query": "{ issue(id: \"SSC-XX\") { identifier title description state { name } priorityLabel labels { nodes { name } } } }"}'Every implementation plan should follow this structure:
# SSC-XX: [Title] - Implementation Plan
## Overview
[2-3 paragraph description of the feature and its purpose]
**Priority**: [High/Medium/Low]
**Feature Type**: [Premium Feature / B2B Feature / Cross-Platform, etc.]
## Tech Stack
- **Backend**: [Technologies]
- **Frontend**: [Technologies]
- **Database**: [Technologies]
- **Other**: [Any additional tech]
## Current State Analysis
### What Already Exists
- [List existing infrastructure that can be leveraged]
### What Needs to Be Built
1. [Numbered list of components to build]
## Implementation Stages (N Atomic Commits)
### Phase 1: [Phase Name] (Commits 1-X)
**Commit 1**: [Commit description]
- [Details]
- Code examples in fenced blocks
**Commit 2**: [Commit description]
...
### Phase 2: [Phase Name] (Commits X-Y)
...
## API Endpoints Summary
### [Endpoint Category]METHOD /api/endpoint - Description (auth requirements)
## Database Schema Changes
### New Models
```prisma
model ModelName {
// Schema definition
}
apps/web/src/
├── app/
│ └── feature/
├── components/
│ └── feature/
- Feature 1
- Feature 2
- All N commits completed and passing CI
- [Specific measurable criteria]
- [How it integrates]
This feature depends on:
- [SSC-XX] ✅ Complete
- [SSC-YY] - [Status]
- [Future enhancement 1]
- [Future enhancement 2]
- [Important implementation notes]
### GitHub Issue Format
Create issues using `gh issue create` with this structure:
```markdown
# [Feature Title]
**Linear Issue**: SSC-XX
**Priority**: [High/Medium/Low]
**Feature Type**: [Type description]
## Overview
[Brief description - 2-3 sentences]
## Implementation Plan
📄 **Full implementation plan**: [docs/SSC-XX-IMPLEMENTATION-PLAN.md](link)
---
## Phase 1: [Phase Name] (Commits 1-X)
### Commit 1: [Description]
\`\`\`prisma
// Key schema or code snippet
\`\`\`
### Commit 2: [Description]
...
---
## API Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | \`/api/...\` | Description |
| POST | \`/api/...\` | Description |
---
## Checklist
### [Category]
- [ ] Task 1
- [ ] Task 2
---
## Success Criteria
- [ ] Criterion 1
- [ ] Criterion 2
---
## Dependencies
This feature depends on:
- [Dependency] ✅ Complete
-
Use HEREDOC for issue body - Prevents shell escaping issues:
gh issue create --title "SSC-XX: Title" --body "$(cat <<'EOF' Issue content here... EOF )"
-
Escape backticks in code blocks - Use
\``` in the heredoc for markdown code blocks -
Link to implementation plan - Always include the full GitHub URL:
📄 **Full implementation plan**: [docs/SSC-XX-IMPLEMENTATION-PLAN.md](https://github.com/Sakeeb91/StudySync/blob/main/docs/SSC-XX-IMPLEMENTATION-PLAN.md)
-
Use tables for API endpoints - Makes them scannable:
| Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/resource` | Get resource |
-
Organize with horizontal rules - Use
---between major sections -
Checklist format - Use
- [ ]for actionable items
After creating the issue and pushing the implementation plan:
-
Update the Phase 2 table - Add the new issue link and implementation plan link:
| SSC-XX | Feature Title | Priority | 📋 Backlog | [#N](issue-url) | [SSC-XX Plan](plan-url) |
-
Update Implementation Priority Order - Add checkmarks:
X. **SSC-XX**: Feature Title - [x] Implementation plan created - [x] GitHub issue created: [#N](url) - [ ] Implementation started - [ ] Implementation complete
-
Update Subscription Feature Matrix - If feature affects tiers:
| Feature (SSC-XX) | ❌ | ✅ | ✅ | ✅ |
For implementation plans:
docs: add implementation plan for SSC-XX [Feature Title]
Comprehensive plan covering:
- [Key aspect 1]
- [Key aspect 2]
- [Key aspect 3]
- [Number] atomic commits implementation strategy
- [Additional details]
# 1. Fetch Linear issue
curl -s -X POST https://api.linear.app/graphql \
-H "Content-Type: application/json" \
-H "Authorization: $LINEAR_API_KEY" \
-d '{"query": "{ issue(id: \"SSC-XX\") { ... } }"}'
# 2. Create implementation plan (write to docs/SSC-XX-IMPLEMENTATION-PLAN.md)
# 3. Create GitHub issue
gh issue create --title "SSC-XX: Feature Title" --body "$(cat <<'EOF'
# Feature Title
...
EOF
)"
# 4. Commit and push implementation plan
git add docs/SSC-XX-IMPLEMENTATION-PLAN.md
git commit -m "docs: add implementation plan for SSC-XX Feature Title
Comprehensive plan covering:
- Detail 1
- Detail 2
"
git push
# 5. Verify CI/CD
gh run list --limit 1
# Wait for completion, then verify success
# 6. Update meta tracker (issue #3)
gh issue edit 3 --body "$(cat <<'EOF'
# Updated meta tracker content...
EOF
)"Reference these for format examples:
docs/SSC-13-IMPLEMENTATION-PLAN.md- Assignment Brainstorming (22 commits, AI features)docs/SSC-14-IMPLEMENTATION-PLAN.md- Exam Prediction (18 commits, AI + analytics)docs/SSC-15-IMPLEMENTATION-PLAN.md- Mobile App (25 commits, React Native)docs/SSC-16-IMPLEMENTATION-PLAN.md- Payment System (Stripe integration)docs/SSC-17-IMPLEMENTATION-PLAN.md- Analytics Dashboard (20 commits, charts)docs/SSC-18-IMPLEMENTATION-PLAN.md- University Partnerships (24 commits, B2B)