Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
description: Code style, formatting, naming conventions, imports, and type rules
globs: ["src/**/*.ts", "src/**/*.tsx"]
description: Code style, formatting, naming conventions, imports, and type rules for the backend
globs: ["apps/backend/src/**/*.ts", "apps/backend/src/**/*.tsx"]
alwaysApply: true
---

# Code Style Rules
# Backend Code Style Rules

## Formatting (Prettier)

Expand Down Expand Up @@ -49,7 +49,7 @@ import { namespace } from './namespace';

## Type System

- Define shared types in `src/types/`
- Define shared types in `apps/backend/src/types/`
- Use `RouteItem<T>` generic for typed route definitions:
```typescript
type HomeRoute = RouteItem<{ code: number; data: HomeData[] }>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
description: Error handling patterns, status codes, and logging rules
globs: ["src/**/*.ts", "src/**/*.tsx"]
description: Error handling patterns, status codes, and logging rules for the backend
globs: ["apps/backend/src/**/*.ts", "apps/backend/src/**/*.tsx"]
alwaysApply: true
---

# Error Handling Rules
# Backend Error Handling Rules

## Status Codes

Expand Down Expand Up @@ -32,7 +32,6 @@ const handler = async (ctx) => {
const res = await someRequest(/* ... */);

if (res.code === 1) {
// Success path
return {
code: SUCCESS_CODE,
message: SEARCH_MESSAGE.SUCCESS,
Expand Down
34 changes: 16 additions & 18 deletions .cursor/rules/general.mdc → .cursor/rules/backend/general.mdc
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
description: General project overview, architecture, and development commands for VodHub
globs: ["**/*.ts", "**/*.tsx"]
description: General project overview, architecture, and development commands for the backend
globs: ["apps/backend/**/*.ts", "apps/backend/**/*.tsx"]
alwaysApply: true
---

# VodHub General Rules
# VodHub Backend — General Rules

## Project Overview

VodHub is a video aggregation API service built with **Hono** on Node.js. It normalizes multiple video source providers into a unified REST API supporting categories, search, details, and playback. TypeScript throughout, pnpm as package manager.
VodHub backend is a video aggregation API service built with **Hono** on Node.js. It is part of the VodHub pnpm monorepo (`apps/backend`). Normalizes multiple video source providers into a unified REST API supporting categories, search, details, and playback. TypeScript throughout, pnpm as package manager.

## Tech Stack

Expand All @@ -22,7 +22,7 @@ VodHub is a video aggregation API service built with **Hono** on Node.js. It nor
## Project Structure

```
src/
apps/backend/src/
index.ts # Server entry: boots @hono/node-server
app.tsx # Hono app: global middleware + route mounting
api/ # OpenAPI metadata routes
Expand All @@ -38,21 +38,19 @@ src/
## Development Commands

```bash
pnpm install # Install dependencies
pnpm dev # Start dev server with hot reload (tsx watch)
pnpm start # Start server without watch
pnpm install # Install all dependencies (monorepo root)
pnpm dev # Start both backend + frontend
pnpm dev:backend # Backend only (tsx watch)
pnpm --filter @vodhub/backend start # Start backend without watch
pnpm --filter @vodhub/backend lint # Lint backend
pnpm --filter @vodhub/backend lint:fix # Lint with auto-fix
pnpm --filter @vodhub/backend typecheck # Type check backend
pnpm format # Prettier write all apps
pnpm format:check # Prettier check all apps
pnpm commit # Interactive conventional commit
```

No test framework is configured. Linting and type checking:

```bash
npx eslint src/ --ext .ts,.tsx # Lint
npx eslint src/ --ext .ts,.tsx --fix # Lint with auto-fix
npx prettier --cache --write "src/**/*.{ts,tsx}" # Format
npx tsc --noEmit # Type check
```

Commits use **commitizen** with conventional commits. Run `pnpm commit` for the interactive prompt.
No test framework is configured.

## Route URL Pattern

Expand Down
10 changes: 5 additions & 5 deletions .cursor/rules/routes.mdc → .cursor/rules/backend/routes.mdc
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
description: Rules for creating and modifying provider routes in VodHub
globs: ["src/routes/**/*.ts"]
globs: ["apps/backend/src/routes/**/*.ts"]
alwaysApply: false
---

# Provider Route Rules

## Creating a New CMS Provider (Recommended)

For standard CMS sources, only `namespace.ts` and `index.ts` are needed:
For standard CMS sources, only `namespace.ts` and `index.ts` are needed in `apps/backend/src/routes/<provider-name>/`:

