Skip to main content

repti-media Service

Media and content management
Service Type: Media & Content Service
Port: 8004
Database: repti_media_db
Status: Planned
Team Owner: Media Team

Purpose & Responsibilities

repti-media handles all media-related functionality, from file storage and processing to dynamic document generation and embeddable widgets for external websites.

Core Responsibilities

File Storage & Management

  • Image, video, and document uploads
  • CDN integration and optimization
  • File metadata and tagging
  • Storage lifecycle management
  • Access control and permissions

Media Processing

  • Image resizing and optimization
  • Video transcoding and compression
  • Thumbnail generation
  • Format conversion
  • Watermarking and branding

Dynamic Rendering

  • Pedigree chart generation (PDF, SVG, PNG)
  • Health certificate exports
  • Breeding record reports
  • Custom document templates
  • Print-optimized layouts

Embeddable Widgets

  • Animal profile cards
  • Pedigree tree widgets
  • Breeder showcase displays
  • Marketplace listing embeds
  • Real-time data integration

API Endpoints

File Management

POST   /upload                          # Upload files (images, videos, docs)
GET    /files/{file_id}                 # File details and metadata
PUT    /files/{file_id}                 # Update file metadata
DELETE /files/{file_id}                 # Delete file
GET    /files/{file_id}/download        # Download original file
POST   /files/batch                     # Batch file operations
GET    /files/search                    # Search files by metadata

Media Processing

POST   /process/images/{file_id}/resize # Resize image
POST   /process/images/{file_id}/optimize # Optimize image
POST   /process/videos/{file_id}/transcode # Video transcoding
GET    /process/status/{job_id}         # Processing job status
POST   /process/thumbnails              # Generate thumbnails
POST   /process/watermark               # Add watermarks

Document Rendering

POST   /render/pedigree/{animal_id}     # Generate pedigree chart
POST   /render/health-cert/{animal_id}  # Health certificate
POST   /render/breeding-report/{pair_id} # Breeding report
GET    /render/status/{render_id}       # Rendering job status
GET    /render/download/{render_id}     # Download rendered document
POST   /render/template                 # Custom template rendering

Embeddable Widgets

GET    /embed/animal/{animal_id}        # Animal profile widget
GET    /embed/pedigree/{animal_id}      # Pedigree tree widget
GET    /embed/breeder/{breeder_id}      # Breeder showcase
GET    /embed/listing/{listing_id}      # Marketplace listing
POST   /embed/configure                 # Widget configuration
GET    /embed/code/{widget_id}          # Embed code generation

CDN & Delivery

GET    /cdn/{file_id}                   # CDN-optimized file delivery
GET    /cdn/{file_id}/thumb             # Thumbnail delivery
GET    /cdn/{file_id}/preview           # Preview/medium size
GET    /stream/{video_id}               # Video streaming
GET    /download/{file_id}              # Secure download links

Database Schema

Core Tables

-- Main files table
CREATE TABLE files (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id UUID NOT NULL,
    uploaded_by UUID NOT NULL,
    original_filename VARCHAR(255) NOT NULL,
    file_type VARCHAR(100) NOT NULL,
    mime_type VARCHAR(100) NOT NULL,
    file_size_bytes BIGINT NOT NULL,
    file_hash VARCHAR(64) UNIQUE NOT NULL, -- SHA-256 for deduplication
    storage_path VARCHAR(500) NOT NULL,
    cdn_url VARCHAR(500),
    metadata JSONB DEFAULT '{}',
    tags VARCHAR(255)[] DEFAULT '{}',
    access_level VARCHAR(20) DEFAULT 'private',
    expiry_date TIMESTAMP WITH TIME ZONE,
    is_processed BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- File associations (link files to animals, breeding records, etc.)
CREATE TABLE file_associations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    file_id UUID REFERENCES files(id) ON DELETE CASCADE,
    entity_type VARCHAR(50) NOT NULL, -- 'animal', 'breeding_pair', 'organization'
    entity_id UUID NOT NULL,
    association_type VARCHAR(50) NOT NULL, -- 'profile_photo', 'health_record', 'certificate'
    display_order INTEGER DEFAULT 0,
    is_primary BOOLEAN DEFAULT FALSE,
    caption TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(file_id, entity_type, entity_id, association_type)
);

-- File versions for processed variants
CREATE TABLE file_versions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    original_file_id UUID REFERENCES files(id) ON DELETE CASCADE,
    version_type VARCHAR(50) NOT NULL, -- 'thumbnail', 'medium', 'watermarked'
    file_path VARCHAR(500) NOT NULL,
    cdn_url VARCHAR(500),
    dimensions JSONB, -- {width: 800, height: 600}
    file_size_bytes BIGINT,
    processing_params JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Processing jobs
