Skip to content

macedot/dldl

Repository files navigation

πŸ“₯ dldl - Video Downloader

A full-stack web application for downloading videos from YouTube and other platforms using yt-dlp.

Vue.js Zig Docker TypeScript ESLint Vitest


For autonomous agent development, see AGENTS.md for project conventions and commands.


πŸš€ Quick Start

Development Mode

# Start backend (Zig)
cd backend && zig build && ./zig-out/bin/dldl-backend

# Start frontend (Vue.js) in another terminal
cd frontend && npm install && npm run dev

Access the app at http://localhost:5173

🐳 Docker Deployment

# Build and start all services
docker-compose up -d

# View logs
docker-compose logs -f

Access the app at http://localhost


πŸ“ Project Structure

dldl/
β”œβ”€β”€ backend/              # Zig backend
β”‚   └── src/
β”‚       β”œβ”€β”€ main.zig      # Entry point
β”‚       β”œβ”€β”€ server.zig    # HTTP server
β”‚       β”œβ”€β”€ ytdlp.zig     # yt-dlp integration
β”‚       └── types.zig     # Type definitions
β”œβ”€β”€ frontend/             # Vue.js frontend
β”‚   └── src/
β”‚       β”œβ”€β”€ components/   # UI components
β”‚       β”œβ”€β”€ views/        # Page views
β”‚       └── stores/       # Pinia stores
β”œβ”€β”€ Dockerfile           # Container build
β”œβ”€β”€ docker-compose.yml   # Multi-container setup
β”œβ”€β”€ haproxy.cfg         # Load balancer config
└── SPEC.md             # Full specification

πŸ› οΈ Technology Stack

Layer Technology
Frontend Vue.js 3, Vite, TypeScript, Pinia
Backend Zig (std.http)
Download yt-dlp
Load Balancer HAProxy
Container Docker, Docker Compose
Testing Vitest, Playwright
Code Quality ESLint, Prettier, lint-staged, knip, jscpd

πŸ”Œ API Endpoints

Method Path Description
GET /health Health check
POST /api/info Get video info
POST /api/download Start download
GET /api/status/:id Download status

Example Usage

# Get video info
curl -X POST http://localhost:8080/api/info \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'

# Start download
curl -X POST http://localhost:8080/api/download \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "format_id": "best"}'

# Check status
curl http://localhost:8080/api/status/dl-1234567890

🐳 Docker Architecture

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚     HAProxy     β”‚
                    β”‚   (Port 80/8080) β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                   β”‚                   β”‚
    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
    β”‚  App 1  β”‚        β”‚  App 2  β”‚        β”‚  App 3  β”‚    ...
    β”‚ 1 CPU   β”‚        β”‚ 1 CPU   β”‚        β”‚ 1 CPU   β”‚
    β”‚  4GB    β”‚        β”‚  4GB    β”‚        β”‚  4GB    β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Each app instance is limited to 1 CPU core and 4GB RAM.


βš™οΈ Configuration

Environment Variables

Variable Default Description
PORT 8080 Server port
DOWNLOAD_DIR ./downloads Download directory
YTDLP_PATH yt-dlp yt-dlp executable path

HAProxy


πŸ“‹ Logging Guidelines

When adding logging to the application:

  1. Never log sensitive data: URLs, user inputs, or error messages containing user data
  2. Sanitize logs: Remove or mask any PII before logging
  3. Use structured logging: JSON format is preferred for production logs
  4. Log levels: Use appropriate levels (ERROR for failures, INFO for significant events, DEBUG for development)

Example: Safe Logging Pattern

// BAD - logs potentially sensitive data
console.error(`Failed to fetch: ${url}`);

// GOOD - logs only safe metadata
console.error(`Failed to fetch video info`, { error: 'network_timeout', timestamp: Date.now() });

πŸ”§ Technical Debt

