Each phase = one PR. Tasks/subtasks = small commits. Revert any single commit safely.
Status: phases 0–6 are complete and shipped (production: https://sunao-omega.vercel.app). Phases below are kept as the historical plan; unchecked boxes reflect scope that was deliberately descoped, not outstanding work.
- Init repo, Next.js 16, Tailwind v4, shadcn/ui.
- Biome, Husky, lint-staged, CI workflow.
- Design tokens, app shell skeleton.
- Docs wiki + roadmap.
- 1.1
useAudiohook syncing HTMLAudioElement ↔ store. - 1.2 Player bar controls (play/pause/prev/next/seek/speed).
- 1.3 Now-playing card in the queue panel.
- 1.4 Queue panel interactions (click to play).
- 2.1 Supabase schema (songs, albums, playlists, playlist_songs, profiles).
- 2.2 RLS policies.
- 2.3 Supabase client + Zod schemas.
- 2.4 Seed data (sample songs/playlists), aligned with static dataset.
- 2.5 TanStack Query hooks (useSongs, usePlaylists, usePlaylist).
- 3.1 Home (album grid + song list).
- 3.2 Search (filter songs/artists, empty state).
- 3.3 Library (list playlists, create playlist).
- 3.4 Playlist detail (play all, remove a song, empty state).
- 3.5 Like/unlike songs persisted to Supabase — descoped here, shipped later: phase 8 of
roadmap-post-mvp.mdlaunched the repository seam (src/lib/library/) so likes persist on-device, and in Supabase mode to theliked_songstable.
- 4.1 Supabase auth (email + password).
- 4.2 Login/signup pages.
- 4.3 Protected routes / proxy.
- 4.4 User profile + persisted liked songs — descoped: no profile page. Like persistence shipped via the repository seam (phase 8,
roadmap-post-mvp.md); the "Liked Songs" projection (phase 9) is still open. OAuth descoped (email+password only).
- 5.1 Image optimization (next/image, album art).
- 5.2 Loading states / skeletons (home route).
- 5.3 Empty states.
- 5.4 Accessibility pass (keyboard, focus, ARIA).
- 5.5 Performance (bundle, Lighthouse).
- 6.1 Vercel project + env vars.
- 6.2 Preview deploys per PR.
- 6.3 Production deploy + smoke test.
Shipped after the original plan, outside the phase/PR structure:
- Real artwork and 30-second previews from the iTunes Search API, with a bundled sample fallback and a Supabase artwork migration.
- Motion polish: shared easing tokens, pointer-gated hover, press feedback, reduced-motion support.
- Queue virtualization (TanStack Virtual) and the collapsible desktop queue panel.
- Mobile shell: bottom nav, queue bottom sheet, compact player bar (44px touch targets).
- Post-MVP phases 7–8 from
roadmap-post-mvp.md: idle-player fix, mobile seek slider, time-of-day greeting, and the repository seam (src/lib/library/) putting playlists and likes in one versioned, Zod-validated store (localStorage; Supabase at parity with theliked_songsmigration), with optimistic mutations. - SEO/discoverability (PR #10): per-route metadata,
robots.ts,sitemap.ts, JSON-LD on/about,llms.txt— seedocs/concepts/seo-and-ai-discovery.md. - Skill-review passes: search filtering deferred with
useDeferredValue, skip-to-content link, stable keyboard-shortcut listener ref, DNS preconnects,optimizePackageImportsfor Base UI.
- Each phase is a separate PR. Subtasks are separate commits.
- Verification skill + feature map updated after each phase (see
.opencode/skills/verify-sunao/).
- Shuffle, repeat, and volume controls (prototype only; not in product scope).
- "Liked Songs" as a live projection of likes (phase 9 remainder; the heart already persists).
- OAuth providers (only email+password shipped).
- Loading skeletons for search/library/playlist routes.