---
path: /studio/file-media-ingestion
surface: studio
domain: authoring
auth: signed-in + studio entitlement
source: apps/oshun/web/src/app/studio/file-media-ingestion/page.tsx
status: walked
last_walked:
  '2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data
  (2xx), console/page-errors, expected content, screenshot verified; live
  screen-reader, touch, offline, and telemetry-delivery checks pending a manual
  AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; body
  re-derived 2026-06-03 from current source (lane-console architecture)'
---

# Studio · File and Media Ingestion

## Purpose

Validate an ingestion batch against a policy so operators can see which files
are accepted, rejected, or duplicated. `StudioFileMediaIngestionWorkspace` is an
admin BFF lane console: it loads the ingestion issue-code catalog from
`/v1/admin/studio/file-ingestion`, then runs the real validation engine via
`/validate`, which checks the MIME allow-list, extension/MIME consistency (spoof
guard), size limit, and checksum-based deduplication.

## Entry points

- **Studio root** (`/studio`) — discoverable as an authoring workspace
- **Quick-action links from sibling studio consoles** (asset-preview-pipeline,
  review-approval-workflows, commenting-annotation-system,
  presence-cursor-systems, activity-change-feeds)
- **Direct URL / bookmark** — yes

## Layout regions

`page.tsx` mounts `<ShellLayout active="studio">`, renders
`StudioFileMediaIngestionWorkspace`, then a `panel` of 5 `quickAction` links.
There is no Route Map panel on this route.

- **Workspace `<h1>`**: "Studio File & Media Ingestion" (`WorkspaceHeading`)
  plus a `data-file-media-ingestion-summary` lede
- **Ingestion Validation Lane** (`<h2 data-fi-lane-heading>`): catalog blurb
  (`data-fi-enums`), the JSON payload form, and the validated-files table
- **Quick-actions panel**: 5 sibling `Link.quickAction`s (no Back-to-Studio
  link; no self-link)

## States

- [ ] **Loading** (`data-fi-loading`) — "Loading ingestion validator…"
- [ ] **Unauthorized** (`data-fi-unauthorized`) — admin scope required (401/403)
- [ ] **Error** (`data-fi-error`) — catalog fetch failed/malformed
- [ ] **Ready (form)** — catalog blurb + payload textarea + "Validate batch"
- [ ] **Result** (`data-fi-result`) — `data-fi-accepted-count` /
      `data-fi-rejected-count` / duplicate headline + files table; invalid JSON
      or non-200 surfaces `data-fi-validate-error`

## Interactions

### Ingestion Validation Lane

- [ ] **Ingestion batch (JSON)** — `textarea[data-fi-payload]`,
      `aria-label="ingestion json"`; shape
      `{ policy{ allowedMimeTypes[], maxSizeBytes }, files[{ fileId, filename, declaredMimeType, sizeBytes, checksum }] }`
- [ ] **Validate batch** — `button[data-fi-submit]` (form `data-fi-form`
      submit) → `POST /v1/admin/studio/file-ingestion/validate`; renders
      `data-fi-file-row` rows (file / accepted / `data-fi-file-issues`)

### Quick actions

- [ ] 5 sibling links: asset-preview-pipeline, review-approval-workflows,
      commenting-annotation-system, presence-cursor-systems,
      activity-change-feeds

## Data & contracts

- **Reads**: `GET /v1/admin/studio/file-ingestion` (catalog:
  `ingestionIssues[]`)
- **Writes**: `POST /v1/admin/studio/file-ingestion/validate` (returns
  `{ result: { files[], summary{ acceptedCount, rejectedCount, duplicateCount } } }`)
- **Realtime**: none
- **Caching**: client `fetch` on mount, `cache: 'no-store'`
- **Auth/role check**: admin-scoped fail-closed (`admin:*` | `admin:studio`,
  401/403) at the BFF; proxy `studio` gate on the route. Headers via
  `buildBffAuthHeaders()`.

## Cross-references

- Parent: [`../studio-overview.md`](../studio-overview.md)
- Sibling:
  [`../generation/studio-asset-preview-pipeline.md`](../generation/studio-asset-preview-pipeline.md),
  [`../collaboration/studio-review-approval-workflows.md`](../collaboration/studio-review-approval-workflows.md)
- Source:
  `apps/oshun/web/src/components/studio/StudioFileMediaIngestionWorkspace.tsx`
  (no Route Map source — this route has no Route Map panel)

## Open questions / known gaps

- [ ] The lane validates a pasted batch (declared MIME + checksum); it does not
      sniff real file bytes or upload to object storage. Document the live
      ingestion path (MinIO + worker) the validator feeds.
- [ ] Confirm the production validation-profile catalog (video / image / audio /
      doc) vs. the single `policy` object accepted here.