1. Create `src/routes/<provider-name>/` directory
1. Create `apps/backend/src/routes/<provider-name>/` directory
2. Add `namespace.ts` with provider metadata
3. Add `index.ts` that uses the factory:
```typescript
Expand All @@ -37,7 +37,7 @@ export const namespace: Namespace = {
For non-CMS sources, create individual route files. Each file exports a single `route` object:

```
src/routes/<provider>/
apps/backend/src/routes/<provider>/
namespace.ts
home.ts
homeVod.ts
Expand Down Expand Up @@ -99,7 +99,7 @@ Every route must conform to its typed `RouteItem<T>`:

## Registry Auto-Discovery

The registry (`src/routes/registry.ts`) auto-discovers routes via `directory-import`:
The registry (`apps/backend/src/routes/registry.ts`) auto-discovers routes via `directory-import`:
- `namespace` export → provider metadata
- `routes` export → array of route objects (from factory)
- `route` export → single route object (custom provider)
124 changes: 124 additions & 0 deletions .cursor/rules/frontend/rules/code-style.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
description: Frontend coding conventions and style guide
globs: ["apps/frontend/**/*.ts", "apps/frontend/**/*.tsx", "apps/frontend/**/*.scss"]
alwaysApply: true
---

# Frontend Code Style Rules

## TypeScript Rules
- Strict mode (`strict: true`)
- `any` is allowed (`@typescript-eslint/no-explicit-any: off`)
- `@ts-ignore` is allowed (`@typescript-eslint/ban-ts-comment: off`)
- Prefer `interface` for object types
- API responses use generics (`async get<T>(url, config): Promise<T>`)

## Naming Conventions
| Item | Convention | Example |
|---|---|---|
| Components | PascalCase | `InitProvider`, `VodList` |
| Hooks | camelCase + `use` prefix | `useIsMobile`, `useThemeStore` |
| Stores | camelCase + `use` + `Store` suffix | `useSettingStore` |
| Constants | UPPER_SNAKE_CASE | `DEFAULT_CONFIG` |
| Types | PascalCase | `HomeData`, `VodListProps` |
| Files | `.tsx` for components, `.ts` otherwise | |

## Import Order
Enforced by ESLint `import/order`:
1. Node built-in modules
2. External dependency packages
3. Internal modules (`@/`), parent, sibling, index

Blank line between each group, alphabetized within groups (case-insensitive).

```typescript
// Example
import { Button } from 'antd';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';

import useSettingStore from '@/lib/store/useSettingStore';
import { useVodSitesStore } from '@/lib/store/useVodSitesStore';
```

## Component Rules
- Client components must include `'use client'` directive
- Props defined with `interface` and destructured in params
- Components use `export default`

```typescript
'use client';
import { FC } from 'react';

export interface MyComponentProps {
title: string;
onClick?: () => void;
}

const MyComponent: FC<MyComponentProps> = ({ title, onClick }) => {
return <div onClick={onClick}>{title}</div>;
};

export default MyComponent;
```

## Styling Rules
- Use SCSS Modules (`index.module.scss`)
- Class names use `vod-next-` prefix
- **All colors must use CSS variables** — never hardcode hex/rgba values
- Ant Design components are preferred

```scss
// Correct: CSS variables
background: var(--color-bg-container);
color: var(--color-text-secondary);
border: 1px solid var(--color-border-secondary);

// Wrong: hardcoded colors
background: #0f0f23;
color: #94a3b8;
```

Available CSS variables (defined in `globals.scss`):
| Category | Variable | Description |
|---|---|---|
| Brand | `--color-primary` | Primary color |
| Brand | `--color-primary-light` | Light primary |
| Background | `--color-bg` | Page background |
| Background | `--color-bg-container` | Container background |
| Background | `--color-bg-elevated` | Elevated background |
| Background | `--color-bg-container-alpha` | Semi-transparent container |
| Background | `--color-bg-elevated-alpha` | Semi-transparent elevated |
| Background | `--color-bg-elevated-hover` | Hover state background |
| Text | `--color-text` | Primary text |
| Text | `--color-text-secondary` | Secondary text |
| Text | `--color-text-tertiary` | Tertiary text |
| Border | `--color-border` | Border |
| Border | `--color-border-secondary` | Secondary border |
| State | `--color-primary-alpha-low` | Selected state |
| State | `--color-primary-alpha-medium` | Border accent |
| State | `--color-primary-alpha-hover` | Hover state |
| State | `--color-primary-shadow` | Shadow |
| Overlay | `--color-overlay` | Overlay background |
| Overlay | `--color-overlay-border` | Overlay border |

## Themes
Three built-in themes defined in `lib/themes/index.ts`:
- **midnight**: Dark with red accent
- **aurora**: Light with cyan accent
- **cyber**: Dark with purple accent

