project-standalo-sonic-cloud/docs/QUICK_REFERENCE.md

259 lines
8.5 KiB
Markdown

# 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