Rindle.Domain.MediaProviderAsset (Rindle v0.1.5)

Copy Markdown View Source

Ecto schema for a provider-side asset row (Phase 33 — media_provider_assets).

One row per (asset, profile, provider). Tracks durable provider-side state (FSM lives in Rindle.Domain.ProviderAssetFSM) and the public-side playback_ids array.

Security invariant 14

Provider-internal identifiers (provider_asset_id, raw provider metadata) are treated as secrets at rest and in transit. The custom Inspect impl below redacts provider_asset_id to a last-4-char tag ("...abcd") and replaces raw_provider_metadata with %{redacted: true} so telemetry, log lines, and inspect/2 output never leak provider-internal state.

States

StateMeaning
"pending"Row created; create_asset/3 not yet invoked.
"uploading"Server-push or direct-creator upload in flight.
"processing"Provider is transcoding / preparing playback.
"ready"Provider asset is playable; playback_ids populated.
"errored"Provider sync failed; inspect last_sync_error.
"deleted"Soft-deleted; provider asset may already be purged.

See Rindle.Domain.ProviderAssetFSM for the locked transition allowlist.

Summary

Functions

Builds a changeset for a MediaProviderAsset row.

Redact a provider_asset_id to its last-4-character tag ("...abcd"). Returns nil for nil, "...redacted" for ids shorter than 4 chars.

Locked state vocabulary (matches Rindle.Domain.ProviderAssetFSM keys).

Types

t()

@type t() :: %Rindle.Domain.MediaProviderAsset{
  __meta__: term(),
  asset: term(),
  asset_id: term(),
  id: term(),
  ingest_mode: term(),
  inserted_at: term(),
  last_event_at: term(),
  last_event_id: term(),
  last_sync_error: term(),
  playback_ids: term(),
  playback_policy: term(),
  profile: term(),
  provider_asset_id: term(),
  provider_name: term(),
  raw_provider_metadata: term(),
  state: term(),
  updated_at: term()
}

Functions

changeset(asset, attrs)

@spec changeset(
  t()
  | %Rindle.Domain.MediaProviderAsset{
      __meta__: term(),
      asset: term(),
      asset_id: term(),
      id: term(),
      ingest_mode: term(),
      inserted_at: term(),
      last_event_at: term(),
      last_event_id: term(),
      last_sync_error: term(),
      playback_ids: term(),
      playback_policy: term(),
      profile: term(),
      provider_asset_id: term(),
      provider_name: term(),
      raw_provider_metadata: term(),
      state: term(),
      updated_at: term()
    },
  map()
) :: Ecto.Changeset.t()

Builds a changeset for a MediaProviderAsset row.

Casts the writable fields, requires the minimum invariants, validates the lifecycle state, enforces last_sync_error 4096-char truncation per D-09, and asserts the two unique constraints from D-10.

redact_id(id)

@spec redact_id(nil | String.t()) :: nil | String.t()

Redact a provider_asset_id to its last-4-character tag ("...abcd"). Returns nil for nil, "...redacted" for ids shorter than 4 chars.

Used by telemetry emit sites and log lines to enforce security invariant 14 (provider-internal identifiers never cross into adopter-facing telemetry, log lines, or inspect/2 output). The defimpl Inspect block below delegates to this helper so the Inspect rendering and the telemetry emit sites use the same redaction routine.

states()

@spec states() :: [String.t()]

Locked state vocabulary (matches Rindle.Domain.ProviderAssetFSM keys).