- 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.
7.8 KiB
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
# 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
httpClientAdapterandliteMqtt
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
PiniaSharedStateplugin
API Client Architecture
The API client (src/api/client.ts) is auto-generated from OpenAPI spec:
- Uses
customFetchadapter that differs between client/server - Server adapter (
httpClientAdapter.server.ts): Forwards cookies viahono/context-storage, merges headers, callshttps://api.pipic.fun - Client adapter (
httpClientAdapter.client.ts): Standard fetch withcredentials: "include" - API proxy route:
/r/*paths proxy tohttps://api.pipic.funviaapiProxyMiddleware - Base API URL constant:
baseAPIURL = "https://api.pipic.fun"
Routing Structure
Routes are defined in src/routes/index.ts with three main layouts:
- Public (
/): Landing page, terms, privacy - Auth (
/login,/sign-up,/forgot): Authentication pages (redirects if logged in) - 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-animatedfor 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
useAuthStoremanages auth state with cookie-based sessionsinit()called on every request to fetch current user via/meendpointbeforeEachrouter 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.orgAPI for chunk uploads,/mergeendpoint for finalizing - Cancel support via XHR abort tracking
Type Safety
- TypeScript strict mode enabled
CloudflareBindingsinterface for environment variables (generated viacf-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 viais-mobileapiProxy.ts- Proxies/r/*requests to external API
Routes (src/server/routes/):
ssr.ts- Handles SSR rendering and state serializationdisplay.ts,merge.ts,manifest.ts,wellKnown.ts- API endpoints
Development Notes
- Always use
customFetchfrom@httpClientAdapterfor API calls, never raw fetch - The
honoContextis provided to Vue app for accessing request context in components - MQTT client in
src/lib/liteMqtt.ts(usingTinyMqttClient) 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)insrc/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.vueuses child components insrc/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
filledprop 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
- Button icons in PrimeVue components (e.g.,
- 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 (supportfilledprop)