Skip to content

37 — Home Dashboard (role-driven "what needs my attention")

▶ PROMOTED TO PROTAGONIST by [doc-50] (2026-06-29): the app's center of gravity is now action-first — Home is the default gravity well, not a sibling tab. It gains a light cross-catalog work-board (the doc-46 pipeline: where work sits by stage) on top of the existing "what needs you" digest. Browse/ Portals (doc-49) become the substrate you land on when you act. First build slice: a pipeline strip on Home (stage counts across the catalog). See 50-UX-PARADIGM-OPTIONS.md §6.

▶ REDESIGNED by doc-54 (2026-07-04): Home v2 is NON-SCROLLABLE — one screen, no vertical scroll (stakeholder-locked "bold philosophy"). The §2 sections become a fixed tile budget (count + one-line top signal); depth lives behind the See-all drill-ins — the only scroll escape. Adds a context-aware Resume tile (closes the doc-47 §11 field feedback). See doc-54 §3.1.

Envisioning. Governed by 00-ROADMAP.md; implements 20-UI-SIMPLIFICATION.md §4.2 ("dashboard widgets — pin recents, pending approvals, activity"). Opened 2026-06-21 (owner locked this as the phase after the first-load perf slice). iOS-first, then web parity.


0. Value model (owner-raised 2026-06-22) — the perspective that ties it together

Owner QA surfaced the real question: a row that just says "Under review", or a note with no provenance, feels thin — it's data, not decision-support. Three principles fix that and should govern every section:

  1. Digest → drill-in. The dashboard is a triage surface, not a data screen. Each section shows the top N highest-signal items + a count + "See all →" to a dedicated full screen (filter / sort / history). This is what makes a thin row OK: depth lives one tap away; the dashboard's job is "what should I look at first." So each attention section becomes both a dashboard digest and its own screen (reachable from the digest and from the drawer where it makes sense).
  2. Per-row context contract: what · who · when. Every item must answer what happened, by whom, how recently — that's the minimum to decide whether to act. Today we have "what" (and only partially). "who" and "when" are not in the current list payloads — surfacing them is the real reason the /mobile/dashboard aggregate exists: not merely to bundle calls, but to be the dashboard's purpose-built read model that joins author + timestamp and pre-shapes each item. (So the aggregate SHOULD do this enrichment — it's not just a latency play. Owner intuition was right.)
  3. Per-actor perspective — same dashboard, role-driven emphasis. Different actors triage different things; the dashboard orders/weights sections by role, it does not fork into per-type screens (doc-20 §1 still holds). First cut:
    • Owner / Admin (label / manager): approvals they owe · release-readiness across projects · team activity. Triaging others' work.
    • Editor (producer / artist): changes requested on their tracks · notes left for them · what to fix next. Acting on feedback.
    • Viewer (client / A&R): awaiting my review (approve) · shared-with-me. Read-mostly; approval sections render read-only ("Awaiting approval"). The aggregate computes per-actor relevance server-side so the client stays dumb.

Build implication / order: (a) evolve /mobile/dashboard from "bundle" → read model with who·when + per-actor shaping; (b) add "See all" section screens; (c) richer rows (cover, dimension, author, relative time). Slices 1–3 (the digest skeleton + the four sections) are done; this is the enrichment phase on top. Section-level richness beats adding more sections.

1. Decision & guardrail

Turn the iOS home from a grid of artists into an actionable dashboard that foregrounds the Review & Approve loop: what needs my attention right now.

One dashboard, role-driven content — Owner / Admin / Editor / Viewer change what's surfaced and actionable, not which screen you land on. No per-user-type home screens (doc-20 §1 — that's the deferred templates layer). This phase is the single dashboard; "role/workflow templates" stay post-MVP.

The artist/roster grid does not disappear — it becomes one section of the dashboard (or a tab), below the attention surface.


2. What it surfaces (sections, in priority order)