CREATE TABLE processing_jobs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    file_id UUID REFERENCES files(id) ON DELETE CASCADE,
    job_type VARCHAR(50) NOT NULL, -- 'resize', 'transcode', 'thumbnail'
    status VARCHAR(20) DEFAULT 'queued',
    parameters JSONB DEFAULT '{}',
    progress_percent INTEGER DEFAULT 0,
    error_message TEXT,
    started_at TIMESTAMP WITH TIME ZONE,
    completed_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Processing templates for consistent operations
CREATE TABLE processing_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(100) UNIQUE NOT NULL,
    template_type VARCHAR(50) NOT NULL,
    parameters JSONB NOT NULL,
    description TEXT,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Rendering jobs for dynamic documents
CREATE TABLE rendering_jobs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id UUID NOT NULL,
    requested_by UUID NOT NULL,
    render_type VARCHAR(50) NOT NULL, -- 'pedigree', 'health_cert', 'breeding_report'
    entity_id UUID NOT NULL, -- animal_id, breeding_pair_id, etc.
    template_id UUID,
    output_format VARCHAR(10) NOT NULL, -- 'pdf', 'svg', 'png'
    parameters JSONB DEFAULT '{}',
    status VARCHAR(20) DEFAULT 'queued',
    output_file_id UUID REFERENCES files(id),
    error_message TEXT,
    started_at TIMESTAMP WITH TIME ZONE,
    completed_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Document templates
CREATE TABLE document_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(100) NOT NULL,
    template_type VARCHAR(50) NOT NULL,
    template_content TEXT NOT NULL, -- HTML/SVG template
    style_sheet TEXT, -- CSS for styling
    variables JSONB DEFAULT '{}', -- Template variables definition
    preview_image_id UUID REFERENCES files(id),
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Widget configurations
CREATE TABLE widget_configs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id UUID NOT NULL,
    widget_type VARCHAR(50) NOT NULL, -- 'animal_profile', 'pedigree_tree', 'breeder_showcase'
    entity_id UUID NOT NULL,
    title VARCHAR(255),
    configuration JSONB DEFAULT '{}',
    styling JSONB DEFAULT '{}',
    access_level VARCHAR(20) DEFAULT 'public',
    is_active BOOLEAN DEFAULT TRUE,
    embed_code_generated BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Widget usage analytics
