Skip to content

Latest commit

 

History

History
209 lines (181 loc) · 7.72 KB

File metadata and controls

209 lines (181 loc) · 7.72 KB

CIGHT — Project Checkpoint

Overview

AI-powered entertainment recognition and discovery platform. Identify movies, TV shows, and anime from screenshots and clips.

Architecture

Browser → Vercel (Frontend) → Render (Backend API) → MongoDB Atlas
         cight-two.vercel.app   cight.onrender.com     cluster0.vxpzdh0

Tech Stack

Layer Technology
Frontend React 19, Vite 6, Tailwind CSS 4, Motion
Backend Express 5, Node.js
Database MongoDB Atlas (Mongoose)
AI Groq (openai/gpt-oss-120b) via OpenAI SDK
Auth JWT (email/password, bcryptjs)
Movie Data TMDB API, AniList GraphQL, Trace.moe
PWA vite-plugin-pwa

Project Structure

Cight/
├── server/
│   ├── index.js              # Express API server
│   ├── db.js                 # MongoDB/Mongoose connection
│   ├── middleware.js          # JWT auth middleware
│   ├── models/
│   │   ├── User.js           # email, password, displayName
│   │   ├── Watchlist.js      # userId, movieId, movieTitle, mediaType, posterPath
│   │   ├── Comment.js        # userId, userName, movieId, content, parentId
│   │   └── Rating.js         # userId, movieId, type (like|dislike)
│   └── routes/
│       ├── auth.js           # POST /register, POST /login, GET /me
│       ├── watchlist.js      # GET /, POST /, DELETE /:id, GET /check/:movieId
│       ├── comments.js       # GET /:movieId, POST /, DELETE /:id
│       └── ratings.js        # GET /:movieId, GET /:movieId/mine, POST /
├── src/
│   ├── main.tsx              # Entry point
│   ├── App.tsx               # Router + auth provider
│   ├── context/
│   │   └── AuthContext.tsx    # JWT auth state (user, login, register, logout)
│   ├── components/
│   │   ├── AuthModal.tsx      # Email/password login and signup modal
│   │   ├── Navbar.tsx         # Navigation + search + auth controls
│   │   └── SEO.tsx            # Dynamic meta tags for each page
│   ├── pages/
│   │   ├── Landing.tsx        # Marketing page with hero and features
│   │   ├── Home.tsx           # Trending movies, genre filter, browse
│   │   ├── Scan.tsx           # Scene recognition (single + batch mode)
│   │   ├── Movie.tsx          # Movie detail: trailer, cast, comments, ratings
│   │   ├── Chat.tsx           # AI assistant chat with Groq
│   │   └── Watchlist.tsx      # User's saved movies list
│   └── lib/
│       ├── api.ts             # API client (JWT token management)
│       ├── groq.ts            # Groq AI: identifyMovieFromMedia, identifyMovieFromText, chatAssistant
│       ├── tmdb.ts            # TMDB API: trending, genres, search, details, providers
│       ├── anilist.ts         # AniList GraphQL: searchAnime
│       ├── tracemoe.ts        # Trace.moe: frame-accurate anime identification
│       └── utils.ts           # cn() tailwind class merge helper
├── public/                   # Static assets (logos, icons, OG image)
├── vercel.json               # Vercel SPA rewrites
├── render.yaml               # Render Blueprint config
├── vite.config.ts            # Vite + Tailwind + PWA config
├── tsconfig.json             # TypeScript config
└── .env.example              # Environment variable template

Environment Variables

Vercel (Frontend)

Variable Description
VITE_API_URL Render backend URL with /api suffix
VITE_GROQ_API_KEY Groq API key from console.groq.com/keys
VITE_TMDB_API_KEY TMDB API key from themoviedb.org

Render (Backend)

Variable Description
NODE_ENV Set to "production"
MONGODB_URL MongoDB Atlas connection string
JWT_SECRET Auto-generated by Render
FRONTEND_URL Vercel URL (no trailing slash) for CORS

API Routes

Base: https://cight.onrender.com/api

Auth

Method Path Auth Description
POST /auth/register No { email, password, displayName } → { token, user }
POST /auth/login No { email, password } → { token, user }
GET /auth/me Yes Returns current user

Watchlist

Method Path Auth Description
GET /watchlist Yes User's watchlist
POST /watchlist Yes { movieId, movieTitle, mediaType, posterPath }
GET /watchlist/check/:movieId Yes { saved: boolean }
DELETE /watchlist/:id Yes Remove item

Comments

Method Path Auth Description
GET /comments/:movieId No All comments for a movie
POST /comments Yes { movieId, content, parentId? }
DELETE /comments/:id Yes Delete own comment

Ratings

Method Path Auth Description
GET /ratings/:movieId No { likes, dislikes } counts
GET /ratings/:movieId/mine Yes { rating: "like"|"dislike"|null }
POST /ratings Yes { movieId, type } → toggle

Health

Method Path Auth Description
GET /api/health No { status: "ok" }

Database Models (MongoDB/Mongoose)

User

  • email: String (unique, lowercase)
  • password: String (bcrypt hashed)
  • displayName: String
  • createdAt: Date

Watchlist

  • userId: String (indexed)
  • movieId: String
  • movieTitle: String
  • mediaType: String (default: "movie")
  • posterPath: String
  • createdAt: Date
  • Compound unique: (userId, movieId)

Comment

  • userId: String
  • userName: String
  • movieId: String (indexed)
  • content: String (max 1000)
  • parentId: ObjectId? (ref: Comment, for replies)
  • createdAt: Date

Rating

  • userId: String
  • movieId: String (indexed)
  • type: String (enum: "like", "dislike")
  • updatedAt: Date
  • Compound unique: (userId, movieId)

AI Integration (Groq)

  • Model: openai/gpt-oss-120b
  • SDK: openai npm package pointed at https://api.groq.com/openai/v1
  • Functions:
    • identifyMovieFromMedia(base64, mimeType) — vision recognition
    • identifyMovieFromText(description) — text-based identification
    • chatAssistant(messages) — conversational AI expert

External APIs

  • TMDB v3: Trending movies, genre discovery, search, details, watch providers
  • AniList GraphQL: Anime metadata search
  • Trace.moe: Frame-accurate anime scene identification

Deployment

Vercel (Frontend)

  1. Import GitHub repo: Benedict258/Cight
  2. Framework: auto-detected (Vite)
  3. Env vars: VITE_API_URL, VITE_GROQ_API_KEY, VITE_TMDB_API_KEY
  4. vercel.json handles SPA rewrites

Render (Backend)

  1. New → Blueprint → select repo
  2. render.yaml auto-provisions web service
  3. Set MONGODB_URL and FRONTEND_URL env vars
  4. JWT_SECRET auto-generated

MongoDB Atlas

  • Cluster: cluster0.vxpzdh0.mongodb.net
  • Database: cight
  • Network access: allow 0.0.0.0/0 for Render's dynamic IPs

Scripts

Command Description
npm run dev Vite dev server on port 3000
npm run build Production build to dist/
npm start Start backend API server (server/index.js)
npm run lint TypeScript type-checking

Design System

  • Brand color: #FF4E00 (orange)
  • Background: #0a0a0a (near-black)
  • Font: Inter (Google Fonts)
  • Aesthetic: Brutalist — uppercase, italic, tight tracking, grayscale images
  • Animations: Motion (Framer Motion)

Live URLs