Files
moreminimore-marketing/backend/docs/ASSET_TRACKING_IMPLEMENTATION.md
Kunthawat Greethong c35fa52117 Base code
2026-01-08 22:39:53 +07:00

9.0 KiB

Asset Tracking Implementation Guide

Overview

This document describes the production-ready implementation of asset tracking across all ALwrity modules. The unified Content Asset Library automatically tracks all AI-generated content (images, videos, audio, text) for easy management and organization.

Architecture

Core Components

  1. Database Models (backend/models/content_asset_models.py)

    • ContentAsset: Main model for tracking assets
    • AssetCollection: Collections/albums for organizing assets
    • AssetType: Enum (text, image, video, audio)
    • AssetSource: Enum (all ALwrity modules)
  2. Service Layer (backend/services/content_asset_service.py)

    • CRUD operations for assets
    • Search, filter, pagination
    • Usage tracking
  3. Utility Functions

    • backend/utils/asset_tracker.py: save_asset_to_library() helper
    • backend/utils/file_storage.py: Robust file saving utilities

Implementation Status

Completed Integrations

1. Story Writer (backend/api/story_writer/router.py)

  • Images: Tracks all scene images with metadata
  • Audio: Tracks all scene audio files with narration details
  • Videos: Tracks individual scene videos and complete story videos
  • Location: After generation in /generate-images, /generate-audio, /generate-video, /generate-complete-video
  • Metadata: Includes prompts, scene numbers, providers, models, costs, status

2. Image Studio (backend/api/images.py)

  • Image Generation: Tracks all generated images
  • Image Editing: Tracks all edited images
  • Location: After generation in /api/images/generate and /api/images/edit
  • Features:
    • Robust file saving with validation
    • Atomic file writes
    • Proper error handling (non-blocking)
    • File serving endpoint at /api/images/image-studio/images/{filename}

📝 Notes on Other Modules

Main Generation Services

  • Text Generation (main_text_generation.py): Returns strings, not files. If text content needs tracking, save to .txt or .md files first.
  • Video Generation (main_video_generation.py): Already integrated via Story Writer
  • Audio Generation (main_audio_generation.py): Already integrated via Story Writer

Social Writers

  • LinkedIn Writer: Generates text content (posts, articles). No file generation currently.
  • Facebook Writer: Generates text content (posts, stories, reels). No file generation currently.
  • Blog Writer: Generates blog content. May generate images in future.

Note: If these modules generate files in the future, follow the integration pattern below.

Integration Pattern

For Image Generation

from utils.asset_tracker import save_asset_to_library
from utils.file_storage import save_file_safely, generate_unique_filename
from sqlalchemy.orm import Session
from pathlib import Path

# After successful image generation
try:
    base_dir = Path(__file__).parent.parent
    output_dir = base_dir / "module_images"
    
    image_filename = generate_unique_filename(
        prefix="img_prompt",
        extension=".png",
        include_uuid=True
    )
    
    # Save file safely
    image_path, save_error = save_file_safely(
        content=result.image_bytes,
        directory=output_dir,
        filename=image_filename,
        max_file_size=50 * 1024 * 1024  # 50MB
    )
    
    if image_path and not save_error:
        image_url = f"/api/module/images/{image_path.name}"
        
        # Track in asset library (non-blocking)
        try:
            asset_id = save_asset_to_library(
                db=db,
                user_id=user_id,
                asset_type="image",
                source_module="module_name",
                filename=image_path.name,
                file_url=image_url,
                file_path=str(image_path),
                file_size=len(result.image_bytes),
                mime_type="image/png",
                title="Image Title",
                description="Image description",
                prompt=prompt,
                tags=["tag1", "tag2"],
                provider=result.provider,
                model=result.model,
                metadata={"status": "completed"}
            )
            logger.info(f"✅ Asset saved: ID={asset_id}")
        except Exception as e:
            logger.error(f"Asset tracking failed: {e}", exc_info=True)
            # Don't fail the request
except Exception as e:
    logger.error(f"File save failed: {e}", exc_info=True)
    # Continue - base64 is still available

For Video Generation

