- Implemented Billing page with wallet balance, current plan, usage stats, available plans, and payment history. - Created Danger Zone page for account deletion and data clearing actions with confirmation prompts. - Developed Domains DNS page for managing whitelisted domains for iframe embedding, including add and remove functionality. - Added Notification Settings page to configure email, push, marketing, and Telegram notifications. - Introduced Player Settings page to customize video player behavior such as autoplay, loop, and controls visibility. - Established Security and Connected Accounts page for managing user profile, two-factor authentication, and connected accounts.
199 lines
7.8 KiB
Markdown
199 lines
7.8 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Holistream is a Vue 3 streaming application with Server-Side Rendering (SSR) deployed on Cloudflare Workers. It provides video upload, management, and streaming capabilities.
|
|
|
|
## Technology Stack
|
|
|
|
- **Framework**: Vue 3 with JSX/TSX support
|
|
- **Router**: Vue Router 5 with SSR-aware history
|
|
- **Server**: Hono framework on Cloudflare Workers
|
|
- **Build Tool**: Vite 7 with custom SSR plugin
|
|
- **Styling**: UnoCSS (Tailwind-like utility-first CSS)
|
|
- **UI Components**: PrimeVue 4 with Aura theme
|
|
- **State Management**: Pinia + Pinia Colada for server state
|
|
- **HTTP Client**: Auto-generated from OpenAPI spec via swagger-typescript-api
|
|
- **Package Manager**: Bun
|
|
|
|
## Common Commands
|
|
|
|
```bash
|
|
# Development server with hot reload
|
|
bun dev
|
|
|
|
# Production build (client + worker)
|
|
bun run build
|
|
|
|
# Preview production build locally
|
|
bun preview
|
|
|
|
# Deploy to Cloudflare Workers
|
|
bun run deploy
|
|
|
|
# Generate TypeScript types from Wrangler config
|
|
bun run cf-typegen
|
|
|
|
# View Cloudflare Worker logs
|
|
bun run tail
|
|
```
|
|
|
|
**Note**: The project uses Bun as the package manager. If using npm/yarn, replace `bun` with `npm run` or `yarn`.
|
|
|
|
## Architecture
|
|
|
|
### SSR Architecture
|
|
|
|
The app uses a custom SSR setup (`ssrPlugin.ts`) that:
|
|
- Builds the client bundle FIRST, then the Worker bundle
|
|
- Injects the Vite manifest into the server build for asset rendering
|
|
- Uses environment-based module resolution for `httpClientAdapter` and `liteMqtt`
|
|
|
|
Entry points:
|
|
- **Server**: `src/index.tsx` - Hono app that renders Vue SSR stream
|
|
- **Client**: `src/client.ts` - Hydrates the SSR-rendered app
|
|
|
|
### Module Aliases
|
|
|
|
- `@/` → `src/`
|
|
- `@httpClientAdapter` → `src/api/httpClientAdapter.server.ts` (SSR) or `.client.ts` (browser)
|
|
- `@liteMqtt` → `src/lib/liteMqtt.server.ts` (SSR) or `.ts` (browser)
|
|
|
|
### State Management Pattern
|
|
|
|
Uses **Pinia Colada** for server state with SSR hydration:
|
|
- Queries are fetched server-side and serialized to `window.__APP_DATA__`
|
|
- Client hydrates the query cache on startup via `hydrateQueryCache()`
|
|
- Pinia state is similarly serialized and restored via `PiniaSharedState` plugin
|
|
|
|
### API Client Architecture
|
|
|
|
The API client (`src/api/client.ts`) is auto-generated from OpenAPI spec:
|
|
- Uses `customFetch` adapter that differs between client/server
|
|
- Server adapter (`httpClientAdapter.server.ts`): Forwards cookies via `hono/context-storage`, merges headers, calls `https://api.pipic.fun`
|
|
- Client adapter (`httpClientAdapter.client.ts`): Standard fetch with `credentials: "include"`
|
|
- API proxy route: `/r/*` paths proxy to `https://api.pipic.fun` via `apiProxyMiddleware`
|
|
- Base API URL constant: `baseAPIURL = "https://api.pipic.fun"`
|
|
|
|
### Routing Structure
|
|
|
|
Routes are defined in `src/routes/index.ts` with three main layouts:
|
|
1. **Public** (`/`): Landing page, terms, privacy
|
|
2. **Auth** (`/login`, `/sign-up`, `/forgot`): Authentication pages (redirects if logged in)
|
|
3. **Dashboard**: Protected routes requiring auth
|
|
- `/overview` - Main dashboard
|
|
- `/upload` - Video upload
|
|
- `/video` - Video list
|
|
- `/video/:id` - Video detail/edit
|
|
- `/payments-and-plans` - Billing
|
|
- `/notification`, `/profile` - User settings
|
|
|
|
Route meta supports `@unhead/vue` for SEO: `meta: { head: { title, meta: [...] } }`
|
|
|
|
### Styling System (UnoCSS)
|
|
|
|
Configuration in `uno.config.ts`:
|
|
- **Presets**: Wind4 (Tailwind), Typography, Attributify, Bootstrap buttons
|
|
- **Custom colors**: `primary` (#14a74b), `accent`, `secondary` (#fd7906), `success`, `info`, `warning`, `danger`
|
|
- **Shortcuts**: `press-animated` for button press effects
|
|
- **Transformers**: `transformerCompileClass` (prefix: `_`), `transformerVariantGroup`
|
|
|
|
Use `cn()` from `src/lib/utils.ts` for conditional class merging (clsx + tailwind-merge).
|
|
|
|
### Component Auto-Import
|
|
|
|
Components in `src/components/` are auto-imported via `unplugin-vue-components`:
|
|
- PrimeVue components resolved via `PrimeVueResolver`
|
|
- Vue/Pinia/Vue Router APIs auto-imported via `unplugin-auto-import`
|
|
|
|
### Auth Flow
|
|
|
|
- `useAuthStore` manages auth state with cookie-based sessions
|
|
- `init()` called on every request to fetch current user via `/me` endpoint
|
|
- `beforeEach` router guard redirects unauthenticated users from protected routes
|
|
- MQTT client connects on user login for real-time notifications
|
|
|
|
### File Upload Architecture
|
|
|
|
Upload queue (`src/composables/useUploadQueue.ts`):
|
|
- Supports both local files and remote URLs
|
|
- Presigned POST URLs fetched from API
|
|
- Parallel chunk upload for large files
|
|
- Progress tracking with speed calculation
|
|
- **Chunk configuration**: 90MB chunks, max 3 parallel uploads, max 3 retries
|
|
- **Upload limits**: Max 5 items in queue
|
|
- Uses `tmpfiles.org` API for chunk uploads, `/merge` endpoint for finalizing
|
|
- Cancel support via XHR abort tracking
|
|
|
|
### Type Safety
|
|
|
|
- TypeScript strict mode enabled
|
|
- `CloudflareBindings` interface for environment variables (generated via `cf-typegen`)
|
|
- API types auto-generated from backend OpenAPI spec
|
|
|
|
### Environment Variables
|
|
|
|
Cloudflare Worker bindings (configured in `wrangler.jsonc`):
|
|
- No explicit secrets in code - use Wrangler secrets management
|
|
- `compatibility_date`: "2025-08-03"
|
|
- `compatibility_flags`: ["nodejs_compat"]
|
|
|
|
## Important File Locations
|
|
|
|
| Purpose | Path |
|
|
|---------|------|
|
|
| Server entry | `src/index.tsx` |
|
|
| Client entry | `src/client.ts` |
|
|
| App factory | `src/main.ts` |
|
|
| Router config | `src/routes/index.ts` |
|
|
| API client | `src/api/client.ts` |
|
|
| Auth store | `src/stores/auth.ts` |
|
|
| SSR plugin | `ssrPlugin.ts` |
|
|
| UnoCSS config | `uno.config.ts` |
|
|
| Wrangler config | `wrangler.jsonc` |
|
|
| Vite config | `vite.config.ts` |
|
|
|
|
## Server Structure
|
|
|
|
Middleware and routes are organized in `src/server/`:
|
|
|
|
**Middlewares** (`src/server/middlewares/`):
|
|
- `setup.ts` - Global middleware: `contextStorage`, CORS, mobile detection via `is-mobile`
|
|
- `apiProxy.ts` - Proxies `/r/*` requests to external API
|
|
|
|
**Routes** (`src/server/routes/`):
|
|
- `ssr.ts` - Handles SSR rendering and state serialization
|
|
- `display.ts`, `merge.ts`, `manifest.ts`, `wellKnown.ts` - API endpoints
|
|
|
|
## Development Notes
|
|
|
|
- Always use `customFetch` from `@httpClientAdapter` for API calls, never raw fetch
|
|
- The `honoContext` is provided to Vue app for accessing request context in components
|
|
- MQTT client in `src/lib/liteMqtt.ts` (using `TinyMqttClient`) handles real-time notifications
|
|
- Icons are custom Vue components in `src/components/icons/`
|
|
- Upload indicator is a global component showing queue status
|
|
- Root component uses error boundary wrapper: `withErrorBoundary(RouterView)` in `src/main.ts`
|
|
- **Testing & Linting**: There are currently no automated test suites (like Vitest) or linting tools (like ESLint/Prettier) configured.
|
|
|
|
## Code Organization
|
|
|
|
### Component Structure
|
|
|
|
- Keep view components small and focused - extract logical sections into child components
|
|
- Page views should compose child components, not contain all logic inline
|
|
- Example: `src/routes/settings/Settings.vue` uses child components in `src/routes/settings/components/`
|
|
- Components that exceed ~200 lines should be considered for refactoring
|
|
- Use `components/` subfolder pattern for page-specific components: `src/routes/{feature}/components/`
|
|
|
|
### Icons
|
|
|
|
- **Use custom SVG icon components** from `src/components/icons/` for UI icons (e.g., `Home`, `Video`, `Bell`, `SettingsIcon`)
|
|
- Custom icons are Vue components with `filled` prop for active/filled state
|
|
- PrimeIcons (`pi pi-*` class) should **only** be used for:
|
|
- Button icons in PrimeVue components (e.g., `icon="pi pi-check"`)
|
|
- Dialog/action icons where no custom SVG exists
|
|
- **Do NOT use** `<i class="pi pi-*">` for navigation icons, action buttons, or UI elements that have custom SVG equivalents
|
|
- When adding new icons, create SVG components in `src/components/icons/` following the existing pattern (support `filled` prop)
|