23 — iOS Phase 2: Information Architecture & Navigation
Active spec. Governed by
00-ROADMAP.md. Last updated 2026-06-07. Builds on the completed Phase 1 MVP (19-IOS-MVP-REVIEW-APPROVE.md) and the design system (22-IOS-DESIGN-SYSTEM.md).
Context
Phase 1 shipped the Review & Approve loop (sign in → feed → track → player → comment → approve), all working end-to-end. The landing screen is a flat Recent / Shared / Yours feed — a deliberate shortcut to the approve loop. Phase 2 replaces that with the artwork-forward browse hierarchy the canva-refs depict, plus first-class shared (inbound/outbound) views and Portals everywhere. The Phase 1 player/comment/approve surfaces stay exactly as they are — this is navigation around them.
The real hierarchy (grounded in the backend)
ArtistSpace → Project → Track → File (versions) → Comment / Section
ArtistSpaceis the top-level container (an "Artist" in the UI). There is noRosterentity yet —labelis only a string field onTrack. A Roster grouping above ArtistSpace (the "Roster" nav inweb-front--home-dashboard-idea.png) is a future concept; do not model it as an entity now. (Preferred term is "Roster", not "Label".)- Permissions cascade ArtistSpace → Project → Track (owner / admin / editor / viewer).
Screen map (Phase 2)
| Screen | Source ref | Primary data |
|---|---|---|
| Home — Artists | mobile-front--artis-projects.png (hero + grid) | GET /artist (owned) + inbound spaces |
| Artist → Projects | mobile-front--artis-projects.png | GET /project/artist/:artistId |
| Project → Tracks | mobile-front--project-tracks.png | GET /track/project/:projectId |
| Track detail / Player / Portal | Phase 1 (web-front--wave-player.png) | existing — unchanged |
| Shared (inbound / outbound) | — | see Sharing below |
Navigation: NavigationStack with navigationDestination per level (Artist id → Project id → Track id), artwork-forward ProjectCard grid + TrackRow list (both already in DesignSystem/). The flat Recents feed becomes a secondary tab or the Home's "Recent" rail, not the primary surface.
Endpoint map (what exists vs gaps)
| Need | Endpoint | Status |
|---|---|---|
| My artists | GET /artist | ✅ |
| Projects in an artist | GET /project/artist/:artistId | ✅ |
| Tracks in a project | GET /track/project/:projectId | ✅ |
| Inbound — shared spaces / projects / tracks | GET /collaboration/collaborator/{spaces,projects,tracks} | ✅ |
| Inbound — recent shared activity | GET /collaboration/recents | ✅ |
| Outbound — what I shared | (derive from owned + GET /link/{artist,project,track}/:id) | 🟡 may want a /collaboration/shared-by-me aggregate |
| Artist / Project metadata for Portals | GET /artist/:id, GET /project/:id | ✅ |
Portals everywhere
Extend the Phase 1 Portal (glass sheet + detents) beyond Track to Artist and Project contextual detail (metadata + collaborators + share). Same Portal / MetadataRow / LabelCopyTable components; new content bodies (ArtistPortalContent, ProjectPortalContent).
Sharing — inbound vs outbound (the UX the user called out)
PARKED (2026-06-07). A first-pass Shared tab was built then pulled — "Shared" is a consequence of how Roster / workspaces / actors are modeled, not a standalone tab. The browse hierarchy below stays active; this Sharing section is parked. The envisioning that answers it (lenses, sharing identity, Roster-as-tag — decisions confirmed 2026-06-07) is
26-IDENTITY-SHARING-NAVIGATION.md; it ships post-polish per25-IOS-CRUD-FIRST-RELEASE.md. Keep the endpoint notes for when it's reintroduced.
- Inbound ("Shared with me"): things others shared to me —
/collaboration/collaborator/*+/recents. - Outbound ("Shared by me"): my owned resources that have collaborators or active share-links. No single endpoint today — derive client-side from owned resources +
GET /link/*, or add a backend aggregate (/collaboration/shared-by-me) in a backend slice. Surface both as segments of a Shared screen.
Out of scope (later phases)
The pro dashboard (web-front--home-dashboard-idea.png — Roster, charts, ContactID), a Roster entity (grouping above ArtistSpace), upload/creation on iOS, and full search. Keep Phase 2 to browse + shared + Portals.
Build order (suggested slices)
- Home → Artists grid (
GET /artist) withArtistPortalContent. - Artist → Projects (
GET /project/artist/:id) usingProjectCard. - Project → Tracks (
GET /track/project/:id) usingTrackRow→ existing track detail/player. - Shared screen (inbound segment first; outbound after the backend aggregate).
Each slice follows .agent/workflows/ios-feature-slice.md.
Cross-references
- One-dashboard / role-driven model:
20-UI-SIMPLIFICATION.md - Design system & components:
22-IOS-DESIGN-SYSTEM.md - MVP loop (unchanged):
19-IOS-MVP-REVIEW-APPROVE.md