500 lines
18 KiB
YAML
500 lines
18 KiB
YAML
# Sonic Cloud - Unified Project Analysis
|
|
# Generated by Eureka Index Parallel Documentation Pipeline
|
|
|
|
project:
|
|
name: "sonic-cloud"
|
|
version: "0.1.0"
|
|
description: "Music platform for musicians to upload songs, manage albums, create playlists, and discover music"
|
|
type: "node"
|
|
|
|
tech_stack:
|
|
language: "TypeScript"
|
|
framework: "Next.js 16.0.10 with App Router"
|
|
ui_library: "React 19.2.1"
|
|
styling: "Tailwind CSS 4"
|
|
database: "SQLite (via Prisma ORM)"
|
|
authentication: "JWT with bcryptjs"
|
|
orm: "Prisma 5.22.0"
|
|
|
|
structure:
|
|
directories:
|
|
- path: "/app"
|
|
purpose: "Next.js App Router pages and API routes"
|
|
file_count: 56
|
|
- path: "/app/api"
|
|
purpose: "REST API endpoints for authentication, songs, playlists, artists, labels, search, sharing"
|
|
file_count: 30
|
|
- path: "/components"
|
|
purpose: "Reusable React UI components including player, cards, forms, modals"
|
|
file_count: 36
|
|
- path: "/lib"
|
|
purpose: "Utility functions for authentication, database access, and sharing"
|
|
file_count: 3
|
|
- path: "/types"
|
|
purpose: "TypeScript type definitions and interfaces"
|
|
file_count: 4
|
|
- path: "/prisma"
|
|
purpose: "Database schema definition and migrations"
|
|
file_count: 1
|
|
- path: "/public"
|
|
purpose: "Static assets (SVG icons, fonts)"
|
|
file_count: 5
|
|
- path: "/styles"
|
|
purpose: "Global CSS and Tailwind configuration"
|
|
file_count: 1
|
|
- path: "/.workflow"
|
|
purpose: "Guardrail workflow system for enforcing design-approve-implement cycle"
|
|
file_count: 30
|
|
- path: "/.claude"
|
|
purpose: "Claude commands and configuration for development workflow"
|
|
file_count: 10
|
|
- path: "/skills"
|
|
purpose: "Custom guardrail orchestrator and documentation generator skills"
|
|
file_count: 15
|
|
|
|
dependencies:
|
|
runtime:
|
|
- name: "@prisma/client"
|
|
version: "^5.22.0"
|
|
purpose: "Database client for Prisma ORM to interact with SQLite database"
|
|
- name: "next"
|
|
version: "16.0.10"
|
|
purpose: "React framework providing file-based routing, API routes, and server capabilities"
|
|
- name: "react"
|
|
version: "19.2.1"
|
|
purpose: "JavaScript library for building interactive user interfaces"
|
|
- name: "react-dom"
|
|
version: "19.2.1"
|
|
purpose: "Renders React components to the DOM for web applications"
|
|
- name: "bcryptjs"
|
|
version: "^3.0.3"
|
|
purpose: "Hashes passwords securely for user authentication"
|
|
- name: "jsonwebtoken"
|
|
version: "^9.0.3"
|
|
purpose: "Creates and verifies JWT tokens for user session management"
|
|
- name: "nanoid"
|
|
version: "^5.1.6"
|
|
purpose: "Generates small unique IDs for database records and tokens"
|
|
- name: "uuid"
|
|
version: "^13.0.0"
|
|
purpose: "Generates universally unique identifiers for entities"
|
|
dev:
|
|
- name: "typescript"
|
|
version: "^5"
|
|
purpose: "Provides static type checking and better developer experience"
|
|
- name: "tailwindcss"
|
|
version: "^4"
|
|
purpose: "Utility-first CSS framework for responsive UI styling"
|
|
- name: "prisma"
|
|
version: "^5.22.0"
|
|
purpose: "ORM toolkit for schema design, migrations, and type-safe database access"
|
|
|
|
api_endpoints:
|
|
# Authentication
|
|
- method: "POST"
|
|
path: "/api/auth/register"
|
|
handler_file: "app/api/auth/register/route.ts"
|
|
description: "Register new user with email, password, username, and optional displayName"
|
|
auth_required: false
|
|
- method: "POST"
|
|
path: "/api/auth/login"
|
|
handler_file: "app/api/auth/login/route.ts"
|
|
description: "Authenticate user and return session token"
|
|
auth_required: false
|
|
- method: "POST"
|
|
path: "/api/auth/forgot-password"
|
|
handler_file: "app/api/auth/forgot-password/route.ts"
|
|
description: "Initiate password reset flow by sending email with reset token"
|
|
auth_required: false
|
|
- method: "POST"
|
|
path: "/api/auth/reset-password"
|
|
handler_file: "app/api/auth/reset-password/route.ts"
|
|
description: "Reset password using valid reset token"
|
|
auth_required: false
|
|
|
|
# Users
|
|
- method: "GET"
|
|
path: "/api/users/me"
|
|
handler_file: "app/api/users/me/route.ts"
|
|
description: "Get current authenticated user profile"
|
|
auth_required: true
|
|
- method: "PUT"
|
|
path: "/api/users/me"
|
|
handler_file: "app/api/users/me/route.ts"
|
|
description: "Update current user profile (displayName, bio, avatarUrl)"
|
|
auth_required: true
|
|
|
|
# Artists
|
|
- method: "POST"
|
|
path: "/api/artists"
|
|
handler_file: "app/api/artists/route.ts"
|
|
description: "Create new artist profile for authenticated user"
|
|
auth_required: true
|
|
- method: "GET"
|
|
path: "/api/artists/{id}"
|
|
handler_file: "app/api/artists/[id]/route.ts"
|
|
description: "Get artist details by ID with counts and relationships"
|
|
auth_required: false
|
|
- method: "PUT"
|
|
path: "/api/artists/{id}"
|
|
handler_file: "app/api/artists/[id]/route.ts"
|
|
description: "Update artist profile (owner only)"
|
|
auth_required: true
|
|
- method: "GET"
|
|
path: "/api/artists/{id}/songs"
|
|
handler_file: "app/api/artists/[id]/songs/route.ts"
|
|
description: "Get all public songs by artist"
|
|
auth_required: false
|
|
- method: "GET"
|
|
path: "/api/artists/{id}/albums"
|
|
handler_file: "app/api/artists/[id]/albums/route.ts"
|
|
description: "Get all albums by artist sorted by release date"
|
|
auth_required: false
|
|
|
|
# Songs
|
|
- method: "POST"
|
|
path: "/api/songs/upload"
|
|
handler_file: "app/api/songs/upload/route.ts"
|
|
description: "Create new song (artist only)"
|
|
auth_required: true
|
|
- method: "GET"
|
|
path: "/api/songs/{id}"
|
|
handler_file: "app/api/songs/[id]/route.ts"
|
|
description: "Get song details (public songs always, private only if owner)"
|
|
auth_required: false
|
|
- method: "PUT"
|
|
path: "/api/songs/{id}"
|
|
handler_file: "app/api/songs/[id]/route.ts"
|
|
description: "Update song details (owner only)"
|
|
auth_required: true
|
|
- method: "DELETE"
|
|
path: "/api/songs/{id}"
|
|
handler_file: "app/api/songs/[id]/route.ts"
|
|
description: "Delete song (owner only)"
|
|
auth_required: true
|
|
- method: "POST"
|
|
path: "/api/songs/{id}/play"
|
|
handler_file: "app/api/songs/[id]/play/route.ts"
|
|
description: "Increment song play count"
|
|
auth_required: false
|
|
|
|
# Albums
|
|
- method: "POST"
|
|
path: "/api/albums"
|
|
handler_file: "app/api/albums/route.ts"
|
|
description: "Create new album (artist only)"
|
|
auth_required: true
|
|
- method: "GET"
|
|
path: "/api/albums/{id}"
|
|
handler_file: "app/api/albums/[id]/route.ts"
|
|
description: "Get album details with all songs"
|
|
auth_required: false
|
|
- method: "PUT"
|
|
path: "/api/albums/{id}"
|
|
handler_file: "app/api/albums/[id]/route.ts"
|
|
description: "Update album details (owner only)"
|
|
auth_required: true
|
|
- method: "DELETE"
|
|
path: "/api/albums/{id}"
|
|
handler_file: "app/api/albums/[id]/route.ts"
|
|
description: "Delete album (owner only)"
|
|
auth_required: true
|
|
|
|
# Playlists
|
|
- method: "GET"
|
|
path: "/api/playlists"
|
|
handler_file: "app/api/playlists/route.ts"
|
|
description: "Get current user playlists"
|
|
auth_required: true
|
|
- method: "POST"
|
|
path: "/api/playlists"
|
|
handler_file: "app/api/playlists/route.ts"
|
|
description: "Create new playlist"
|
|
auth_required: true
|
|
- method: "GET"
|
|
path: "/api/playlists/{id}"
|
|
handler_file: "app/api/playlists/[id]/route.ts"
|
|
description: "Get playlist details with all songs (respects public/private)"
|
|
auth_required: false
|
|
- method: "PUT"
|
|
path: "/api/playlists/{id}"
|
|
handler_file: "app/api/playlists/[id]/route.ts"
|
|
description: "Update playlist details (owner only)"
|
|
auth_required: true
|
|
- method: "DELETE"
|
|
path: "/api/playlists/{id}"
|
|
handler_file: "app/api/playlists/[id]/route.ts"
|
|
description: "Delete playlist (owner only)"
|
|
auth_required: true
|
|
- method: "POST"
|
|
path: "/api/playlists/{id}/songs"
|
|
handler_file: "app/api/playlists/[id]/songs/route.ts"
|
|
description: "Add song to playlist"
|
|
auth_required: true
|
|
- method: "PUT"
|
|
path: "/api/playlists/{id}/reorder"
|
|
handler_file: "app/api/playlists/[id]/reorder/route.ts"
|
|
description: "Reorder songs in playlist"
|
|
auth_required: true
|
|
|
|
# Discovery
|
|
- method: "GET"
|
|
path: "/api/discover/trending"
|
|
handler_file: "app/api/discover/trending/route.ts"
|
|
description: "Get trending public songs sorted by play count"
|
|
auth_required: false
|
|
- method: "GET"
|
|
path: "/api/discover/new-releases"
|
|
handler_file: "app/api/discover/new-releases/route.ts"
|
|
description: "Get new public songs sorted by creation date"
|
|
auth_required: false
|
|
- method: "GET"
|
|
path: "/api/discover/genres"
|
|
handler_file: "app/api/discover/genres/route.ts"
|
|
description: "Get all genres with song counts"
|
|
auth_required: false
|
|
- method: "GET"
|
|
path: "/api/discover/genres/{slug}"
|
|
handler_file: "app/api/discover/genres/[slug]/route.ts"
|
|
description: "Get songs by genre slug"
|
|
auth_required: false
|
|
|
|
# Labels
|
|
- method: "POST"
|
|
path: "/api/labels"
|
|
handler_file: "app/api/labels/route.ts"
|
|
description: "Create new label profile (authenticated user)"
|
|
auth_required: true
|
|
- method: "GET"
|
|
path: "/api/labels/{id}"
|
|
handler_file: "app/api/labels/[id]/route.ts"
|
|
description: "Get label details with artist list"
|
|
auth_required: false
|
|
- method: "PUT"
|
|
path: "/api/labels/{id}"
|
|
handler_file: "app/api/labels/[id]/route.ts"
|
|
description: "Update label details (owner only)"
|
|
auth_required: true
|
|
- method: "GET"
|
|
path: "/api/labels/{id}/stats"
|
|
handler_file: "app/api/labels/[id]/stats/route.ts"
|
|
description: "Get label statistics (artist count, songs, albums, total plays)"
|
|
auth_required: false
|
|
- method: "GET"
|
|
path: "/api/labels/{id}/artists"
|
|
handler_file: "app/api/labels/[id]/artists/route.ts"
|
|
description: "Get all artists under a label"
|
|
auth_required: false
|
|
|
|
# Search
|
|
- method: "GET"
|
|
path: "/api/search"
|
|
handler_file: "app/api/search/route.ts"
|
|
description: "Search songs, artists, and albums across platform"
|
|
auth_required: false
|
|
|
|
# Sharing
|
|
- method: "POST"
|
|
path: "/api/share/song/{id}"
|
|
handler_file: "app/api/share/song/[id]/route.ts"
|
|
description: "Create shareable link for song"
|
|
auth_required: false
|
|
- method: "POST"
|
|
path: "/api/share/playlist/{id}"
|
|
handler_file: "app/api/share/playlist/[id]/route.ts"
|
|
description: "Create shareable link for playlist"
|
|
auth_required: false
|
|
- method: "POST"
|
|
path: "/api/share/album/{id}"
|
|
handler_file: "app/api/share/album/[id]/route.ts"
|
|
description: "Create shareable link for album"
|
|
auth_required: false
|
|
- method: "GET"
|
|
path: "/api/share/{token}"
|
|
handler_file: "app/api/share/[token]/route.ts"
|
|
description: "Resolve share link and get shared content details"
|
|
auth_required: false
|
|
- method: "POST"
|
|
path: "/api/share/{token}/click"
|
|
handler_file: "app/api/share/[token]/click/route.ts"
|
|
description: "Track share link clicks"
|
|
auth_required: false
|
|
|
|
components:
|
|
audio:
|
|
- id: "component_audio_player"
|
|
name: "AudioPlayer"
|
|
path: "components/AudioPlayer.tsx"
|
|
description: "Fixed bottom audio player with song info, playback controls, progress bar, and volume control"
|
|
- id: "component_player_controls"
|
|
name: "PlayerControls"
|
|
path: "components/PlayerControls.tsx"
|
|
description: "Reusable audio player controls with play/pause, next/previous, shuffle, and repeat buttons"
|
|
- id: "component_waveform_display"
|
|
name: "WaveformDisplay"
|
|
path: "components/WaveformDisplay.tsx"
|
|
description: "Canvas-based audio waveform visualization with progress tracking and seek functionality"
|
|
|
|
cards:
|
|
- id: "component_song_card"
|
|
name: "SongCard"
|
|
path: "components/SongCard.tsx"
|
|
description: "Card displaying song info with cover image, title, artist, duration, and play count"
|
|
- id: "component_album_card"
|
|
name: "AlbumCard"
|
|
path: "components/AlbumCard.tsx"
|
|
description: "Card displaying album info with cover art, title, artist, release year, and track count"
|
|
- id: "component_artist_card"
|
|
name: "ArtistCard"
|
|
path: "components/ArtistCard.tsx"
|
|
description: "Card displaying artist info with circular avatar, name, and verified badge"
|
|
- id: "component_playlist_card"
|
|
name: "PlaylistCard"
|
|
path: "components/PlaylistCard.tsx"
|
|
description: "Card displaying playlist with cover image, title, song count, and privacy badge"
|
|
- id: "component_label_card"
|
|
name: "LabelCard"
|
|
path: "components/LabelCard.tsx"
|
|
description: "Card displaying label info with logo, name, and artist count"
|
|
- id: "component_genre_badge"
|
|
name: "GenreBadge"
|
|
path: "components/GenreBadge.tsx"
|
|
description: "Small clickable badge displaying genre name with styling variants"
|
|
|
|
forms:
|
|
- id: "component_auth_form"
|
|
name: "AuthForm"
|
|
path: "components/AuthForm.tsx"
|
|
description: "Authentication form for login, register, and password reset modes"
|
|
- id: "component_upload_form"
|
|
name: "UploadForm"
|
|
path: "components/UploadForm.tsx"
|
|
description: "Multi-field form for uploading songs with audio file, metadata, and genre tagging"
|
|
- id: "component_profile_form"
|
|
name: "ProfileForm"
|
|
path: "components/ProfileForm.tsx"
|
|
description: "User profile editing form with username, email, bio, and website fields"
|
|
- id: "component_create_playlist_modal"
|
|
name: "CreatePlaylistModal"
|
|
path: "components/CreatePlaylistModal.tsx"
|
|
description: "Modal dialog for creating new playlists with title, description, and privacy toggle"
|
|
|
|
navigation:
|
|
- id: "component_header"
|
|
name: "Header"
|
|
path: "components/Header.tsx"
|
|
description: "Fixed top navigation header with logo, nav links, user menu, and mobile menu"
|
|
- id: "component_nav_link"
|
|
name: "NavLink"
|
|
path: "components/NavLink.tsx"
|
|
description: "Navigation link with active state highlighting based on current pathname"
|
|
- id: "component_user_menu"
|
|
name: "UserMenu"
|
|
path: "components/UserMenu.tsx"
|
|
description: "Dropdown menu showing auth state with profile, upload, playlists, and logout"
|
|
- id: "component_search_bar"
|
|
name: "SearchBar"
|
|
path: "components/SearchBar.tsx"
|
|
description: "Search input with real-time suggestions dropdown and loading indicator"
|
|
|
|
sharing:
|
|
- id: "component_share_button"
|
|
name: "ShareButton"
|
|
path: "components/ShareButton.tsx"
|
|
description: "Button that generates share links and opens share modal"
|
|
- id: "component_share_modal"
|
|
name: "ShareModal"
|
|
path: "components/ShareModal.tsx"
|
|
description: "Modal displaying shareable link with copy-to-clipboard and social share buttons"
|
|
|
|
display:
|
|
- id: "component_track_list"
|
|
name: "TrackList"
|
|
path: "components/TrackList.tsx"
|
|
description: "Scrollable list of tracks with position numbers, artist info, and duration"
|
|
|
|
data_models:
|
|
- name: "User"
|
|
source: "prisma"
|
|
description: "Base authentication and user profile entity for all platform users"
|
|
key_fields: ["id", "email", "username", "displayName", "passwordHash", "role"]
|
|
relations: ["Artist (hasOne)", "Label (hasOne)", "Playlist (hasMany)", "Share (hasMany)"]
|
|
|
|
- name: "Artist"
|
|
source: "prisma"
|
|
description: "Extended musician profile for content creators who upload songs"
|
|
key_fields: ["id", "userId", "name", "slug", "verified", "labelId"]
|
|
relations: ["User (belongsTo)", "Label (belongsTo)", "Song (hasMany)", "Album (hasMany)"]
|
|
|
|
- name: "Label"
|
|
source: "prisma"
|
|
description: "Record label organization profile that manages multiple artists"
|
|
key_fields: ["id", "userId", "name", "slug", "description"]
|
|
relations: ["User (belongsTo)", "Artist (hasMany)", "LabelInvitation (hasMany)"]
|
|
|
|
- name: "Genre"
|
|
source: "prisma"
|
|
description: "Music genre categories for content organization and discovery"
|
|
key_fields: ["id", "name", "slug", "description", "color"]
|
|
relations: ["SongGenre (hasMany)"]
|
|
|
|
- name: "Album"
|
|
source: "prisma"
|
|
description: "Collection of songs grouped together as an album, EP, or single"
|
|
key_fields: ["id", "artistId", "title", "releaseDate", "albumType"]
|
|
relations: ["Artist (belongsTo)", "Song (hasMany)"]
|
|
|
|
- name: "Song"
|
|
source: "prisma"
|
|
description: "Individual audio track with metadata, playback, and engagement tracking"
|
|
key_fields: ["id", "artistId", "albumId", "title", "audioUrl", "duration", "playCount"]
|
|
relations: ["Artist (belongsTo)", "Album (belongsTo)", "SongGenre (hasMany)", "PlaylistSong (hasMany)"]
|
|
|
|
- name: "Playlist"
|
|
source: "prisma"
|
|
description: "User-created collection of songs grouped by theme or preference"
|
|
key_fields: ["id", "userId", "title", "isPublic"]
|
|
relations: ["User (belongsTo)", "PlaylistSong (hasMany)"]
|
|
|
|
- name: "LabelInvitation"
|
|
source: "prisma"
|
|
description: "Invitation workflow for labels to recruit artists to their roster"
|
|
key_fields: ["id", "labelId", "artistId", "status", "expiresAt"]
|
|
relations: ["Label (belongsTo)", "Artist (belongsTo)"]
|
|
|
|
- name: "Share"
|
|
source: "prisma"
|
|
description: "Shareable content links for songs, playlists, and albums with analytics"
|
|
key_fields: ["id", "type", "targetId", "token", "clickCount"]
|
|
relations: ["User (belongsTo)"]
|
|
|
|
glossary_terms:
|
|
- term: "UUID"
|
|
definition: "Universally Unique Identifier - a 128-bit standard identifier that ensures uniqueness across distributed systems"
|
|
- term: "JWT"
|
|
definition: "JSON Web Token - a compact, URL-safe means of representing claims to be transferred between parties for authentication"
|
|
- term: "Slug"
|
|
definition: "URL-friendly identifier derived from content name, using hyphens instead of spaces and lowercase letters"
|
|
- term: "ORM"
|
|
definition: "Object-Relational Mapping - a technique that lets you query and manipulate data from a database using an object-oriented paradigm"
|
|
- term: "Prisma"
|
|
definition: "Next-generation Node.js and TypeScript ORM that provides type-safe database access"
|
|
- term: "API Endpoint"
|
|
definition: "A specific URL where an API can access resources needed to carry out a function"
|
|
- term: "Play Count"
|
|
definition: "Total number of times a song has been played by all users on the platform"
|
|
- term: "Waveform"
|
|
definition: "Visual representation of audio amplitude over time used in audio players and editing interfaces"
|
|
- term: "Share Token"
|
|
definition: "Unique alphanumeric code used to create shareable links for content distribution"
|
|
|
|
statistics:
|
|
total_files: 107
|
|
typescript_files: 107
|
|
api_endpoints: 40
|
|
database_models: 10
|
|
pages: 13
|
|
components: 20
|
|
type_definition_files: 4
|
|
lib_utility_files: 3
|