Skip to content

36 — TestimonialMediaAsset Model & Processing Pipeline (Blueprint §5.8)

Cursor-ready plan for media storage metadata, processing lifecycle, callback handling, and storefront-readiness guarantees.

36 — TestimonialMediaAsset Model & Processing Pipeline (Blueprint §5.8)

Section titled “36 — TestimonialMediaAsset Model & Processing Pipeline (Blueprint §5.8)”

Source: 02-Implementation-Blueprint.md§5.8 New model: TestimonialMediaAsset.

This document is a build spec only. No code changes are implied until a task references this file.

Related: 06 (public submission/upload), 10 (submission detail preview), 11/05 (published/storefront eligibility), 08 (security), 20 (schema migration flow).


Implement a robust media asset model and lifecycle so uploaded customer videos/photos move from raw upload to processing to storefront-ready playback with reliable metadata and failure visibility.


Blueprint §5.8 fields:

  • id
  • shopId
  • submissionId
  • storageProvider // stream | mux | s3
  • storageKey
  • playbackUrl
  • thumbnailUrl
  • mimeType
  • durationSec
  • width
  • height
  • fileSizeBytes
  • processingStatus // uploaded | processing | ready | failed
  • processingError
  • transcriptText
  • timestamps

Indexes:

  • @@index([submissionId])
  • @@index([shopId, processingStatus])

  • Prisma model + migration
  • upload metadata persistence
  • processing status transitions
  • callback/worker update contract
  • storefront-ready eligibility rules
  • complex transcoding orchestration internals for every provider
  • subtitle editor UI
  • AI transcript quality improvements

Canonical processingStatus transitions:

  1. uploaded
  2. processing
  3. ready or failed

Rules:

  • no direct uploaded -> ready unless provider guarantees synchronous completion
  • failed may transition back to processing only via explicit retry flow

Document allowed transitions in constants/helper module.


4) Upload flow contract (public submit integration)

Section titled “4) Upload flow contract (public submit integration)”

Create provisional asset row (or post-upload row) with:

  • shopId
  • submissionId (or temporary linkage key if submission row not created yet)
  • storageProvider
  • storageKey
  • processingStatus='uploaded'
  • known file hints (mimeType, fileSizeBytes if available)

Ensure TestimonialSubmission links to the created asset.

If submission is created first and asset second, use transaction-safe linkage.


  • provider job/callback payload with media identifiers
  • asset correlation key (assetId, storageKey, provider id mapping)

Update asset row with:

  • processingStatus
  • playbackUrl
  • thumbnailUrl
  • durationSec
  • width, height
  • processingError on failure
  • optional transcriptText

Callbacks may replay. Updates should be idempotent:

  • repeated ready update should be safe
  • ignore stale status regressions (e.g. do not move ready back to processing without explicit reprocess intent)

Support storageProvider enum values from blueprint:

  • stream
  • mux
  • s3

Recommendation:

  • use adapter pattern per provider with common normalize step:
    • normalize duration units
    • normalize dimensions
    • normalize playback URL format

Store only provider-agnostic fields in main table; provider-specific raw payload can be saved in callback logs if needed.


For any API/widget public response:

only include testimonials where asset is:

  • processingStatus='ready'
  • playbackUrl present for video (or image URL for photo)

If submission is approved/published but asset not ready:

  • keep hidden from storefront
  • show processing indicator in admin screens

  • show clear asset state badge:

    • Uploaded
    • Processing
    • Ready
    • Failed
  • on failed state:

    • show concise error summary (processingError)
    • optional “Retry processing” action (future)

In submission detail:

  • duration
  • resolution
  • file size
  • source provider

Use placeholders when metadata not available yet.


  • storageKey is internal; do not expose raw key in public API response unless necessary.
  • Signed upload URLs must be short-lived and never persisted as-is.
  • transcriptText may contain PII; treat as sensitive in logs/export.

Align with 08-security-compliance-and-privacy.md.


10) Performance and storage considerations

Section titled “10) Performance and storage considerations”
  • Keep file-size values as BigInt (fileSizeBytes) from blueprint.
  • Avoid loading transcript text in list queries by default.
  • Optional retention policy:
    • archive/delete orphaned uploaded assets with no linked submission after N hours.

  • New uploads create asset records with valid provider/key linkage.
  • Asset transitions uploaded -> processing -> ready/failed are reflected correctly.
  • Admin detail view shows metadata when available.
  • Storefront API excludes non-ready assets.
  • Callback replay does not corrupt final asset state.

12) Suggested implementation order (for Cursor)

Section titled “12) Suggested implementation order (for Cursor)”
  1. Add Prisma model and migration for TestimonialMediaAsset.
  2. Add upload-url flow persistence hooks.
  3. Add processing worker/callback endpoint and idempotent updater.
  4. Integrate readiness predicate into storefront API filters.
  5. Add admin status/metadata display in inbox/detail.
  6. Add orphan cleanup task (optional hardening).

  • 02-Implementation-Blueprint.md — §5.8
  • 06-public-submission-page-screen-13.md
  • 10-submission-detail-screen-6.md
  • 05-storefront-widgets-and-read-api.md
  • 11-published-content-screen-7.md
  • 20-database-design-and-migrations-blueprint-section-5.md

This folder already includes 05 through 35 plans. This file is 36-....