Skip to content
Rymflux Documentation
Esc
navigateopen⌘Jpreview
On this page

Data models

Data models

Canonical type definitions. All types are defined as TypeScript interfaces (authoritative for the API spec). Rust serde structs must match exactly — the TypeScript types are the source of truth.

The core does not transform types between plugin↔core and core↔frontend boundaries. The one exception: core adds id (UUID) and added_at on library save — those fields don’t exist in plugin-originated data.

Track

interface Track {
  id: string;                   // core UUID (assigned on library save)
  plugin_id: string;            // which plugin provided this
  content_id: string;           // plugin-scoped foreign ID

  title: string;
  duration_ms: number | null;
  artist: ArtistStub;           // required
  album: AlbumStub | null;
  cover_art_url: string | null;
  explicit: boolean;
  added_at: string | null;      // ISO 8601, set on library save
}

Album

interface Album {
  id: string;                   // core UUID
  plugin_id: string;
  content_id: string;           // plugin-scoped foreign ID

  title: string;
  artist: ArtistStub;
  cover_art_url: string | null;
  track_count: number | null;
  release_year: number | null;
  tracks: TrackStub[];          // stubs only — full tracks via get_track
}

Artist

interface Artist {
  id: string;                   // core UUID
  plugin_id: string;
  content_id: string;

  name: string;
  bio: string | null;
  image_url: string | null;
}

Playlist

interface Playlist {
  id: string;                   // core UUID
  name: string;
  description: string | null;
  created_at: string;           // ISO 8601
  tracks: TrackStub[];
}

Stub types

interface TrackStub {
  plugin_id: string;
  content_id: string;
  title: string;
  duration_ms: number | null;
  artist_name: string;
}

interface ArtistStub {
  id: string | null;            // null if not addressable
  name: string;
}

interface AlbumStub {
  id: string | null;            // null if not addressable
  title: string;
  cover_art_url: string | null;
}

id: null on stubs is valid — not every plugin models artists/albums as addressable entities.

SearchResult

interface SearchResult {
  plugin_id: string;            // which plugin returned this
  content_id: string;           // plugin-scoped foreign ID

  title: string;
  duration_ms: number | null;
  artist: ArtistStub;           // required minimum
  album: AlbumStub | null;
  cover_art_url: string | null;
  explicit: boolean;
}

StreamInfo

interface StreamInfo {
  url: string;
  content_type: string;         // "audio/mpeg", "audio/flac", "audio/ogg", etc.
  duration_ms: number | null;   // plugin may not know
  file_size_bytes: number | null;
  expires_at: string | null;    // ISO 8601 — for signed URLs that expire
}

Field requirements

Required fields are those with non-nullable types above.

  • cover_art_url is always optional — plugins frequently don’t have it.
  • duration_ms is optional — some streaming sources don’t expose it until the stream is opened.
  • No thumbnail vs full-size distinction in v1. One URL; plugins return whatever they have.

References

  • ADR-003 (UUIDv4 content IDs)
  • FR-MUSIC-1 (browse by album/artist)

Was this page helpful?