diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000..430d38e --- /dev/null +++ b/.github/README.md @@ -0,0 +1,63 @@ +# StreamVault Knowledge Base + +This directory contains comprehensive documentation and configuration for GitHub Copilot integration with StreamVault. + +## Files Overview + +### Core Configuration +- **`copilot.json`** - Main Copilot configuration with rules, allowlists, and features +- **`copilot_instructions.md`** - Detailed project context and development guidelines +- **`copilot_firewall_config.md`** - Network firewall configuration for external API access + +### Setup & Workflows +- **`workflows/copilot-setup-steps.yml`** - Automated setup workflow for Copilot environment +- **`workflows/copilot-autofix.yml`** - Automated code fixes and improvements +- **`COPILOT_SETUP.md`** - Developer guide for Copilot integration + +### Project Documentation +- **`CONTRIBUTING.md`** - Contribution guidelines and development workflow +- **`pull_request_template.md`** - PR template with review checklist + +## Quick Reference + +### For Developers +1. Read `COPILOT_SETUP.md` for initial setup +2. Follow `copilot_instructions.md` for coding guidelines +3. Use `CONTRIBUTING.md` for PR workflow + +### For Repository Admins +1. Configure firewall using `copilot_firewall_config.md` +2. Monitor `workflows/` for CI/CD integration +3. Update `copilot.json` for new features or rules + +### For Copilot Agent +- Primary instructions: `copilot_instructions.md` +- Configuration rules: `copilot.json` +- Project examples: `../examples/` +- Documentation: `../docs/` and `../README.md` + +## Integration Status + +βœ… **Configured Features:** +- Code review and analysis +- Security scanning and auto-remediation +- Pull request feedback and suggestions +- Auto-fix for common issues +- StreamVault-specific rules and patterns + +βœ… **Active Integrations:** +- GitHub Actions workflows +- TypeScript strict mode enforcement +- ESLint and Prettier integration +- Firebase, Stripe, and Clerk patterns +- Performance and security best practices + +πŸ”„ **Continuous Improvement:** +- Knowledge base updates with new patterns +- Rule refinement based on code review feedback +- Firewall allowlist optimization +- Developer workflow enhancement + +--- + +For questions or improvements to Copilot integration, see the repository maintainers or create an issue. \ No newline at end of file diff --git a/.github/copilot.json b/.github/copilot.json index 693e621..fd7aabe 100644 --- a/.github/copilot.json +++ b/.github/copilot.json @@ -1,13 +1,36 @@ { "version": "1.0", + "repository": { + "name": "StreamVault", + "description": "Next.js streaming platform with AI-powered content enhancement", + "type": "web-application", + "primary_language": "typescript", + "framework": "nextjs" + }, "copilot": { + "knowledge_base": { + "instructions_file": ".github/copilot_instructions.md", + "documentation_paths": [ + "README.md", + "docs/", + "CONTRIBUTING.md", + "lib/*/README.md" + ], + "examples_path": "examples/" + }, "features": { "code_review": { "enabled": true, "auto_comment": true, "security_analysis": true, "performance_analysis": true, - "best_practices": true + "best_practices": true, + "focus_areas": [ + "typescript_strict_mode", + "nextjs_app_router", + "security_best_practices", + "streaming_optimization" + ] }, "pull_request_analysis": { "enabled": true, @@ -16,15 +39,28 @@ "auto_fix": { "security_vulnerabilities": true, "code_style": true, - "dependency_updates": true - } + "dependency_updates": true, + "typescript_errors": true + }, + "review_checklist": [ + "Authentication and authorization", + "Input validation with Zod", + "Error handling patterns", + "Performance impact", + "Security considerations" + ] }, "security_scanning": { "enabled": true, "vulnerability_detection": true, "secret_scanning": true, "dependency_scanning": true, - "auto_remediation": true + "auto_remediation": true, + "custom_patterns": [ + "hardcoded_api_keys", + "insecure_random_generation", + "unvalidated_redirects" + ] } }, "rules": { @@ -85,10 +121,38 @@ "enforce_test_naming": true } }, + "context": { + "project_patterns": { + "api_routes": "app/api/**/*.ts", + "components": "components/**/*.tsx", + "hooks": "hooks/**/*.ts", + "lib": "lib/**/*.ts", + "types": "types/**/*.ts", + "tests": "tests/**/*.{ts,tsx}" + }, + "ignore_patterns": [ + "node_modules/", + ".next/", + "dist/", + "build/", + "coverage/", + "*.log" + ] + }, + "workflow": { + "setup_steps": ".github/workflows/copilot-setup-steps.yml", + "auto_fix": ".github/workflows/copilot-autofix.yml", + "required_checks": [ + "type-check", + "lint", + "test", + "build" + ] + }, "allowlist": { "external_domains": [ "fonts.googleapis.com", - "fonts.gstatic.com", + "fonts.gstatic.com", "cdn.jsdelivr.net", "unpkg.com", "api.stripe.com", @@ -97,17 +161,21 @@ "clerk.com", "*.clerk.accounts.dev", "firebase.googleapis.com", - "*.googleapis.com", - "storage.googleapis.com", + "firestore.googleapis.com", + "storage.googleapis.com", "cloudflare.com", + "api.cloudflare.com", + "videodelivery.net", "*.cloudflare.com" ], "npm_packages": [ "@clerk/nextjs", - "@google-cloud/storage", + "@google-cloud/storage", "@radix-ui/*", "@tanstack/react-query", + "@upstash/redis", "firebase", + "firebase-admin", "stripe", "next", "react", @@ -117,7 +185,9 @@ "hls.js", "lucide-react", "zod", - "zustand" + "zustand", + "dompurify", + "svix" ] }, "notifications": { @@ -137,18 +207,42 @@ "github_actions": { "enabled": true, "workflow_triggers": ["pull_request", "push"], - "auto_fix_commits": true + "auto_fix_commits": true, + "required_workflows": [ + "ci.yml", + "copilot-setup-steps.yml", + "copilot-autofix.yml" + ] }, "codeql": { "enabled": true, "custom_queries": true, - "sarif_upload": true + "sarif_upload": true, + "languages": ["typescript", "javascript"] }, "dependabot": { "enabled": true, "auto_merge_patches": true, - "security_updates_only": false + "security_updates_only": false, + "package_ecosystems": ["npm"] } + }, + "development": { + "package_manager": "pnpm", + "node_version": "22", + "commands": { + "install": "pnpm install --frozen-lockfile", + "dev": "pnpm dev", + "build": "pnpm build", + "test": "pnpm test", + "lint": "pnpm lint", + "type_check": "pnpm type-check" + }, + "environment_files": [ + ".env.example", + ".env.development.template", + ".env.production.template" + ] } } } diff --git a/.github/copilot_instructions.md b/.github/copilot_instructions.md new file mode 100644 index 0000000..b3a9eda --- /dev/null +++ b/.github/copilot_instructions.md @@ -0,0 +1,316 @@ +# StreamVault - GitHub Copilot Instructions + +## Project Overview + +StreamVault is a Next.js-based streaming platform that provides live video streaming, video-on-demand (VOD), and content management capabilities. This project combines modern web technologies with AI-powered content enhancement and comprehensive analytics. + +## Architecture & Technology Stack + +### Core Technologies +- **Framework**: Next.js 15.5.0 with App Router +- **Language**: TypeScript (strict mode) +- **Styling**: Tailwind CSS v4 + shadcn/ui components +- **Package Manager**: pnpm (required, not npm or yarn) +- **Runtime**: Node.js 22+ + +### Authentication & User Management +- **Primary**: Clerk authentication with JWT validation +- **Patterns**: Use `auth()` from `@clerk/nextjs/server` for server components +- **Middleware**: Clerk middleware in `middleware.ts` handles auth routing +- **Best Practices**: Always validate user roles and permissions + +### Database & Storage +- **Primary Database**: Firebase Firestore +- **File Storage**: Google Cloud Storage (GCS) +- **Caching**: Upstash Redis for session and performance caching +- **Connection**: Use Firebase Admin SDK for server-side operations + +### Payments & Subscriptions +- **Payment Processor**: Stripe +- **Webhook Validation**: Always verify Stripe webhook signatures +- **PCI Compliance**: Never store card data, use Stripe's secure vaults +- **Subscription Logic**: Implement proper trial periods and proration + +### Video Streaming & Processing +- **Live Streaming**: HLS (HTTP Live Streaming) protocol +- **CDN**: Cloudflare Stream for video delivery +- **Player**: HLS.js for browser playback +- **Transcoding**: Automatic quality adaptation +- **Security**: Signed URLs for premium content + +### AI & Machine Learning +- **Content Enhancement**: Automated thumbnails, tags, descriptions +- **Content Moderation**: Real-time chat and video content screening +- **Analytics**: AI-powered insights and recommendations +- **Copyright Detection**: Automated content matching and action + +## Development Guidelines + +### Code Quality Standards +- **TypeScript**: Use strict mode, avoid `any` types +- **ESLint**: Follow the configured rules, fix warnings before commits +- **Prettier**: Auto-formatting is enforced via husky hooks +- **Testing**: Maintain 80%+ coverage for new code + +### File Organization +``` +/app # Next.js App Router pages and API routes + /(dashboard) # Protected dashboard routes + /api # API route handlers +/components # React components (organized by feature) +/lib # Utility functions and services + /ai # AI/ML services + /analytics # Analytics and reporting + /auth # Authentication utilities + /database # Database operations + /streaming # Video streaming logic +/types # TypeScript type definitions +/hooks # Custom React hooks +/tests # Test files (unit, integration, e2e) +``` + +### API Development Best Practices +- **Validation**: Use Zod schemas for input validation +- **Error Handling**: Return consistent error responses +- **Authentication**: Verify user auth on protected endpoints +- **Rate Limiting**: Implement for public-facing endpoints +- **Logging**: Use structured logging for monitoring + +### Security Requirements +- **Input Validation**: Sanitize all user inputs with Zod +- **SQL Injection Prevention**: Use parameterized queries +- **XSS Protection**: Sanitize HTML content with DOMPurify +- **CSRF Protection**: Built into Next.js App Router +- **Secure Headers**: Configured in `next.config.js` +- **Secrets Management**: Use environment variables, never hardcode + +### Performance Best Practices +- **Core Web Vitals**: Monitor and optimize LCP, CLS, FID +- **Bundle Size**: Keep JavaScript bundles under budget +- **Image Optimization**: Use Next.js Image component +- **Lazy Loading**: Implement for non-critical components +- **Database Queries**: Use Firebase query optimization + +### Streaming-Specific Guidelines +- **HLS Implementation**: Follow Apple's HLS specification +- **Quality Adaptation**: Implement adaptive bitrate streaming +- **Latency**: Minimize for live streaming scenarios +- **CDN**: Leverage Cloudflare for global content delivery +- **Monitoring**: Track stream health and performance metrics + +## Common Patterns & Examples + +### Authentication Check +```typescript +import { auth } from '@clerk/nextjs/server' + +export async function GET() { + const { userId } = await auth() + if (!userId) { + return new Response('Unauthorized', { status: 401 }) + } + // ... authenticated logic +} +``` + +### Database Operations +```typescript +import { db } from '@/lib/firebase-admin' +import { z } from 'zod' + +const schema = z.object({ + title: z.string().min(1), + description: z.string().optional() +}) + +export async function POST(request: Request) { + const data = schema.parse(await request.json()) + const docRef = await db.collection('videos').add(data) + return Response.json({ id: docRef.id }) +} +``` + +### Stripe Webhook Validation +```typescript +import Stripe from 'stripe' + +export async function POST(request: Request) { + const body = await request.text() + const signature = request.headers.get('stripe-signature')! + + let event: Stripe.Event + try { + event = stripe.webhooks.constructEvent(body, signature, webhookSecret) + } catch (error) { + return new Response('Invalid signature', { status: 400 }) + } + // ... handle webhook +} +``` + +### Error Handling +```typescript +try { + // risky operation +} catch (error) { + console.error('Operation failed:', error) + return Response.json( + { error: 'Operation failed', message: error instanceof Error ? error.message : String(error) }, + { status: 500 } + ) +} +``` + +## Environment Configuration + +### Required Environment Variables +```bash +# Authentication +NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... +CLERK_SECRET_KEY=sk_test_... + +# Database +FIREBASE_SERVICE_ACCOUNT={"type": "service_account"...} +NEXT_PUBLIC_FIREBASE_CONFIG={"apiKey": "..."} + +# Storage +GCP_PROJECT_ID=your-project-id +GCS_BUCKET_NAME=streamvault-videos + +# Payments +STRIPE_SECRET_KEY=sk_test_... +STRIPE_WEBHOOK_SECRET=whsec_... + +# Streaming +CLOUDFLARE_API_TOKEN=your-token +CLOUDFLARE_ACCOUNT_ID=your-account-id +``` + +### Development Setup +1. Use `pnpm install` (not npm or yarn) +2. Copy `.env.example` to `.env.local` +3. Configure Firebase, Clerk, and Stripe credentials +4. Run `pnpm dev` for development server +5. Run `pnpm test` to verify setup + +## Testing Strategy + +### Unit Tests (Jest) +- Test utility functions and business logic +- Mock external dependencies (Stripe, Firebase) +- Focus on edge cases and error handling + +### Integration Tests +- Test API endpoints with realistic data +- Verify database operations and queries +- Test authentication and authorization flows + +### E2E Tests (Playwright) +- Test complete user journeys +- Verify streaming functionality works +- Test payment and subscription flows + +### Performance Tests +- Monitor Core Web Vitals +- Test streaming latency and quality +- Verify database query performance + +## Deployment & Infrastructure + +### Staging Environment +- Vercel deployment with preview branches +- Test Firebase project for safe experimentation +- Stripe test mode for payment testing +- Real but limited external service usage + +### Production Environment +- Vercel production deployment +- Production Firebase project with security rules +- Stripe live mode with webhook validation +- Full CDN and monitoring setup +- Performance monitoring and alerting + +## Monitoring & Analytics + +### Application Monitoring +- Error tracking and performance monitoring +- User analytics and streaming metrics +- Business intelligence and revenue tracking +- Content performance and engagement analytics + +### Security Monitoring +- Failed authentication attempts +- Suspicious payment activity +- Content moderation alerts +- API rate limiting and abuse detection + +## AI Integration Guidelines + +### Content Enhancement +- Automated thumbnail generation from video frames +- AI-generated titles and descriptions +- Smart tagging and categorization +- Quality analysis and recommendations + +### Content Moderation +- Real-time chat message filtering +- Video content scanning for inappropriate material +- Copyright detection and automated actions +- Community guideline enforcement + +### Analytics & Insights +- Viewer behavior analysis and recommendations +- Performance optimization suggestions +- Revenue optimization insights +- Content strategy recommendations + +## Common Issues & Solutions + +### Authentication Problems +- Verify Clerk environment variables are set correctly +- Check middleware configuration in `middleware.ts` +- Ensure proper `await auth()` usage in server components + +### Database Connection Issues +- Verify Firebase service account JSON is properly formatted +- Check Firestore security rules allow operations +- Ensure proper error handling for connection failures + +### Streaming Issues +- Verify HLS.js is properly initialized +- Check Cloudflare Stream API credentials +- Monitor CDN cache and purging behavior +- Verify video transcoding completion + +### Payment Integration Issues +- Always verify Stripe webhook signatures +- Handle idempotency for webhook events +- Test subscription lifecycle thoroughly +- Monitor failed payment handling + +## Contributing Guidelines + +### Pull Request Requirements +- All tests must pass (unit, integration, e2e) +- Code must pass ESLint and TypeScript checks +- New features require corresponding tests +- Documentation updates for API changes +- Security review for payment/auth changes + +### Code Review Checklist +- Verify proper error handling and logging +- Check for security vulnerabilities +- Ensure performance best practices +- Validate TypeScript usage and type safety +- Review test coverage for new code + +### Release Process +- Staging deployment and testing +- Performance verification and monitoring +- Database migration validation +- Third-party service configuration +- Rollback procedures and monitoring + +--- + +This document should be kept up-to-date as the project evolves. When adding new features or changing architecture, update these instructions to help Copilot provide better assistance. \ No newline at end of file diff --git a/copilot_firewall_config.md b/copilot_firewall_config.md index 0e40583..832715f 100644 --- a/copilot_firewall_config.md +++ b/copilot_firewall_config.md @@ -1,32 +1,179 @@ -# Customizing or disabling the firewall for GitHub Copilot coding agent - -Copilot coding agent uses an outbound firewall by default to reduce data exfiltration risk. You can keep the recommended allowlist and add a minimal custom allowlist for required third‑party APIs. - -Where to configure -- Repository Settings β†’ Code & automation β†’ Copilot β†’ coding agent - -Recommended settings -- Enable firewall: ON -- Recommended allowlist: ON -- Custom allowlist: add only what you need - -Suggested custom allowlist for StreamVault -- Cloudflare Stream API (narrow URL is safer): - - https://api.cloudflare.com/client/v4/accounts//stream/ - - Or broader: Domain: api.cloudflare.com -- Playback CDN (if tests fetch sample content): - - Domain: videodelivery.net -- Stripe API (use test keys in CI): - - Domain: api.stripe.com -- Google/Firebase (only those used by tests/build): - - Domains: firestore.googleapis.com, firebase.googleapis.com, storage.googleapis.com - -How the firewall behaves -- If a blocked request occurs, Copilot will add a warning to the PR or comment indicating the blocked address and the command that attempted it. Use that signal to refine the allowlist. - -Disabling the firewall (not recommended) -- Toggle "Enable firewall" to OFF. This allows the agent to connect to any host and increases exfiltration risk. Prefer targeted allowlisting. - -Notes -- Larger runners and self-hosted runners: Copilot supports GitHub‑hosted Ubuntu x64 runners only. To use larger runners, provision them first in Settings β†’ Actions β†’ Runners β†’ Larger runners, then update the `runs-on` label in `.github/workflows/copilot-setup-steps.yml`. -- Git LFS: The setup workflow checks out with `lfs: true` to ensure LFS objects are available to the agent. \ No newline at end of file +# GitHub Copilot Firewall Configuration for StreamVault + +This document provides configuration guidance for the GitHub Copilot coding agent firewall to ensure StreamVault's development workflow runs smoothly while maintaining security. + +## Overview + +GitHub Copilot coding agent uses an outbound firewall by default to reduce data exfiltration risk. The firewall blocks network requests to external services unless explicitly allowed through an allowlist. + +## Configuration Location + +Configure the firewall in your GitHub repository: +- **Path**: Repository Settings β†’ Code & automation β†’ Copilot β†’ coding agent +- **Access**: Repository admin permissions required + +## Recommended Settings for StreamVault + +### Basic Configuration +- **Enable firewall**: βœ… ON (recommended for security) +- **Recommended allowlist**: βœ… ON (includes common developer tools) +- **Custom allowlist**: Add StreamVault-specific services only + +### StreamVault Custom Allowlist + +#### Authentication Services +- **Clerk Authentication**: + - Domain: `clerk.com` + - Domain: `*.clerk.accounts.dev` + - Domain: `*.clerk.dev` + +#### Video Streaming & CDN +- **Cloudflare Stream API** (prefer narrow URLs): + - URL: `https://api.cloudflare.com/client/v4/accounts//stream/` + - Alternative broader: Domain: `api.cloudflare.com` +- **Video Playback CDN**: + - Domain: `videodelivery.net` + - Domain: `*.cloudflare.com` (for additional CDN endpoints) + +#### Payment Processing +- **Stripe API** (use test keys in CI/CD): + - Domain: `api.stripe.com` + - Domain: `checkout.stripe.com` + - Domain: `js.stripe.com` + +#### Database & Storage +- **Google Firebase/Firestore**: + - Domain: `firestore.googleapis.com` + - Domain: `firebase.googleapis.com` + - Domain: `storage.googleapis.com` +- **Google Cloud APIs**: + - Domain: `*.googleapis.com` (broader, use with caution) + +#### Development & Monitoring +- **Package Registries**: + - Domain: `registry.npmjs.org` (for pnpm/npm) + - Domain: `cdn.jsdelivr.net` (CDN for packages) + - Domain: `unpkg.com` (alternative CDN) +- **Fonts & Assets**: + - Domain: `fonts.googleapis.com` + - Domain: `fonts.gstatic.com` + +#### Optional Services (add as needed) +- **AI Services** (if using): + - Domain: `api.openai.com` + - Domain: `generativelanguage.googleapis.com` (Google AI) +- **Analytics** (if implementing): + - Domain: `www.googletagmanager.com` + - Domain: `analytics.google.com` + +## Firewall Behavior + +### When Requests are Blocked +- Copilot will add a warning comment to PRs indicating: + - The blocked domain/URL + - The specific command that attempted the request + - Suggested allowlist additions + +### Monitoring and Refinement +1. **Monitor PR comments** for blocked request warnings +2. **Evaluate necessity** of each blocked service +3. **Add minimal allowlist entries** for legitimate services +4. **Avoid overly broad domains** when possible + +## Security Best Practices + +### Allowlist Management +- βœ… **Use specific URLs** over broad domains when possible +- βœ… **Regular review** of allowlist entries +- βœ… **Remove unused entries** during maintenance +- ❌ **Avoid wildcards** unless absolutely necessary + +### Environment Considerations +- **Development**: More permissive for productivity +- **CI/CD**: Minimal allowlist for build/test requirements +- **Production**: Not applicable (firewall affects Copilot only) + +### API Key Security +- βœ… **Use test/sandbox keys** in CI/CD environments +- βœ… **Rotate keys regularly** according to service recommendations +- ❌ **Never commit real API keys** to version control + +## Troubleshooting Common Issues + +### Build Failures Due to Blocked Requests +**Symptoms**: CI/CD workflows fail with network errors +**Solution**: Check Copilot comments for blocked domains, add to allowlist + +### Package Installation Issues +**Symptoms**: `pnpm install` or similar commands fail +**Solution**: Ensure `registry.npmjs.org` is in allowlist + +### Firebase/Database Connection Issues +**Symptoms**: Database operations fail during Copilot analysis +**Solution**: Add Firebase/Google Cloud domains to allowlist + +### Stripe Webhook Testing Issues +**Symptoms**: Payment integration tests fail +**Solution**: Add Stripe domains and ensure test keys are used + +## Alternative: Disabling the Firewall + +**⚠️ Not Recommended for StreamVault** + +To disable the firewall entirely: +- Toggle "Enable firewall" to OFF in repository settings +- This allows unrestricted network access but increases security risks +- Consider this only for private repositories with trusted contributors + +## Advanced Configuration + +### Larger Runners +- **Default**: GitHub-hosted Ubuntu runners supported +- **Larger runners**: Provision in Settings β†’ Actions β†’ Runners β†’ Larger runners +- **Configuration**: Update `runs-on` label in `.github/workflows/copilot-setup-steps.yml` + +### Git LFS Support +- **Enabled by default** in our setup workflow +- **Configuration**: `lfs: true` in checkout action +- **Purpose**: Ensures large files are available to Copilot + +### Webhook Configuration +When Copilot firewall blocks requests, consider configuring webhooks for: +- Real-time allowlist updates +- Automated PR comment responses +- Integration with monitoring tools + +## Monitoring and Maintenance + +### Regular Review Schedule +- **Weekly**: Check for new blocked request warnings +- **Monthly**: Review and cleanup allowlist entries +- **Quarterly**: Audit security and update documentation + +### Metrics to Track +- Number of blocked requests per week +- Build failure rate due to network issues +- Developer productivity impact +- Security incident prevention + +### Documentation Updates +Keep this document current with: +- New service integrations +- Changed API endpoints +- Updated security requirements +- Lessons learned from blocked requests + +--- + +## Support + +For firewall configuration issues: + +1. **Check GitHub Actions logs** for specific error messages +2. **Review Copilot PR comments** for blocked request details +3. **Contact repository maintainers** for allowlist updates +4. **Reference GitHub Copilot documentation** for advanced configuration + +--- + +**Last updated**: Always review and update when adding new external service integrations to StreamVault. \ No newline at end of file diff --git a/examples/common-patterns.md b/examples/common-patterns.md new file mode 100644 index 0000000..821e722 --- /dev/null +++ b/examples/common-patterns.md @@ -0,0 +1,573 @@ +# StreamVault - Common Patterns & Examples + +This file provides code examples and patterns commonly used in StreamVault to help GitHub Copilot understand the project conventions and provide better suggestions. + +## Authentication Patterns + +### Server-Side Authentication Check +```typescript +// app/api/streams/[streamId]/route.ts +import { auth } from '@clerk/nextjs/server' +import { NextRequest } from 'next/server' + +export async function GET( + request: NextRequest, + { params }: { params: { streamId: string } } +) { + try { + const { userId } = await auth() + if (!userId) { + return Response.json({ error: 'Unauthorized' }, { status: 401 }) + } + + // Your authenticated logic here + return Response.json({ streamId: params.streamId, userId }) + } catch (error) { + return Response.json( + { + error: 'Authentication failed', + message: error instanceof Error ? error.message : String(error) + }, + { status: 500 } + ) + } +} +``` + +### Client-Side Authentication Hook +```typescript +// hooks/use-auth.ts +import { useUser } from '@clerk/nextjs' + +export function useAuthenticatedUser() { + const { user, isLoaded, isSignedIn } = useUser() + + if (!isLoaded) { + return { user: null, loading: true, isAuthenticated: false } + } + + return { + user: isSignedIn ? user : null, + loading: false, + isAuthenticated: isSignedIn + } +} +``` + +## Database Operations (Firebase) + +### Firestore Query with Validation +```typescript +// lib/database/streams.ts +import { db } from '@/lib/firebase-admin' +import { z } from 'zod' + +const createStreamSchema = z.object({ + title: z.string().min(1, 'Title is required'), + description: z.string().optional(), + isLive: z.boolean().default(false), + categoryId: z.string().optional() +}) + +export async function createStream(userId: string, data: unknown) { + const validatedData = createStreamSchema.parse(data) + + const streamData = { + ...validatedData, + userId, + createdAt: new Date(), + updatedAt: new Date(), + viewCount: 0, + status: 'draft' as const + } + + const docRef = await db.collection('streams').add(streamData) + return { id: docRef.id, ...streamData } +} + +export async function getUserStreams(userId: string) { + const snapshot = await db + .collection('streams') + .where('userId', '==', userId) + .orderBy('createdAt', 'desc') + .get() + + return snapshot.docs.map(doc => ({ + id: doc.id, + ...doc.data() + })) +} +``` + +### Firestore Transaction Pattern +```typescript +// lib/database/transactions.ts +import { db } from '@/lib/firebase-admin' + +export async function updateStreamViewCount(streamId: string) { + const streamRef = db.collection('streams').doc(streamId) + + await db.runTransaction(async (transaction) => { + const doc = await transaction.get(streamRef) + if (!doc.exists) { + throw new Error('Stream not found') + } + + const currentViews = doc.data()?.viewCount || 0 + transaction.update(streamRef, { + viewCount: currentViews + 1, + updatedAt: new Date() + }) + }) +} +``` + +## Stripe Payment Integration + +### Webhook Validation Pattern +```typescript +// app/api/webhooks/stripe/route.ts +import { stripe } from '@/lib/stripe' +import { headers } from 'next/headers' + +const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET! + +export async function POST(request: Request) { + const body = await request.text() + const signature = headers().get('stripe-signature')! + + let event: Stripe.Event + + try { + event = stripe.webhooks.constructEvent(body, signature, webhookSecret) + } catch (error) { + console.error('Webhook signature verification failed:', error) + return Response.json( + { error: 'Invalid signature' }, + { status: 400 } + ) + } + + switch (event.type) { + case 'customer.subscription.created': + await handleSubscriptionCreated(event.data.object) + break + case 'customer.subscription.updated': + await handleSubscriptionUpdated(event.data.object) + break + default: + console.log(`Unhandled event type: ${event.type}`) + } + + return Response.json({ received: true }) +} +``` + +### Subscription Management +```typescript +// lib/payments/subscriptions.ts +import { stripe } from '@/lib/stripe' + +export async function createSubscription(customerId: string, priceId: string) { + try { + const subscription = await stripe.subscriptions.create({ + customer: customerId, + items: [{ price: priceId }], + payment_behavior: 'default_incomplete', + expand: ['latest_invoice.payment_intent'], + }) + + return subscription + } catch (error) { + console.error('Subscription creation failed:', error) + throw new Error('Failed to create subscription') + } +} +``` + +## Video Streaming (HLS) + +### HLS Player Component +```typescript +// components/player/hls-player.tsx +'use client' + +import { useEffect, useRef, useState } from 'react' +import Hls from 'hls.js' + +interface HLSPlayerProps { + src: string + poster?: string + autoPlay?: boolean + controls?: boolean +} + +export function HLSPlayer({ src, poster, autoPlay = false, controls = true }: HLSPlayerProps) { + const videoRef = useRef(null) + const hlsRef = useRef(null) + const [error, setError] = useState(null) + + useEffect(() => { + const video = videoRef.current + if (!video) return + + if (Hls.isSupported()) { + const hls = new Hls({ + enableWorker: false, // Disable for better compatibility + }) + + hlsRef.current = hls + + hls.loadSource(src) + hls.attachMedia(video) + + hls.on(Hls.Events.ERROR, (event, data) => { + if (data.fatal) { + setError(`HLS Error: ${data.details}`) + } + }) + } else if (video.canPlayType('application/vnd.apple.mpegurl')) { + video.src = src + } else { + setError('HLS is not supported in this browser') + } + + return () => { + if (hlsRef.current) { + hlsRef.current.destroy() + } + } + }, [src]) + + if (error) { + return
Error: {error}
+ } + + return ( +