BUCKYVERSE

Date: 2025-03-10

Status

Proposed

Context

The Codexis system needs sophisticated asset management for handling various types of assets (images, SVG files, cover images) across different output formats. The asset management system must handle:

  1. Asset discovery and classification
  2. Format-specific processing
  3. Optimization and compression
  4. Caching and reuse
  5. Validation and verification

Decision

We will implement a comprehensive asset management system with the following components:

1. Asset Registry

defmodule Codexis.Assets.Registry do
  use GenServer
  
  defmodule Asset do
    defstruct [:id, :path, :type, :metadata, :variants]
  end
  
  def start_link(opts) do
    GenServer.start_link(__MODULE__, opts, name: __MODULE__)
  end
  
  @impl true
  def init(_opts) do
    {:ok, %{assets: %{}, variants: %{}}}
  end
  
  def register_asset(path, type, metadata \\ %{}) do
    GenServer.call(__MODULE__, {:register, path, type, metadata})
  end
  
  def get_asset(id) do
    GenServer.call(__MODULE__, {:get, id})
  end
  
  def get_variant(asset_id, format) do
    GenServer.call(__MODULE__, {:get_variant, asset_id, format})
  end
end

2. Asset Processor Pipeline

defmodule Codexis.Assets.Processor do
  def process_asset(asset = %Asset{}) do
    with {:ok, asset} <- validate_asset(asset),
         {:ok, asset} <- optimize_asset(asset),
         {:ok, asset} <- generate_variants(asset) do
      {:ok, asset}
    end
  end
  
  defp validate_asset(asset) do
    case asset.type do
      :image -> validate_image(asset)
      :svg -> validate_svg(asset)
      :cover -> validate_cover(asset)
      _ -> {:error, :unsupported_asset_type}
    end
  end
  
  defp optimize_asset(asset) do
    case asset.type do
      :image -> optimize_image(asset)
      :svg -> optimize_svg(asset)
      :cover -> optimize_cover(asset)
      _ -> {:ok, asset}
    end
  end
  
  defp generate_variants(asset) do
    variants = 
      supported_formats(asset.type)
      |> Task.async_stream(fn format ->
        generate_variant(asset, format)
      end)
      |> Enum.reduce(%{}, fn {:ok, {format, path}}, acc ->
        Map.put(acc, format, path)
      end)
    
    {:ok, %{asset | variants: variants}}
  end
end

3. Asset Cache

defmodule Codexis.Assets.Cache do
  use GenServer
  
  @cache_dir "priv/asset_cache"
  
  def start_link(opts) do
    GenServer.start_link(__MODULE__, opts, name: __MODULE__)
  end
  
  @impl true
  def init(_opts) do
    File.mkdir_p!(@cache_dir)
    {:ok, %{}}
  end
  
  def get_cached(asset_id, variant) do
    GenServer.call(__MODULE__, {:get, asset_id, variant})
  end
  
  def cache_asset(asset_id, variant, path) do
    GenServer.cast(__MODULE__, {:cache, asset_id, variant, path})
  end
  
  def invalidate(asset_id) do
    GenServer.cast(__MODULE__, {:invalidate, asset_id})
  end
end

4. Asset Validation

defmodule Codexis.Assets.Validator do
  def validate_image(path) do
    with {:ok, info} <- identify_image(path),
         :ok <- validate_dimensions(info),
         :ok <- validate_format(info),
         :ok <- validate_color_space(info) do
      {:ok, info}
    end
  end
  
  def validate_svg(path) do
    with {:ok, doc} <- File.read(path),
         {:ok, parsed} <- parse_svg(doc),
         :ok <- validate_svg_structure(parsed) do
      {:ok, parsed}
    end
  end
  
  def validate_cover(path) do
    with {:ok, info} <- validate_image(path),
         :ok <- validate_cover_requirements(info) do
      {:ok, info}
    end
  end
end

5. Asset Optimization

defmodule Codexis.Assets.Optimizer do
  def optimize_image(path, options \\ []) do
    with {:ok, temp_path} <- create_temp_copy(path),
         :ok <- run_image_optimization(temp_path, options) do
      {:ok, temp_path}
    end
  end
  
  def optimize_svg(path, options \\ []) do
    with {:ok, content} <- File.read(path),
         {:ok, optimized} <- optimize_svg_content(content, options),
         {:ok, temp_path} <- write_temp_file(optimized) do
      {:ok, temp_path}
    end
  end
  
  defp run_image_optimization(path, options) do
    # Use image optimization tools based on format
  end
  
  defp optimize_svg_content(content, options) do
    # Use SVGO or similar tool
  end
end

Consequences

Positive

  1. Centralized Management: Single system for all asset handling
  2. Optimization: Automatic asset optimization for each format
  3. Caching: Efficient reuse of processed assets
  4. Validation: Comprehensive asset validation
  5. Parallelization: Concurrent asset processing

Negative

  1. Complexity: More complex than simple file operations
  2. Dependencies: Requires external tools for optimization
  3. Storage: Needs space for cached variants

Risks

  1. Performance: Must monitor processing overhead
  2. Storage Growth: Need strategy for cache cleanup
  3. Tool Dependencies: External tool version management

Compliance

Asset management must:

  1. Validate all assets before processing
  2. Optimize assets appropriately
  3. Generate required variants
  4. Maintain proper caching
  5. Clean up temporary files

Notes