CREATE TABLE widget_analytics (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    widget_id UUID REFERENCES widget_configs(id) ON DELETE CASCADE,
    event_type VARCHAR(50) NOT NULL, -- 'view', 'click', 'interaction'
    event_data JSONB DEFAULT '{}',
    referrer_url VARCHAR(500),
    user_agent TEXT,
    ip_address INET,
    occurred_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

Event Publishing & Subscriptions

Published Events

File Events:
  • file.uploaded - New file uploaded
  • file.processed - Processing completed
  • file.deleted - File removed
  • file.accessed - File downloaded/viewed
  • file.expired - File reached expiry date
Processing Events:
  • processing.started - Media processing began
  • processing.completed - Processing finished
  • processing.failed - Processing error occurred
  • processing.progress - Processing status update
Rendering Events:
  • render.pedigree.requested - Pedigree generation started
  • render.pedigree.completed - Pedigree chart ready
  • render.document.generated - Document created
  • render.failed - Rendering error
Widget Events:
  • embed.widget.created - New embeddable widget
  • embed.widget.viewed - Widget display tracked
  • embed.widget.interacted - Widget interaction
  • embed.code.generated - Embed code created
Content Events:
  • content.updated - Media content changed
  • content.published - Content made public
  • content.optimized - Media optimization completed

Event Subscriptions

  • animal.created - Generate placeholder images
  • animal.updated - Update associated media
  • lineage.updated - Regenerate pedigree charts
  • profile.updated - Refresh embeddable widgets
  • breeding.clutch.completed - Generate breeding reports

File Processing Pipeline

Image Processing

async def process_image(file_id: UUID, operations: List[str]):
    """
    Process uploaded images with various operations
    """
    file_info = await get_file_info(file_id)
    image_path = await download_from_storage(file_info.storage_path)
    
    processed_versions = []
    
    for operation in operations:
        if operation == "thumbnail":
            # Generate multiple thumbnail sizes
            for size in [(150, 150), (300, 300), (600, 600)]:
                thumbnail = await resize_image(image_path, size, crop=True)
                thumbnail_url = await upload_to_cdn(thumbnail, f"thumb_{size[0]}x{size[1]}")
                processed_versions.append({
                    "type": f"thumbnail_{size[0]}x{size[1]}",
                    "url": thumbnail_url,
                    "dimensions": size
                })
        
        elif operation == "optimize":
            # Optimize for web delivery
            optimized = await optimize_image(image_path, quality=85)
            optimized_url = await upload_to_cdn(optimized, "optimized")
            processed_versions.append({
                "type": "optimized",
                "url": optimized_url,
                "size_reduction": calculate_size_reduction(image_path, optimized)
            })
        
        elif operation == "watermark":
            # Add ReptiDex watermark
            watermarked = await apply_watermark(image_path, get_watermark_template())
            watermarked_url = await upload_to_cdn(watermarked, "watermarked")
            processed_versions.append({
                "type": "watermarked",
                "url": watermarked_url
            })
    
    # Update file record with processed versions
    await update_file_versions(file_id, processed_versions)
    await publish_event("file.processed", {"file_id": file_id, "versions": processed_versions})
    
    return processed_versions

Pedigree Chart Generation

async def generate_pedigree_chart(animal_id: UUID, format: str = "pdf", generations: int = 5):
    """
    Generate pedigree chart in requested format
    """
    # Get pedigree data from repti-animal service
    pedigree_data = await get_pedigree_data(animal_id, generations)
    
    if format == "svg":
        # Generate SVG for web display
        svg_content = await render_pedigree_svg(pedigree_data)
        return await save_rendered_document(svg_content, "image/svg+xml")
    
    elif format == "pdf":
        # Generate PDF for printing
        html_content = await render_pedigree_html(pedigree_data)
        pdf_content = await convert_html_to_pdf(html_content)
        return await save_rendered_document(pdf_content, "application/pdf")
    
    elif format == "png":
        # Generate PNG for sharing
        svg_content = await render_pedigree_svg(pedigree_data)
        png_content = await convert_svg_to_png(svg_content, width=1200)
        return await save_rendered_document(png_content, "image/png")
    
    else:
        raise ValueError(f"Unsupported format: {format}")

CDN & Performance Optimization

CDN Strategy

  • Global Distribution: CloudFront edge locations worldwide
  • Smart Caching: Intelligent cache TTL based on content type
  • Image Optimization: WebP conversion for modern browsers
  • Lazy Loading: Progressive image loading for better UX

Storage Optimization

  • Deduplication: SHA-256 hashing to prevent duplicate storage
  • Lifecycle Policies: Automatic archival of old files
  • Compression: Lossless compression for suitable file types
  • Hot/Cold Storage: Tiered storage based on access patterns

Security & Access Control

File Security

  • Access Control: Organization-scoped file permissions
  • Secure URLs: Time-limited signed URLs for private content
  • Virus Scanning: Automated malware detection on upload
  • Content Validation: File type and content verification

Privacy Controls

  • Visibility Levels: Public, organization-only, private settings
  • Watermarking: Automatic watermarks for protected content
  • Download Tracking: Complete audit trail of file access
  • EXIF Stripping: Remove metadata from uploaded images

Performance & Scaling

Processing Optimization

  • Async Processing: Background job processing with queues
  • Parallel Processing: Multi-threaded media operations
  • Caching: Processed version caching to avoid reprocessing
  • Smart Resizing: On-demand resizing with caching

Storage Scaling

  • Object Storage: Scalable S3-based file storage
  • CDN Integration: Global content delivery network
  • Bandwidth Optimization: Adaptive quality based on connection
  • Prefetching: Intelligent content prefetching

Integration Points

Internal Dependencies

  • repti-core: Authentication, configuration
  • repti-animal: Animal data for rendering
  • repti-commerce: Listing images and media

External Services

  • AWS S3: Primary file storage
  • CloudFront: CDN and content delivery
  • Image Processing: ImageMagick/PIL for processing
  • Video Processing: FFmpeg for video operations

Monitoring & Key Metrics

Performance Metrics

  • Upload Success Rate: File upload completion rate
  • Processing Time: Media processing duration
  • CDN Hit Rate: Cache effectiveness
  • Storage Utilization: Storage usage and growth

Business Metrics

  • Media Engagement: File view and download rates
  • Widget Performance: Embed widget usage analytics
  • Document Generation: Pedigree and report creation rates
  • Storage Costs: Cost optimization tracking

repti-media enables rich visual experiences across ReptiDex, from beautiful animal photos to professional pedigree charts and embeddable widgets that extend the platform’s reach to external websites.