Theme managed by `useThemeStore`, updates CSS variables and Ant Design theme config.

## State Management
- Zustand stores use `persist` middleware
- Store file naming: `use{Name}Store.ts`
- localStorage operations via `store2`

## Error Handling
- HTTP errors: rejected via interceptor (`Promise.reject(error)`)
- API calls: wrap in try/catch, re-throw as `Promise.reject`
- UI errors: display with Ant Design `message` component

## Formatting (Prettier)
- Single quotes, no trailing commas, 4-space indent, 200 char width, LF line endings, semicolons always
45 changes: 45 additions & 0 deletions .cursor/rules/frontend/rules/project.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
description: Project overview and tech stack for the frontend
globs: ["apps/frontend/**/*.ts", "apps/frontend/**/*.tsx", "apps/frontend/**/*.scss"]
alwaysApply: true
---

# VodHub Frontend — Project Overview

VodNext is the frontend of the VodHub monorepo, a video aggregation player built with Next.js.

## Core Features
- Next.js (React) with SSR and static generation
- Aggregates multiple video sources, supports category browsing, search, playback
- Multi-theme support (midnight, aurora, cyber)

## Tech Stack
- **Framework**: Next.js 16 + React 19 + TypeScript
- **State Management**: Zustand + Valtio
- **UI Library**: Ant Design 6
- **Styling**: SCSS Modules + CSS variables (multi-theme)
- **HTTP Client**: Axios
- **Video Player**: xgplayer + HLS.js
- **Package Manager**: pnpm (monorepo at root)

## Development Tools
- **Linting**: ESLint (eslint-config-next) + Prettier
- **Git Hooks**: Husky + lint-staged
- **Commits**: Commitlint + commitizen (conventional commits)

## Environment Requirements
- Node.js >= 24
- pnpm >= 10

## Development Commands

```bash
pnpm dev # Start both backend + frontend dev servers
pnpm dev:frontend # Frontend only (next dev)
pnpm --filter @vodhub/frontend build # Production build (standalone)
pnpm --filter @vodhub/frontend lint # ESLint check
pnpm --filter @vodhub/frontend typecheck # TypeScript type check
pnpm format # Prettier write all apps
pnpm format:check # Prettier check
pnpm commit # Interactive conventional commit
```
71 changes: 71 additions & 0 deletions .cursor/rules/frontend/rules/structure.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
description: Frontend directory structure and file organization
globs: ["apps/frontend/**/*.ts", "apps/frontend/**/*.tsx", "apps/frontend/**/*.scss"]
alwaysApply: true
---

# Frontend Structure

## Directory Layout

```
apps/frontend/
app/ # Next.js App Router pages
layout.tsx # Root layout
globals.scss # Global styles + CSS variables
layouts/ # Layout components (BasicLayout, header, disclaimer)
home/ # Home page
category/ # Category browsing
detail/ # Video detail
setting/ # Settings page
components/ # Shared components
providers/ # Context providers (InitProvider, ThemeProvider)
video/ # Video components (VodList, VodPalyer, VodSearch, VodSites, VodTypes)
icons/ # Custom SVG icon components
ui/ # UI utilities (Loading, ThemeSelector)
lib/ # Business logic and utilities
constant/ # Constants (llm.ts, site.ts, prompt.ts)
hooks/ # Custom hooks
store/ # Zustand stores
themes/ # Theme definitions (midnight, aurora, cyber)
types/ # TypeScript type definitions
utils/ # Utilities (HTTP request wrapper)
services/ # API service layer
index.ts # Service exports
vodhub/ # VodHub API calls
```

## File Organization

### Pages
- Located in `app/` using Next.js App Router
- Each page directory: `page.tsx` + optional `index.module.scss`
- Client components require `'use client'` directive

### Components
- Located in `components/` directory
- Component directory format: `ComponentName/index.tsx` + `index.module.scss`
- Props interfaces exported with `export interface`

### State Management
- Located in `lib/store/` directory
- File naming: `use{Name}Store.ts`
- Uses Zustand + `persist` middleware

### API Services
- Located in `services/` directory
- Organized by module (e.g., `vodhub/`)
- Uses generics for response types

### Styles
- SCSS Modules (`.module.scss`)
- Class names prefixed with `vod-next-`
- All colors use CSS variables from `globals.scss`

## Key File Locations
- Types: `lib/types/index.ts`
- HTTP wrapper: `lib/utils/request/index.ts`
- Theme config: `lib/themes/index.ts`
- Theme Provider: `components/providers/ThemeProvider.tsx`
- Theme store: `lib/store/useThemeStore.ts`
- Sites store: `lib/store/useVodSitesStore.ts`
Loading
Loading