# After successful video generation
try:
    asset_id = save_asset_to_library(
        db=db,
        user_id=user_id,
        asset_type="video",
        source_module="module_name",
        filename=video_filename,
        file_url=video_url,
        file_path=str(video_path),
        file_size=file_size,
        mime_type="video/mp4",
        title="Video Title",
        description="Video description",
        prompt=prompt,
        tags=["video", "tag"],
        provider=provider,
        model=model,
        cost=cost,
        metadata={"duration": duration, "status": "completed"}
    )
except Exception as e:
    logger.error(f"Asset tracking failed: {e}", exc_info=True)

For Audio Generation

# After successful audio generation
try:
    asset_id = save_asset_to_library(
        db=db,
        user_id=user_id,
        asset_type="audio",
        source_module="module_name",
        filename=audio_filename,
        file_url=audio_url,
        file_path=str(audio_path),
        file_size=file_size,
        mime_type="audio/mpeg",
        title="Audio Title",
        description="Audio description",
        prompt=text,
        tags=["audio", "tag"],
        provider=provider,
        model=model,
        cost=cost,
        metadata={"status": "completed"}
    )
except Exception as e:
    logger.error(f"Asset tracking failed: {e}", exc_info=True)

Best Practices

1. Error Handling

  • Always non-blocking: Asset tracking failures should never break the main request
  • Log errors: Use logger.error() with exc_info=True for debugging
  • Graceful degradation: Continue with base64/file response even if tracking fails

2. File Management

  • Use save_file_safely(): Handles validation, atomic writes, directory creation
  • Sanitize filenames: Use sanitize_filename() to prevent path traversal
  • Unique filenames: Use generate_unique_filename() with UUIDs
  • File size limits: Enforce reasonable limits (50MB for images, 100MB for videos)

3. Database Sessions

  • Pass session explicitly: Use db: Session = Depends(get_db) in endpoints
  • Handle session lifecycle: Let FastAPI manage session cleanup
  • Background tasks: Get new session in background tasks

4. Metadata

  • Rich metadata: Include provider, model, dimensions, cost, status
  • Searchable tags: Use consistent tag naming (e.g., "image_studio", "generated")
  • Status tracking: Always include "status": "completed" in metadata

5. File URLs

  • Consistent patterns: Use /api/{module}/images/{filename} format
  • Serving endpoints: Create corresponding GET endpoints to serve files
  • Authentication: Protect file serving endpoints with get_current_user

File Storage Utilities

save_file_safely()

  • Validates file size
  • Creates directories automatically
  • Atomic writes (temp file + rename)
  • Returns (file_path, error_message) tuple

sanitize_filename()

  • Removes dangerous characters
  • Prevents path traversal
  • Limits filename length
  • Handles empty filenames

generate_unique_filename()

  • Creates unique filenames with UUIDs
  • Sanitizes prefix
  • Handles extensions properly

Testing Checklist

  • Images are saved to disk correctly
  • Files are accessible via serving endpoints
  • Asset tracking works (check database)
  • Errors don't break main requests
  • File size limits are enforced
  • Filenames are sanitized properly
  • Metadata is complete and accurate
  • Asset Library UI displays assets correctly

Future Enhancements

  1. Text Content Tracking: Save text content as files when needed
  2. Batch Operations: Track multiple assets in single transaction
  3. File Cleanup: Automatic cleanup of orphaned files
  4. Storage Backends: Support S3, GCS for production
  5. Thumbnail Generation: Auto-generate thumbnails for videos/images
  6. Compression: Compress large files before storage

Troubleshooting

Assets not appearing in library

  1. Check database: SELECT * FROM content_assets WHERE user_id = '...'
  2. Check logs for asset tracking errors
  3. Verify save_asset_to_library() returns asset ID
  4. Check file URLs are correct

File serving fails

  1. Verify file exists on disk
  2. Check serving endpoint is registered
  3. Verify authentication is working
  4. Check file permissions

Performance issues

  1. Use background tasks for heavy operations
  2. Batch database operations
  3. Consider async file I/O for large files
  4. Monitor database query performance