First draft — for discussion, not final

Mediabase — from single-list app to a real media app

Screen flow, layouts for the 8 categories on your home screen, and a database design to back them. Built from your Home wireframe — same sketch style carried through every screen below.

Your reference — Home

Confirming I read this right before building on top of it: a hamburger menu and search bar up top, open space in the middle (room for something later — recently played, a hero banner, not decided yet), and the 8 categories as a fixed 2×4 grid at the bottom.

Screen flow

Everything eventually leads to the Player. The one real branch is whether a category has sub-items to browse first (an album's tracks, a show's episodes) or plays directly.

Login / Signup Home search bar + 8 category tiles Upload Search results flat list, mixed types Category screen grid · list · feed — see patterns below one of the 8 tiles Collection detail Music, Podcasts, Series, Audio Books Player universal, every path ends here nav search tap tile grouped: has sub-items standalone: plays directly tap track / episode / chapter tap result
Music, Podcasts, Series, and Audio Books route through Collection Detail (an album's tracks, a show's episodes) before playing. Movies, Shorts, News, and Videos play directly from the category screen.

The 4 screen patterns

Instead of 8 bespoke layouts, the categories share 4 real shapes. Below each is one representative wireframe — the others just swap cover proportions or which metadata line shows.

Database design

Revised from the first draft: Collection isn't its own rigid table anymore. Grouping, genre, mood, and credits all collapse into one flexible Tag system — an album is just a tag applied to some tracks, a season is just another tag, "Directed by" is just a tag with a role. category (the 8 home-screen buttons) is the one exception that stays a fixed field on Item, since the home screen needs something reliable to query — turning that into a tag too is a real future step, once the UI supports custom navigation, not this one.

User MediaFile the actual bytes on disk Item track · episode · chapter · standalone ItemTag sequenceNumber role — many : many Tag album · genre · credit PayoutSplit percentage — who gets paid uploads 1 : 1 who gets paid percentage
One join (ItemTag) covers grouping and credits — the same shape, just a different role. PayoutSplit is deliberately separate and always points back at a real User, because unlike a credit, money has to land somewhere real.

How each category maps onto it

CategoryTypical grouping tagsequenceNumberTypical credit role
MusicAlbum (optional)Track numberArtist
PodcastsShowEpisode numberHost
Movies——Director
Shorts——Creator
SeriesShow (+ a season tag)Episode numberCreator
Audio BooksBookChapter numberAuthor, Narrator
NewsSource/Program (optional)—Reporter
Videos——Creator

Payment rights

Every Item gets at least one PayoutSplit row — at upload time, the uploader is auto-assigned 100%. They can then add collaborators and adjust the split (e.g. 60/40), as long as everyone named already has a Mediabase account, since this is where real money actually goes. Percentages for a given item are expected to sum to 100 — enforced in application code, not a database constraint, since Postgres can't easily check a sum across rows on its own.

This is deliberately a different table from credits, not a reuse of the Tag system: a credit tag can name anyone, on the platform or not ("featuring" someone who never signed up); a PayoutSplit row can't, because it has to resolve to an actual payable account. Your future idea — "anyone can add a video to this song and we split 50/50" — fits on top of this same table without changing its shape: an open offer would just be a rule that auto-creates the PayoutSplit rows once someone uploads a qualifying derivative. Worth designing properly when it's actually being built, not guessed at here.

Simplified for this draft — flag before building

Series seasons — a season is just a second tag applied to the same episodes (e.g. "Show: X" + "Season 2"), rather than its own table. Reconstructing clean season/episode order from two independent tags isn't fully solved here — worth revisiting once real season data exists.
No migration needed — existing v1/v2 media, accounts, and seed data get dropped when this schema ships, not carried forward. Confirmed fine to do — nothing there is worth preserving.
Tag creation — for v2 the system creates tags (via upload/edit forms); letting users freely create their own tags is the natural next step but not built yet.