Skip to content

Capability Apps

A capability app is a self-contained piece of UI + client-side logic that implements one specific product capability well enough to be reused as-is by more than one host application — rather than each app re-implementing its own version of the same form/flow against the same backend domain.

As of 2026-08-21 this is a real package boundary, not just a documentation grouping — @playtelly/capability-apps, published to the private Nexus npm registry, currently at v0.6.x. It started (2026-08-xx) as PlayoutAdmin-only components extracted for reuse; it's now consumed by both PlayoutAdmin and TellyboardAdmin. Each host app wires its own backend calls in via a createCapabilityAdapter(...) factory rather than the package calling any API directly — the package owns UI/interaction logic only, never a fetch client of its own.

The point of calling these out separately here is that their scope, API contract, and known gaps are meant to be understood independent of any one host app — a consuming team ports/embeds the component, not the flow's logic, which now genuinely lives in one place.

Why this distinction matters for a consuming team: the rest of docs/domain/media/ documents the backend — routes, schemas, pipeline behavior. These pages document the frontend contract on top of it — which fields a form actually sends, what it detects/decides client-side before it ever calls the API, and which parts are still placeholder (hardcoded values, unbuilt pickers) that a second consumer needs to know about before depending on the current behavior.


Capability apps documented here

App Backend domain Host app(s) Status
Media Upload (MediaUploadSheet) media PlayoutAdmin, TellyboardAdmin Real — replaces PlayoutAdmin's old hand-rolled AddContentSheet.jsx (removed 2026-08-21). Type picker, drag-drop, "From URL" registration, cancel handling, thumbnail preview
Media Library Table (MediaLibraryTable) media PlayoutAdmin, TellyboardAdmin Real — generalized from PlayoutAdmin's original ~825-line hand-rolled MediaList.jsx table (2026-08-21); each host app now wires ~95 lines of app-specific bits (upload adapter, header actions, detail panel) around it
Media Thumbnail / Lightbox media PlayoutAdmin, TellyboardAdmin Real, shared
Media Transcoding Presets media — TranscodingProfile/TranscodingProfileVersion PlayoutAdmin (TranscodingProfileList.jsx + ProfileEditSheet.jsx) Migrated into the shared package; full CRUD, all 3 categories (video/image/document)

All of these sit on top of the same domain/media backend documented in docs/domain/media — read that first for the pipeline/API side; the package's own README/ROADMAP.md picks up where that leaves off, at the form and its decisions (adapter contract, per-host wiring, known gaps).


Adding a new capability app to this list

A page belongs here if it's a UI flow another team is expected to reuse or port, not just any React component. When adding one:

  1. Create docs/capability-apps/<kebab-case-name>/index.md.
  2. Trace the actual functions called, in call order — not just a feature list. A second team porting this needs to know which client-side decision (file-extension sniffing, category mapping, passthrough detection, etc.) happens before which API call, since that's exactly the logic they'd otherwise have to reverse-engineer from the component source.
  3. Call out every hardcoded/placeholder value explicitly, with a To-do — a capability app being reused elsewhere is exactly the moment a "temporary" hardcoded tenant or folder stops being safe to copy silently.
  4. Add a row to the table above.