# Sonic Cloud - Quick Reference Card ## Commands | Command | Purpose | |---------|---------| | `npm run dev` | Start development server (port 3000) | | `npm run build` | Build production bundle | | `npm start` | Start production server | | `npm run lint` | Run ESLint code checks | | `npx prisma studio` | Open database GUI | | `npx prisma migrate dev` | Create and apply migrations | | `npx prisma generate` | Regenerate Prisma client | | `npx prisma db push` | Push schema to database | ## Tech Stack | Layer | Technology | |-------|-----------| | Language | TypeScript 5 | | Framework | Next.js 16.0.10 (App Router) | | UI Library | React 19.2.1 | | Styling | Tailwind CSS 4 | | Database | SQLite (Prisma ORM 5.22.0) | | Authentication | JWT + bcryptjs | ## Key Files | File | Purpose | |------|---------| | `app/layout.tsx` | Root layout with Header, AudioPlayer | | `app/page.tsx` | Homepage with trending/new releases | | `lib/auth.ts` | JWT utilities (verifyToken, hashPassword) | | `lib/db.ts` | Prisma client singleton | | `lib/sharing.ts` | Share link generation | | `prisma/schema.prisma` | Database schema (10 models) | | `types/index.ts` | Core TypeScript types | | `project_manifest.json` | Guardrail entity definitions | ## Environment Variables | Variable | Required | Purpose | |----------|----------|---------| | `DATABASE_URL` | Yes | SQLite file path | | `JWT_SECRET` | Yes | Token signing secret | | `NEXT_PUBLIC_API_URL` | Optional | API base URL | ## API Endpoints (40 total) ### Authentication | Method | Path | Auth | Purpose | |--------|------|------|---------| | POST | `/api/auth/register` | No | Register new user | | POST | `/api/auth/login` | No | Login and get token | | POST | `/api/auth/forgot-password` | No | Request reset token | | POST | `/api/auth/reset-password` | No | Reset with token | ### Users | Method | Path | Auth | Purpose | |--------|------|------|---------| | GET | `/api/users/me` | Yes | Get current user | | PUT | `/api/users/me` | Yes | Update profile | ### Artists | Method | Path | Auth | Purpose | |--------|------|------|---------| | POST | `/api/artists` | Yes | Create artist | | GET | `/api/artists/{id}` | No | Get artist details | | PUT | `/api/artists/{id}` | Yes | Update artist (owner) | | GET | `/api/artists/{id}/songs` | No | List artist songs | | GET | `/api/artists/{id}/albums` | No | List artist albums | ### Songs | Method | Path | Auth | Purpose | |--------|------|------|---------| | POST | `/api/songs/upload` | Yes | Upload song (artist) | | GET | `/api/songs/{id}` | No | Get song details | | PUT | `/api/songs/{id}` | Yes | Update song (owner) | | DELETE | `/api/songs/{id}` | Yes | Delete song (owner) | | POST | `/api/songs/{id}/play` | No | Increment play count | ### Albums | Method | Path | Auth | Purpose | |--------|------|------|---------| | POST | `/api/albums` | Yes | Create album (artist) | | GET | `/api/albums/{id}` | No | Get album with songs | | PUT | `/api/albums/{id}` | Yes | Update album (owner) | | DELETE | `/api/albums/{id}` | Yes | Delete album (owner) | ### Playlists | Method | Path | Auth | Purpose | |--------|------|------|---------| | GET | `/api/playlists` | Yes | List user playlists | | POST | `/api/playlists` | Yes | Create playlist | | GET | `/api/playlists/{id}` | No | Get playlist (respects privacy) | | PUT | `/api/playlists/{id}` | Yes | Update playlist (owner) | | DELETE | `/api/playlists/{id}` | Yes | Delete playlist (owner) | | POST | `/api/playlists/{id}/songs` | Yes | Add song to playlist | | PUT | `/api/playlists/{id}/reorder` | Yes | Reorder songs | ### Discovery | Method | Path | Auth | Purpose | |--------|------|------|---------| | GET | `/api/discover/trending` | No | Trending songs (by plays) | | GET | `/api/discover/new-releases` | No | Recent songs (by date) | | GET | `/api/discover/genres` | No | All genres with counts | | GET | `/api/discover/genres/{slug}` | No | Songs by genre | ### Labels | Method | Path | Auth | Purpose | |--------|------|------|---------| | POST | `/api/labels` | Yes | Create label | | GET | `/api/labels/{id}` | No | Get label details | | PUT | `/api/labels/{id}` | Yes | Update label (owner) | | GET | `/api/labels/{id}/stats` | No | Label statistics | | GET | `/api/labels/{id}/artists` | No | Label artists | ### Search & Sharing | Method | Path | Auth | Purpose | |--------|------|------|---------| | GET | `/api/search` | No | Search songs/artists/albums | | POST | `/api/share/song/{id}` | No | Create song share link | | POST | `/api/share/playlist/{id}` | No | Create playlist share link | | POST | `/api/share/album/{id}` | No | Create album share link | | GET | `/api/share/{token}` | No | Resolve share link | | POST | `/api/share/{token}/click` | No | Track share clicks | ## Common Patterns ### Authentication Flow ```typescript // 1. Login → get token const res = await fetch('/api/auth/login', { method: 'POST', body: JSON.stringify({ email, password }) }); const { token } = await res.json(); // 2. Store token localStorage.setItem('auth_token', token); // 3. Use in authenticated requests fetch('/api/users/me', { headers: { Authorization: `Bearer ${token}` } }); ``` ### Data Fetching (Client Component) ```typescript // Using fetch with auth const [data, setData] = useState(null); useEffect(() => { const token = localStorage.getItem('auth_token'); fetch('/api/endpoint', { headers: { Authorization: `Bearer ${token}` } }) .then(res => res.json()) .then(setData); }, []); ``` ### Error Handling ```typescript // API returns { error: "message" } or { data: ... } const res = await fetch('/api/endpoint'); const json = await res.json(); if (!res.ok || json.error) { // Handle error console.error(json.error); return; } // Use json.data ``` ### Ownership Checks (Backend) ```typescript // lib/auth.ts exports verifyToken(request) const user = verifyToken(request); if (!user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); // Check ownership const entity = await prisma.entity.findUnique({ where: { id } }); if (entity.userId !== user.id) { return NextResponse.json({ error: 'Forbidden' }, { status: 403 }); } ``` ## Database Models (10) | Model | Key Relations | Auth | |-------|---------------|------| | User | → Artist (1), Label (1), Playlist (*), Share (*) | Base | | Artist | → User (1), Label (1), Song (*), Album (*) | User role | | Label | → User (1), Artist (*), LabelInvitation (*) | User role | | Song | → Artist (1), Album (1), Genre (*), Playlist (*) | Public/Private | | Album | → Artist (1), Song (*) | Public | | Playlist | → User (1), Song (*) | Public/Private | | Genre | → Song (*) | Public | | Share | → User (1) | Token-based | | LabelInvitation | → Label (1), Artist (1) | Status-based | | SongGenre | → Song (1), Genre (1) | Join table | ## Component Categories | Category | Components | Count | |----------|-----------|-------| | Audio | AudioPlayer, PlayerControls, WaveformDisplay | 3 | | Cards | SongCard, AlbumCard, ArtistCard, PlaylistCard, LabelCard, GenreBadge | 6 | | Forms | AuthForm, UploadForm, ProfileForm, CreatePlaylistModal | 4 | | Navigation | Header, NavLink, UserMenu, SearchBar | 4 | | Sharing | ShareButton, ShareModal | 2 | | Display | TrackList | 1 | ## Workflow Commands | Command | Purpose | |---------|---------| | `/workflow:spawn` | Start automated workflow | | `/workflow:status` | Check current state | | `/workflow:approve` | Approve current gate | | `/workflow:reject` | Reject with feedback | | `/workflow:resume` | Resume interrupted workflow | | `/guardrail:init` | Initialize manifest (manual) | | `/guardrail:design` | Add entities (manual) | | `/guardrail:implement` | Implement entities (manual) | | `/eureka:index` | Generate documentation | ## Project Structure ``` sonic-cloud/ ├── app/ # Next.js App Router (pages + API) │ ├── api/ # REST API endpoints (30 files) │ └── [pages]/ # Frontend pages (13 pages) ├── components/ # React components (36 files) ├── lib/ # Utilities (auth, db, sharing) ├── types/ # TypeScript definitions (4 files) ├── prisma/ # Database schema ├── .workflow/ # Guardrail workflow state ├── .claude/ # Claude commands └── skills/ # Custom skills (orchestrator, docs) ``` ## Statistics - **Total Files**: 107 TypeScript files - **API Endpoints**: 40 (REST) - **Database Models**: 10 (Prisma) - **Pages**: 13 (App Router) - **Components**: 20 (reusable) - **LOC**: ~15,000 lines --- **Generated by Eureka Documentation Pipeline** | Sonic Cloud v0.1.0