This project tracks technical debt through TODO/FIXME comments. When adding technical debt:

  1. Link to issues: All TODO/FIXME comments must reference an issue: TODO(#123): description
  2. Use descriptive language: Explain why this is debt and what the ideal solution would be
  3. Prioritize: Include severity hints like TODO(high): or TODO(low):

Example TODO Format

// TODO(#45): Refactor to use a proper state management library
// Currently using localStorage directly - should be abstracted behind
// a service interface for better testability. Priority: medium.

πŸ”’ Secrets Management

This project uses environment variables for configuration. In production deployments:

  1. Never commit .env files - they are gitignored
  2. Use .env.example as a template for required variables
  3. Inject secrets via Docker using -e flags or docker-compose.override.yml
  4. For production, consider using Docker secrets or external secret managers

Docker Secrets Example

# docker-compose.prod.yml
services:
  app-1:
    environment:
      - PORT=8080
      - DOWNLOAD_DIR=/app/downloads
    # For production, use: --env-file or Docker secrets

πŸ§ͺ Development

Frontend

cd frontend
npm install
npm run dev      # Development server (port 5173)
npm run build    # Production build
npm run lint     # Run ESLint
npm run check    # Run all quality checks (lint, format, cpd, dead code)

Backend

cd backend
zig build        # Debug build
zig build -OReleaseSafe  # Release build

Testing

cd frontend
npm test              # Run unit tests (Vitest)
npm run test:coverage  # Run with coverage
npm run test:integration  # Run Playwright integration tests
npm run test:all      # Run all tests

Code Quality

The project enforces quality standards:

  • ESLint: TypeScript and Vue linting with complexity and naming conventions
  • Prettier: Code formatting
  • lint-staged: Auto-format on commit
  • knip: Dead code and unused dependency detection
  • jscpd: Copy-paste detection

Run all checks:

npm run check  # lint && format:check && cpd && dead

πŸ”„ CI/CD

Automated workflows run on every push to master:

Workflow Purpose
Release Run tests, build, publish Docker images
Security Scanning OWASP ZAP baseline scan
Observability Sentry monitoring and metrics
Documentation Auto-generate API docs and changelog
Dependabot Weekly dependency updates

See .github/workflows/ for details.


πŸ“Š Observability

Structured Logging

The frontend uses pino for structured JSON logging:

  • Development: Human-readable format with colors
  • Production: JSON format for log aggregation
  • Automatic redaction of sensitive fields (auth headers, cookies, passwords)

Error Tracking

Sentry integration for error tracking:

  • Configure via VITE_SENTRY_DSN environment variable
  • Enable via VITE_SENTRY_ENABLED=true
  • Captures exceptions, breadcrumbs, and session replays

Distributed Tracing

OpenTelemetry for request tracing:

  • Configure via VITE_OTEL_ENDPOINT environment variable
  • X-Request-ID propagation across services
  • Automatic span creation for API requests

Analytics

PostHog for product analytics:

  • Configure via VITE_POSTHOG_KEY environment variable
  • Enable via VITE_POSTHOG_ENABLED=true
  • Tracks user interactions and feature usage
  • Feature flags for progressive rollouts

Circuit Breakers

Built-in circuit breakers protect against cascading failures:

  • api: External API calls (threshold: 5 failures, reset: 60s)
  • download: yt-dlp subprocess calls

Metrics

Prometheus-compatible metrics available at runtime:

import { metricsApi } from './utils/metrics';
metricsApi.getMetricsJSON();
metricsApi.getMetrics();  // Prometheus text format

🚨 Alerting

Alerts are configured via:

  • Sentry issue creation for critical errors
  • GitHub Actions workflow for scheduled monitoring
  • PagerDuty/OpsGenie integration (configure secrets)

See docs/runbooks/ for incident response procedures.


πŸš€ Deployment

Feature Flags

The application uses PostHog feature flags for safe rollouts:

Release Process

  1. Trigger Release Workflow: Go to Actions > Release > Run workflow
  2. Select Version Type: patch, minor, or major
  3. Automated Steps:
    • Run tests
    • Build frontend
    • Generate changelog
    • Create Docker images
    • Publish GitHub Release

See docs/runbooks/rollback.md for rollback procedures.

Rollback Methods

Method Use Case Time
Disable Feature Flag Flag-related issues < 1 min
Git Revert Code issues 5-10 min
Docker Image Rollback Container issues 10-15 min
HAProxy Config Rollback Config issues 2-5 min

πŸ“ License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors