Files
stream.ui/CLAUDE.md
lethdat cd9aab8979 feat(settings): add Billing, Danger Zone, Domains DNS, Notification, Player, and Security settings pages
- 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.
2026-03-01 22:49:30 +07:00

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 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/
  • @httpClientAdaptersrc/api/httpClientAdapter.server.ts (SSR) or .client.ts (browser)
  • @liteMqttsrc/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)