The dashboard is attention + continuity only. Management surfaces (artists/roster, teams, trash, settings) live in the secondary nav (§6), not on the dashboard — so the home stays a focused "do this next" surface, not a navigation hub.

  1. Needs your approval — versions/covers Under review where the viewer can approve (Owner/Admin/ Editor). Source: per-track releaseStatus + per-file reviewStatus; project gate from GET /project/:id/release-readiness. Viewers see a read-only "Awaiting approval" count, no action.
  2. Unresolved notes & comments (rolled up) — the eagle-level roll-up we already shipped: GET /comment/rollup + /comment/rollup/counts (unresolved · tagged), breadcrumbed to their track/version. The single highest-signal "attention" feed.
  3. Recent activityGET /notification (already the live SSE-backed feed) + the realtime (doc-35) events, framed as "what changed since you looked".
  4. Jump back in (recents)GET /track/recent-access. Already built; just surfaced here.

Updated by doc-54 (2026-07-04): these sections persist as tiles (count + top signal) in the one-screen, non-scrollable Home v2; the row lists move wholly into the See-all screens (the §0 what·who·when contract migrates with them). Section 4's recents collapse into a single Resume continuity tile. §2.1's rule is unchanged — and now generalized platform-wide as doc-47 §7 principle 7.

Role gating is per resource (doc-20 §2 — getCollaboratorRole() equivalent): a section/action only shows where the viewer's cascaded role allows it. No new RBAC; reuse the collaborator-array + Role enum that already governs the app. Viewer gets the same dashboard (owner decision 2026-06-21) — approval sections render read-only (status, no action), notes/activity/recents are read as normal.

2.1 Empty / first-run state (progressive disclosure)

A brand-new user has nothing in any section — rendering four empty sections is a wall of nothing. Instead, progressive disclosure:

  • All sections empty → collapse to a single first-run hero: "Create your first artist" (primary CTA, promoting today's empty state) + one line explaining the Review & Approve loop. Nothing else.
  • Some sections have content → render only the non-empty sections; never show an empty section header. A subtle "finish setting up" nudge can ride along until the workspace has an artist + a track.
  • This means the dashboard grows into itself as the user adds content, rather than presenting a skeleton of empty promises on day one. (Owner confirmed the create-artist CTA direction; this is the refinement.)

Everything above is already exposed as separate endpoints. The only new backend work is the roadmap-flagged GET /mobile/dashboard aggregate (roadmap §"optional"): one authenticated call returning { pendingApprovals, rollupCounts, notifications, recents } for the viewer, to kill the 4–5 cold round-trips on home open (which is exactly the first-load cost we've been fighting). Build it as a thin composition over the existing services — no new domain state.

  • Slice it so the iOS client can ship against the existing endpoints first (fan-out), then switch to the aggregate when it lands — the aggregate is a latency optimization, not a dependency.

4. Build order (slices)

  1. iOS dashboard + nav shell — restructure ArtistsHomeView into the sectioned attention dashboard (§2) and move the roster grid + other destinations into the avatar drawer (§5.3). Includes the progressive-disclosure empty state (§2.1). Reuse CachedImage, SectionHeader, the roll-up row + breadcrumb components from the Portal. Mostly layout/IA; no new endpoints. The old artist-grid home becomes the "Artists" drawer destination — it isn't deleted, just relocated.
  2. Wire the attention sections to the existing endpoints (rollup/counts, release-readiness per recent project, notifications, recents). Role-gate each section/action.
  3. GET /mobile/dashboard aggregate (backend) + switch the iOS client to one call.
  4. Web parity (later) — same sections in the Next.js app once the single layout is consolidated (doc-20 §3+§5).

Reuses, not rebuilds: roll-up (doc-33), approval dimension (doc-32), activity/realtime (doc-35), notifications, recents. The dashboard is the surface that finally makes them legible together.


5. Navigation & secondary destinations (owner: "home is the dashboard; roster + the rest in a menu")

5.1 The destinations (today's app)

Primary: Dashboard (home). Secondary, behind the menu: Artists / roster, Teams, Shared with me, Search, Trash, Subscription & Storage, Settings, Account / sign-out. (Recents folds into the dashboard; Search may later graduate — see §5.4.)

5.2 Actor lens (who needs what)

  • Owner / Admin — the long tail: artists, teams, storage, trash, settings. Benefits most from a grouped menu of destinations.
  • Editor — mostly lives in the dashboard + the projects they collaborate on; reaches Artists/Shared occasionally.
  • Viewer — dashboard + Shared/Search. Teams/Trash/Storage are hidden (nothing to manage).

So the secondary surface is role-gated: the menu only lists what the viewer can actually use.

5.3 Pattern decision — a Liquid-Glass drawer sheet opened from the avatar, not a tab bar

Why not the iOS-default tab bar. Apple's HIG favors a tab bar for top-level nav — but a tab bar promotes 3–5 co-equal surfaces, which directly contradicts the owner decision that the dashboard is the surface and everything else is secondary. A tab bar would dilute the "one place to look" intent.

Why not a true left-edge slide drawer. It's an Android/web idiom with no native iOS component; hand-rolling it fights the system back-swipe, costs custom gesture code, and is weaker on VoiceOver / Dynamic Type. The "hamburger" concept is right; a literal edge-drawer is the wrong mechanism on iOS.

Recommended (native + matches intent): the account avatar (top-leading) opens a Liquid-Glass sheet (.presentationDetents([.medium, .large]), glass background — native on iOS 26). One affordance merges "where can I go" and "who am I" — a well-established pattern (Gmail/Google). Sheet layout:

  • Header — user identity + a storage meter (subscription usage at a glance).
  • Workspace — Artists / roster · Teams.
  • Library — Shared with me · Search · Trash.
  • You — Settings · Subscription · Sign out.
  • Each row role-gated; absent rows simply don't render (no disabled clutter).

Keep the trailing + as the create affordance (new artist/project) — distinct from navigation, so "go somewhere" (leading avatar) and "make something" (trailing +) stay cleanly separated. This also retires the current separate trailing profile menu (folded into the drawer) — one menu, not two.

▶ Queued (owner-raised 2026-06-26): the + should create any hierarchy node, not just an artist. Today the home + only makes an artist. Turn it into a create menu spanning the whole hierarchy — Roster · Artist · Project · Track · Version — so creation isn't gated by where you are. Open question: whether items requiring a parent (Project needs an Artist; Track needs a Project; Version needs a Track) prompt a parent-picker inline or are disabled until context exists. The CRUD sheets already exist (CreateArtistSheet / CreateProjectSheet / CreateTrackSheet); this is a menu + parent-resolution layer over them. Build after the current Sort/Filter/Search + records work (doc-40/41). Pairs with doc-25 CRUD. Also (owner-raised 2026-06-26): the same + create affordance must appear on the section screens reached from Home — Artists, Projects (.albums), Tracks — not only the home root. Each section pre-selects the relevant type (e.g. Tracks → "New track" with a project-picker). One shared create-menu component, surfaced in each section's toolbar.

Native, accessible, Liquid-Glass by default, minimal custom code. A literal edge-swipe drawer can be a later feel enhancement if wanted — flagged, not assumed.

5.4 Escape hatch (don't over-commit)

If usage later shows people can't find a section, promote the 2–3 most-used (likely Search + Shared) to a minimal iOS-26 Liquid-Glass tab bar and leave the long tail in the drawer. The drawer scales down gracefully; we don't need to decide now. The dashboard stays the primary surface either way.

6. Resolved decisions (owner, 2026-06-21) + remaining

  • Home is the dashboard. Roster + other sections move to the secondary menu (§5).
  • Empty state = progressive disclosure with a promoted "create your first artist" hero (§2.1).
  • Viewer gets the same dashboard, approval sections read-only (§2).
  • Remaining (decide during the shell slice): exact menu glyph/position (avatar-leading recommended); whether Search lives in the drawer or graduates to a tab early; storage-meter detail in the drawer header.

Ctrl-Audio Platform Documentation