feat: backend, stream server & infra improvements
Backend (Go):
- Config: CORS, RabbitMQ, rate limit, main config updates
- Routes: core, distribution, tracks routing changes
- Middleware: rate limiter, endpoint limiter, response cache hardening
- Handlers: distribution, search handler fixes
- Workers: job worker improvements
- Upload validator and logging config additions
- New migrations: products, orders, performance indexes
- Seed tooling and data
Stream Server (Rust):
- Audio processing, config, routes, simple stream server updates
- Dockerfile improvements
Infrastructure:
- docker-compose.yml updates
- nginx-rtmp config changes
- Makefile improvements (config, dev, high, infra)
- Root package.json and lock file updates
- .env.example updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:36:06 +00:00
package main
import (
"database/sql"
"fmt"
"log"
"math/rand"
"os"
"strings"
"time"
"github.com/google/uuid"
"github.com/joho/godotenv"
_ "github.com/lib/pq"
"golang.org/x/crypto/bcrypt"
)
// ─── helpers ────────────────────────────────────────────────────────────────
func must ( err error , msg string ) {
if err != nil {
log . Fatalf ( "%s: %v" , msg , err )
}
}
func tryExec ( db * sql . DB , query string , args ... interface { } ) {
_ , _ = db . Exec ( query , args ... )
}
func execOrWarn ( db * sql . DB , label string , query string , args ... interface { } ) {
if _ , err := db . Exec ( query , args ... ) ; err != nil {
log . Printf ( " ⚠ %s: %v" , label , err )
}
}
func countRows ( db * sql . DB , table string ) int {
var n int
_ = db . QueryRow ( fmt . Sprintf ( "SELECT COUNT(*) FROM %s" , table ) ) . Scan ( & n )
return n
}
func randBetween ( min , max int ) int { return min + rand . Intn ( max - min + 1 ) }
func daysAgo ( d int ) time . Time { return time . Now ( ) . Add ( - time . Duration ( d ) * 24 * time . Hour ) }
func hoursAgo ( h int ) time . Time { return time . Now ( ) . Add ( - time . Duration ( h ) * time . Hour ) }
// ─── main ───────────────────────────────────────────────────────────────────
func main ( ) {
_ = godotenv . Load ( )
dbURL := os . Getenv ( "DATABASE_URL" )
if dbURL == "" {
log . Fatal ( "DATABASE_URL not set" )
}
db , err := sql . Open ( "postgres" , dbURL )
must ( err , "DB connect" )
defer db . Close ( )
must ( db . Ping ( ) , "DB ping" )
fmt . Println ( "╔═══════════════════════════════════════════════╗" )
fmt . Println ( "║ VEZA — Database Seed Script ║" )
fmt . Println ( "╚═══════════════════════════════════════════════╝" )
fmt . Println ( )
// Hash a shared password (bcrypt cost 12)
hash , err := bcrypt . GenerateFromPassword ( [ ] byte ( "Password123!" ) , 12 )
must ( err , "bcrypt" )
pw := string ( hash )
// ═════════════════════════════════════════════════════════════════════════
// USERS (10)
// ═════════════════════════════════════════════════════════════════════════
type user struct {
id , email , username , display , role , bio string
isAdmin bool
}
var users [ ] user
if countRows ( db , "users" ) == 0 {
fmt . Print ( "Creating users... " )
users = [ ] user {
{ uuid . NewString ( ) , "admin@veza.fr" , "admin_veza" , "Admin Veza" , "admin" , "Platform administrator" , true } ,
{ uuid . NewString ( ) , "amelie@veza.fr" , "amelie_dubois" , "Amelie Dubois" , "creator" , "Productrice electro basee a Paris. Melodic techno & ambient." , false } ,
{ uuid . NewString ( ) , "marcus@veza.fr" , "marcus_beats" , "Marcus Beats" , "creator" , "Beatmaker from Lyon. Hip-hop, trap, lo-fi." , false } ,
{ uuid . NewString ( ) , "sakura@veza.fr" , "sakura_sound" , "Sakura Sound" , "creator" , "Sound designer & foley artist. Cinematic textures." , false } ,
{ uuid . NewString ( ) , "djrenzo@veza.fr" , "dj_renzo" , "DJ Renzo" , "creator" , "House & disco edits. Paris nightlife." , false } ,
{ uuid . NewString ( ) , "clara@veza.fr" , "clara_voice" , "Clara Voix" , "creator" , "Singer-songwriter. Indie folk & acoustic." , false } ,
{ uuid . NewString ( ) , "listener1@veza.fr" , "music_lover" , "Music Lover" , "user" , "Just here for the vibes." , false } ,
{ uuid . NewString ( ) , "listener2@veza.fr" , "groove_hunter" , "Groove Hunter" , "user" , "Always looking for fresh beats." , false } ,
{ uuid . NewString ( ) , "listener3@veza.fr" , "night_owl" , "Night Owl" , "premium" , "Late night music sessions." , false } ,
{ uuid . NewString ( ) , "mod@veza.fr" , "moderator_veza" , "Moderator" , "moderator" , "Community moderator." , false } ,
}
for _ , u := range users {
_ , err := db . Exec ( ` INSERT INTO users ( id , email , email_verified_at , password_hash , username , slug , display_name ,
role , is_active , is_verified , is_admin , bio , created_at , updated_at )
VALUES ( $ 1 , $ 2 , NOW ( ) , $ 3 , $ 4 , $ 5 , $ 6 , $ 7 , true , true , $ 8 , $ 9 , NOW ( ) - interval ' 1 day ' * $ 10 , NOW ( ) ) ` ,
u . id , u . email , pw , u . username , u . username , u . display , u . role , u . isAdmin , u . bio , randBetween ( 1 , 60 ) )
must ( err , "user " + u . username )
}
fmt . Printf ( "%d created\n" , len ( users ) )
// Profiles & settings
for _ , u := range users {
tryExec ( db , ` INSERT INTO user_profiles (user_id,bio,tagline,language,theme,profile_visibility) VALUES ($1,$2,$3,'fr','auto','public') ` ,
u . id , u . bio , strings . Split ( u . bio , "." ) [ 0 ] )
tryExec ( db , ` INSERT INTO user_settings (user_id) VALUES ($1) ON CONFLICT DO NOTHING ` , u . id )
}
// Roles
tryExec ( db , ` INSERT INTO user_roles (user_id,role_id) SELECT $1,id FROM roles WHERE name='admin' ON CONFLICT DO NOTHING ` , users [ 0 ] . id )
tryExec ( db , ` INSERT INTO user_roles (user_id,role_id) SELECT $1,id FROM roles WHERE name='moderator' ON CONFLICT DO NOTHING ` , users [ 9 ] . id )
} else {
fmt . Println ( "Users already exist — loading IDs..." )
rows , _ := db . Query ( ` SELECT id,email,username,display_name,role,COALESCE(bio,''),is_admin FROM users ORDER BY created_at LIMIT 10 ` )
for rows != nil && rows . Next ( ) {
var u user
_ = rows . Scan ( & u . id , & u . email , & u . username , & u . display , & u . role , & u . bio , & u . isAdmin )
users = append ( users , u )
}
if rows != nil {
rows . Close ( )
}
}
if len ( users ) < 10 {
fmt . Println ( "⚠ Need at least 10 users for full seed. Exiting." )
os . Exit ( 0 )
}
amelieID := users [ 1 ] . id
marcusID := users [ 2 ] . id
sakuraID := users [ 3 ] . id
renzoID := users [ 4 ] . id
claraID := users [ 5 ] . id
// ═════════════════════════════════════════════════════════════════════════
// TRACKS (22)
// ═════════════════════════════════════════════════════════════════════════
type track struct {
id , creator , title , artist , album , genre , key , tags string
duration , bpm int
}
var tracks [ ] track
if countRows ( db , "tracks" ) == 0 {
fmt . Print ( "Creating tracks... " )
tracks = [ ] track {
{ uuid . NewString ( ) , amelieID , "Neon Dreams" , "Amelie Dubois" , "Neon EP" , "electronic" , "Am" , "{electronic,ambient,melodic}" , 342 , 128 } ,
{ uuid . NewString ( ) , amelieID , "Midnight Protocol" , "Amelie Dubois" , "Neon EP" , "techno" , "Dm" , "{techno,dark,melodic}" , 410 , 132 } ,
{ uuid . NewString ( ) , amelieID , "Aurora Borealis" , "Amelie Dubois" , "Neon EP" , "ambient" , "C" , "{ambient,atmospheric,chill}" , 520 , 90 } ,
{ uuid . NewString ( ) , amelieID , "Digital Rain" , "Amelie Dubois" , "Singles" , "electronic" , "Em" , "{electronic,synth,progressive}" , 285 , 126 } ,
{ uuid . NewString ( ) , amelieID , "Pulse" , "Amelie Dubois" , "Singles" , "techno" , "Bm" , "{techno,driving,peak}" , 378 , 134 } ,
{ uuid . NewString ( ) , marcusID , "Late Night Loops" , "Marcus Beats" , "Bedroom Sessions" , "hip-hop" , "Cm" , "{lofi,chill,beats}" , 198 , 85 } ,
{ uuid . NewString ( ) , marcusID , "Concrete Jungle" , "Marcus Beats" , "Bedroom Sessions" , "hip-hop" , "Fm" , "{hiphop,boom-bap,gritty}" , 225 , 90 } ,
{ uuid . NewString ( ) , marcusID , "Velvet Touch" , "Marcus Beats" , "Bedroom Sessions" , "r&b" , "Ab" , "{rnb,smooth,lofi}" , 240 , 78 } ,
{ uuid . NewString ( ) , marcusID , "City Lights" , "Marcus Beats" , "Singles" , "trap" , "Gm" , "{trap,melodic,urban}" , 210 , 140 } ,
{ uuid . NewString ( ) , marcusID , "Rainy Days" , "Marcus Beats" , "Singles" , "lo-fi" , "D" , "{lofi,rain,relax}" , 180 , 72 } ,
{ uuid . NewString ( ) , sakuraID , "Forest Whispers" , "Sakura Sound" , "Nature Vol.1" , "ambient" , "F" , "{nature,foley,cinematic}" , 480 , 60 } ,
{ uuid . NewString ( ) , sakuraID , "Ocean Depths" , "Sakura Sound" , "Nature Vol.1" , "ambient" , "Eb" , "{water,deep,ambient}" , 540 , 55 } ,
{ uuid . NewString ( ) , sakuraID , "Thunder Plains" , "Sakura Sound" , "Nature Vol.1" , "cinematic" , "Bb" , "{storm,epic,cinematic}" , 360 , 80 } ,
{ uuid . NewString ( ) , sakuraID , "Urban Field Recording" , "Sakura Sound" , "Singles" , "experimental" , "" , "{field-recording,urban,experimental}" , 300 , 0 } ,
{ uuid . NewString ( ) , renzoID , "Saturday Night Edit" , "DJ Renzo" , "Club Cuts" , "house" , "G" , "{house,disco,funky}" , 420 , 122 } ,
{ uuid . NewString ( ) , renzoID , "Funky Elevator" , "DJ Renzo" , "Club Cuts" , "disco" , "A" , "{disco,funk,groovy}" , 355 , 118 } ,
{ uuid . NewString ( ) , renzoID , "Deep in the Club" , "DJ Renzo" , "Club Cuts" , "deep house" , "Dm" , "{deephouse,minimal,late-night}" , 480 , 124 } ,
{ uuid . NewString ( ) , renzoID , "Sunrise Set" , "DJ Renzo" , "Singles" , "house" , "C" , "{house,progressive,sunrise}" , 600 , 120 } ,
{ uuid . NewString ( ) , claraID , "Paper Boats" , "Clara Voix" , "Whisper" , "folk" , "G" , "{folk,acoustic,indie}" , 220 , 95 } ,
{ uuid . NewString ( ) , claraID , "Morning Light" , "Clara Voix" , "Whisper" , "indie" , "D" , "{indie,dreamy,morning}" , 198 , 100 } ,
{ uuid . NewString ( ) , claraID , "Letters Never Sent" , "Clara Voix" , "Whisper" , "folk" , "Em" , "{folk,emotional,singer-songwriter}" , 265 , 88 } ,
{ uuid . NewString ( ) , claraID , "Wildflowers" , "Clara Voix" , "Singles" , "acoustic" , "C" , "{acoustic,nature,gentle}" , 185 , 92 } ,
}
for i , t := range tracks {
createdAt := daysAgo ( 60 - i * 2 )
2026-03-23 14:46:57 +00:00
// file_path uses "audio/{Title_With_Underscores}.mp3" matching generated audio files
filePath := "audio/" + strings . ReplaceAll ( t . title , " " , "_" ) + ".mp3"
feat: backend, stream server & infra improvements
Backend (Go):
- Config: CORS, RabbitMQ, rate limit, main config updates
- Routes: core, distribution, tracks routing changes
- Middleware: rate limiter, endpoint limiter, response cache hardening
- Handlers: distribution, search handler fixes
- Workers: job worker improvements
- Upload validator and logging config additions
- New migrations: products, orders, performance indexes
- Seed tooling and data
Stream Server (Rust):
- Audio processing, config, routes, simple stream server updates
- Dockerfile improvements
Infrastructure:
- docker-compose.yml updates
- nginx-rtmp config changes
- Makefile improvements (config, dev, high, infra)
- Root package.json and lock file updates
- .env.example updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:36:06 +00:00
_ , err := db . Exec ( ` INSERT INTO tracks ( id , creator_id , user_id , title , artist , album , genre , duration , bpm , musical_key ,
2026-03-23 14:46:57 +00:00
visibility , is_public , is_downloadable , status , stream_status , play_count , like_count , tags , file_path , format , published_at , created_at , updated_at )
VALUES ( $ 1 , $ 2 , $ 2 , $ 3 , $ 4 , $ 5 , $ 6 , $ 7 , $ 8 , $ 9 , ' public ' , true , false , ' completed ',' ready ' , $ 10 , $ 11 , $ 12 : : text [ ] , $ 14 , ' mp3 ' , $ 13 , $ 13 , $ 13 ) ` ,
feat: backend, stream server & infra improvements
Backend (Go):
- Config: CORS, RabbitMQ, rate limit, main config updates
- Routes: core, distribution, tracks routing changes
- Middleware: rate limiter, endpoint limiter, response cache hardening
- Handlers: distribution, search handler fixes
- Workers: job worker improvements
- Upload validator and logging config additions
- New migrations: products, orders, performance indexes
- Seed tooling and data
Stream Server (Rust):
- Audio processing, config, routes, simple stream server updates
- Dockerfile improvements
Infrastructure:
- docker-compose.yml updates
- nginx-rtmp config changes
- Makefile improvements (config, dev, high, infra)
- Root package.json and lock file updates
- .env.example updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:36:06 +00:00
t . id , t . creator , t . title , t . artist , t . album , t . genre , t . duration , t . bpm , t . key ,
2026-03-23 14:46:57 +00:00
randBetween ( 10 , 500 ) , randBetween ( 2 , 50 ) , t . tags , createdAt , filePath )
feat: backend, stream server & infra improvements
Backend (Go):
- Config: CORS, RabbitMQ, rate limit, main config updates
- Routes: core, distribution, tracks routing changes
- Middleware: rate limiter, endpoint limiter, response cache hardening
- Handlers: distribution, search handler fixes
- Workers: job worker improvements
- Upload validator and logging config additions
- New migrations: products, orders, performance indexes
- Seed tooling and data
Stream Server (Rust):
- Audio processing, config, routes, simple stream server updates
- Dockerfile improvements
Infrastructure:
- docker-compose.yml updates
- nginx-rtmp config changes
- Makefile improvements (config, dev, high, infra)
- Root package.json and lock file updates
- .env.example updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:36:06 +00:00
must ( err , "track " + t . title )
}
fmt . Printf ( "%d created\n" , len ( tracks ) )
} else {
fmt . Println ( "Tracks already exist — loading IDs..." )
rows , _ := db . Query ( ` SELECT id,creator_id,title,artist,COALESCE(album,''),COALESCE(genre,''),COALESCE(musical_key,''),' { }',duration,COALESCE(bpm,0) FROM tracks ORDER BY created_at LIMIT 22 ` )
for rows != nil && rows . Next ( ) {
var t track
_ = rows . Scan ( & t . id , & t . creator , & t . title , & t . artist , & t . album , & t . genre , & t . key , & t . tags , & t . duration , & t . bpm )
tracks = append ( tracks , t )
}
if rows != nil {
rows . Close ( )
}
}
// ═════════════════════════════════════════════════════════════════════════
// PLAYLISTS (6)
// ═════════════════════════════════════════════════════════════════════════
type playlist struct { id , user , name , desc string }
var playlists [ ] playlist
if countRows ( db , "playlists" ) < 6 {
fmt . Print ( "Creating playlists... " )
playlists = [ ] playlist {
{ uuid . NewString ( ) , amelieID , "Late Night Techno" , "My favorite tracks for late sessions" } ,
{ uuid . NewString ( ) , marcusID , "Chill Beats Study" , "Perfect background music for focus" } ,
{ uuid . NewString ( ) , renzoID , "Weekend Warm-Up" , "Pre-party essentials" } ,
{ uuid . NewString ( ) , claraID , "Acoustic Mornings" , "Gentle wake-up tracks" } ,
{ uuid . NewString ( ) , users [ 6 ] . id , "Discovery Mix" , "New finds from this month" } ,
{ uuid . NewString ( ) , users [ 7 ] . id , "Workout Energy" , "High-BPM motivation" } ,
}
for _ , p := range playlists {
tryExec ( db , ` INSERT INTO playlists (id,user_id,name,title,description,visibility,is_public,is_collaborative) VALUES ($1,$2,$3,$3,$4,'public',true,false) ` ,
p . id , p . user , p . name , p . desc )
}
fmt . Printf ( "%d created\n" , len ( playlists ) )
// Playlist tracks
ptMap := [ ] struct { pi int ; ti [ ] int } {
{ 0 , [ ] int { 0 , 1 , 4 , 14 , 16 , 17 } } , { 1 , [ ] int { 5 , 7 , 9 , 18 , 19 } } ,
{ 2 , [ ] int { 14 , 15 , 16 , 3 , 4 } } , { 3 , [ ] int { 18 , 19 , 20 , 21 , 10 } } ,
{ 4 , [ ] int { 0 , 5 , 10 , 14 , 18 , 8 } } , { 5 , [ ] int { 1 , 4 , 8 , 14 , 15 , 16 } } ,
}
for _ , pt := range ptMap {
for pos , ti := range pt . ti {
if ti < len ( tracks ) {
tryExec ( db , ` INSERT INTO playlist_tracks (playlist_id,track_id,position,added_by) VALUES ($1,$2,$3,$4) ` ,
playlists [ pt . pi ] . id , tracks [ ti ] . id , pos , playlists [ pt . pi ] . user )
}
}
tryExec ( db , ` UPDATE playlists SET track_count=(SELECT COUNT(*) FROM playlist_tracks WHERE playlist_id=$1) WHERE id=$1 ` , playlists [ pt . pi ] . id )
}
} else {
fmt . Println ( "Playlists already exist — skipping" )
}
// ═════════════════════════════════════════════════════════════════════════
// FOLLOWS (18)
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "follows" ) < 10 {
fmt . Print ( "Creating follows... " )
follows := [ ] [ 2 ] int {
fix: stabilize frontend — 98 TS errors to 0, align API endpoints, optimize bundle
- Fix 98 TypeScript errors across 37 files:
- Service layer double-unwrapping (subscriptionService, distributionService, gearService)
- Self-referencing variables in SearchPageResults
- FeedView/ExploreView .posts→.items alignment
- useQueueSync Zustand subscribe API
- AdminAuditLogsView missing interface fields
- Toast proxy type, interceptor type narrowing
- 22 unused imports/variables removed
- 5 storybook mock data fixes
- Align frontend API calls with backend endpoints:
- Analytics: useAnalyticsView now calls /creator/analytics/dashboard (was /analytics)
- Chat: chatService uses /conversations (was mock data), WS URL from backend token
- Dashboard StatsSection: uses real /dashboard API data (was hardcoded zeros)
- Settings: suppress 2FA toast error when endpoint unavailable
- Fix marketplace products: seed uses 'active' status (was 'published')
- Enrich seed: admin follows all creators (feed has content)
- Optimize bundle: vendor catch-all 793KB→318KB gzip (-60%)
Split into vendor-charts, vendor-emoji, vendor-swagger, vendor-media, etc.
- Clean repo: remove ~100 orphaned screenshots, audit reports, logs from root
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:18:49 +00:00
// Listeners follow creators
feat: backend, stream server & infra improvements
Backend (Go):
- Config: CORS, RabbitMQ, rate limit, main config updates
- Routes: core, distribution, tracks routing changes
- Middleware: rate limiter, endpoint limiter, response cache hardening
- Handlers: distribution, search handler fixes
- Workers: job worker improvements
- Upload validator and logging config additions
- New migrations: products, orders, performance indexes
- Seed tooling and data
Stream Server (Rust):
- Audio processing, config, routes, simple stream server updates
- Dockerfile improvements
Infrastructure:
- docker-compose.yml updates
- nginx-rtmp config changes
- Makefile improvements (config, dev, high, infra)
- Root package.json and lock file updates
- .env.example updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:36:06 +00:00
{ 6 , 1 } , { 6 , 2 } , { 6 , 4 } , { 7 , 1 } , { 7 , 3 } , { 7 , 4 } , { 7 , 2 } ,
{ 8 , 1 } , { 8 , 2 } , { 8 , 3 } , { 8 , 4 } , { 8 , 5 } ,
fix: stabilize frontend — 98 TS errors to 0, align API endpoints, optimize bundle
- Fix 98 TypeScript errors across 37 files:
- Service layer double-unwrapping (subscriptionService, distributionService, gearService)
- Self-referencing variables in SearchPageResults
- FeedView/ExploreView .posts→.items alignment
- useQueueSync Zustand subscribe API
- AdminAuditLogsView missing interface fields
- Toast proxy type, interceptor type narrowing
- 22 unused imports/variables removed
- 5 storybook mock data fixes
- Align frontend API calls with backend endpoints:
- Analytics: useAnalyticsView now calls /creator/analytics/dashboard (was /analytics)
- Chat: chatService uses /conversations (was mock data), WS URL from backend token
- Dashboard StatsSection: uses real /dashboard API data (was hardcoded zeros)
- Settings: suppress 2FA toast error when endpoint unavailable
- Fix marketplace products: seed uses 'active' status (was 'published')
- Enrich seed: admin follows all creators (feed has content)
- Optimize bundle: vendor catch-all 793KB→318KB gzip (-60%)
Split into vendor-charts, vendor-emoji, vendor-swagger, vendor-media, etc.
- Clean repo: remove ~100 orphaned screenshots, audit reports, logs from root
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:18:49 +00:00
// Creators follow each other
feat: backend, stream server & infra improvements
Backend (Go):
- Config: CORS, RabbitMQ, rate limit, main config updates
- Routes: core, distribution, tracks routing changes
- Middleware: rate limiter, endpoint limiter, response cache hardening
- Handlers: distribution, search handler fixes
- Workers: job worker improvements
- Upload validator and logging config additions
- New migrations: products, orders, performance indexes
- Seed tooling and data
Stream Server (Rust):
- Audio processing, config, routes, simple stream server updates
- Dockerfile improvements
Infrastructure:
- docker-compose.yml updates
- nginx-rtmp config changes
- Makefile improvements (config, dev, high, infra)
- Root package.json and lock file updates
- .env.example updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:36:06 +00:00
{ 1 , 2 } , { 2 , 1 } , { 1 , 4 } , { 4 , 1 } , { 3 , 1 } , { 5 , 2 } , { 5 , 3 } ,
fix: stabilize frontend — 98 TS errors to 0, align API endpoints, optimize bundle
- Fix 98 TypeScript errors across 37 files:
- Service layer double-unwrapping (subscriptionService, distributionService, gearService)
- Self-referencing variables in SearchPageResults
- FeedView/ExploreView .posts→.items alignment
- useQueueSync Zustand subscribe API
- AdminAuditLogsView missing interface fields
- Toast proxy type, interceptor type narrowing
- 22 unused imports/variables removed
- 5 storybook mock data fixes
- Align frontend API calls with backend endpoints:
- Analytics: useAnalyticsView now calls /creator/analytics/dashboard (was /analytics)
- Chat: chatService uses /conversations (was mock data), WS URL from backend token
- Dashboard StatsSection: uses real /dashboard API data (was hardcoded zeros)
- Settings: suppress 2FA toast error when endpoint unavailable
- Fix marketplace products: seed uses 'active' status (was 'published')
- Enrich seed: admin follows all creators (feed has content)
- Optimize bundle: vendor catch-all 793KB→318KB gzip (-60%)
Split into vendor-charts, vendor-emoji, vendor-swagger, vendor-media, etc.
- Clean repo: remove ~100 orphaned screenshots, audit reports, logs from root
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:18:49 +00:00
// Admin follows all creators (so feed has content)
{ 0 , 1 } , { 0 , 2 } , { 0 , 3 } , { 0 , 4 } , { 0 , 5 } ,
feat: backend, stream server & infra improvements
Backend (Go):
- Config: CORS, RabbitMQ, rate limit, main config updates
- Routes: core, distribution, tracks routing changes
- Middleware: rate limiter, endpoint limiter, response cache hardening
- Handlers: distribution, search handler fixes
- Workers: job worker improvements
- Upload validator and logging config additions
- New migrations: products, orders, performance indexes
- Seed tooling and data
Stream Server (Rust):
- Audio processing, config, routes, simple stream server updates
- Dockerfile improvements
Infrastructure:
- docker-compose.yml updates
- nginx-rtmp config changes
- Makefile improvements (config, dev, high, infra)
- Root package.json and lock file updates
- .env.example updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:36:06 +00:00
}
c := 0
for _ , f := range follows {
if _ , err := db . Exec ( ` INSERT INTO follows (follower_id,followed_id) VALUES ($1,$2) ON CONFLICT DO NOTHING ` , users [ f [ 0 ] ] . id , users [ f [ 1 ] ] . id ) ; err == nil {
c ++
}
}
fmt . Printf ( "%d created\n" , c )
}
// ═════════════════════════════════════════════════════════════════════════
// CHAT ROOMS & MESSAGES
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "rooms" ) == 0 {
fmt . Print ( "Creating chat rooms & messages... " )
roomIDs := [ 3 ] string { uuid . NewString ( ) , uuid . NewString ( ) , uuid . NewString ( ) }
roomData := [ ] struct { name , owner string } {
{ "General" , users [ 0 ] . id } , { "Production Tips" , amelieID } , { "Beat Marketplace" , marcusID } ,
}
for i , r := range roomData {
tryExec ( db , ` INSERT INTO rooms (id,name,owner_id,creator_id,room_type,is_private,created_at,updated_at) VALUES ($1,$2,$3,$3,'group',false,NOW(),NOW()) ` , roomIDs [ i ] , r . name , r . owner )
}
for _ , rid := range roomIDs {
for _ , u := range users [ : 8 ] {
tryExec ( db , ` INSERT INTO room_members (room_id,user_id,role) VALUES ($1,$2,'member') ON CONFLICT DO NOTHING ` , rid , u . id )
}
}
msgs := [ ] struct { r , s int ; c string } {
{ 0 , 1 , "Hey everyone! Welcome to Veza." } , { 0 , 2 , "Glad to be here. Just uploaded some new beats!" } ,
{ 0 , 6 , "Love the vibes on this platform." } , { 0 , 3 , "Anyone interested in some cinematic samples?" } ,
{ 0 , 4 , "Weekend set coming soon, stay tuned!" } , { 1 , 1 , "What DAW is everyone using?" } ,
{ 1 , 2 , "Ableton all the way. FL Studio for quick ideas." } , { 1 , 3 , "Pro Tools for recording, Reaper for mixing." } ,
{ 1 , 5 , "Logic Pro X here. Love the stock plugins." } , { 2 , 2 , "New beat pack dropping this weekend. 10 beats, all original." } ,
{ 2 , 7 , "How much for exclusive rights?" } , { 2 , 2 , "DM me for pricing on exclusives!" } ,
}
for i , m := range msgs {
ts := hoursAgo ( len ( msgs ) - i )
tryExec ( db , ` INSERT INTO messages (room_id,sender_id,user_id,content,message_type,created_at,updated_at) VALUES ($1,$2,$2,$3,'text',$4,$4) ` ,
roomIDs [ m . r ] , users [ m . s ] . id , m . c , ts )
}
fmt . Printf ( "3 rooms, %d messages\n" , len ( msgs ) )
}
// ═════════════════════════════════════════════════════════════════════════
// TRACK PLAYS (analytics — fixed column names)
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "track_plays" ) == 0 {
fmt . Print ( "Creating play history... " )
c := 0
listeners := [ ] int { 6 , 7 , 8 }
sources := [ ] string { "web" , "mobile" , "api" }
countries := [ ] string { "FR" , "US" , "DE" , "GB" , "JP" , "BR" , "CA" }
for _ , li := range listeners {
for _ , t := range tracks {
// Each listener plays ~70% of tracks, some multiple times
plays := 0
if rand . Intn ( 10 ) < 7 {
plays = 1
}
if rand . Intn ( 10 ) < 3 {
plays = randBetween ( 2 , 5 ) // replay
}
for p := 0 ; p < plays ; p ++ {
ts := daysAgo ( randBetween ( 0 , 45 ) )
dur := t . duration * randBetween ( 60 , 100 ) / 100 // 60-100% of track
tryExec ( db , ` INSERT INTO track_plays ( track_id , user_id , duration , played_at , source , country_code , created_at , updated_at )
VALUES ( $ 1 , $ 2 , $ 3 , $ 4 , $ 5 , $ 6 , $ 4 , $ 4 ) ` ,
t . id , users [ li ] . id , dur , ts , sources [ rand . Intn ( len ( sources ) ) ] , countries [ rand . Intn ( len ( countries ) ) ] )
c ++
}
}
}
fmt . Printf ( "%d plays recorded\n" , c )
}
// ═════════════════════════════════════════════════════════════════════════
// TRACK LIKES
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "track_likes" ) < 20 {
fmt . Print ( "Creating likes... " )
c := 0
for _ , li := range [ ] int { 6 , 7 , 8 } {
for i , t := range tracks {
if i % 3 == 0 || i % 5 == 0 || rand . Intn ( 4 ) == 0 {
if _ , err := db . Exec ( ` INSERT INTO track_likes (track_id,user_id) VALUES ($1,$2) ON CONFLICT DO NOTHING ` , t . id , users [ li ] . id ) ; err == nil {
c ++
}
}
}
}
fmt . Printf ( "%d likes\n" , c )
}
// ═════════════════════════════════════════════════════════════════════════
// COMMENTS
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "comments" ) == 0 {
fmt . Print ( "Creating comments... " )
commentData := [ ] struct { track , user int ; content string } {
{ 0 , 6 , "This track is incredible, the synth work is amazing!" } , { 0 , 7 , "Perfect for late night coding sessions." } ,
{ 0 , 8 , "Amelie never disappoints. 🔥" } , { 1 , 7 , "Dark and moody, love it." } ,
{ 5 , 6 , "These loops are so clean." } , { 5 , 8 , "Could listen to this on repeat all day." } ,
{ 7 , 6 , "Smooth R&B vibes, exactly what I needed." } , { 10 , 8 , "Beautiful nature sounds, so calming." } ,
{ 14 , 7 , "DJ Renzo always brings the groove!" } , { 14 , 6 , "This one gets the party started!" } ,
{ 18 , 6 , "Clara your voice is so beautiful." } , { 18 , 8 , "Acoustic perfection." } ,
{ 20 , 7 , "This made me emotional, beautiful songwriting." } , { 9 , 6 , "Lo-fi perfection for rainy days." } ,
{ 3 , 8 , "The production quality is top notch." } , { 16 , 7 , "Deep house at its finest." } ,
{ 11 , 6 , "I can hear the ocean in my headphones." } , { 19 , 8 , "Morning Light is my alarm song now." } ,
{ 4 , 7 , "Peak time techno! Need this in a set." } , { 15 , 6 , "Funky Elevator is an instant classic." } ,
}
for _ , cm := range commentData {
if cm . track < len ( tracks ) {
tryExec ( db , ` INSERT INTO comments (user_id,target_id,target_type,content,created_at,updated_at) VALUES ($1,$2,'track',$3,$4,$4) ` ,
users [ cm . user ] . id , tracks [ cm . track ] . id , cm . content , daysAgo ( randBetween ( 0 , 30 ) ) )
}
}
fmt . Printf ( "%d comments\n" , len ( commentData ) )
}
// ═════════════════════════════════════════════════════════════════════════
// NOTIFICATIONS (fixed: column "read" not "is_read", "content" not "message")
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "notifications" ) == 0 {
fmt . Print ( "Creating notifications... " )
notifs := [ ] struct { user int ; ntype , title , content string } {
{ 1 , "follow" , "New follower" , "music_lover started following you" } ,
{ 1 , "follow" , "New follower" , "groove_hunter started following you" } ,
{ 2 , "follow" , "New follower" , "night_owl started following you" } ,
{ 1 , "like" , "Track liked" , "Someone liked your track Neon Dreams" } ,
{ 2 , "like" , "Track liked" , "Someone liked your track Late Night Loops" } ,
{ 3 , "like" , "Track liked" , "Someone liked your track Forest Whispers" } ,
{ 4 , "comment" , "New comment" , "music_lover commented on Saturday Night Edit" } ,
{ 5 , "comment" , "New comment" , "night_owl commented on Paper Boats" } ,
{ 1 , "system" , "Welcome" , "Welcome to Veza! Start by uploading your first track." } ,
{ 6 , "system" , "Welcome" , "Welcome to Veza! Discover amazing music from independent artists." } ,
{ 7 , "system" , "Welcome" , "Welcome to Veza! Follow your favorite artists to see their new releases." } ,
{ 0 , "system" , "Admin alert" , "New user registrations this week: 5" } ,
{ 2 , "milestone" , "Milestone reached" , "Your track Late Night Loops just hit 100 plays!" } ,
{ 1 , "milestone" , "Milestone reached" , "You now have 5 followers!" } ,
}
for _ , n := range notifs {
tryExec ( db , ` INSERT INTO notifications (user_id,type,title,content,read,created_at,updated_at) VALUES ($1,$2,$3,$4,false,$5,$5) ` ,
users [ n . user ] . id , n . ntype , n . title , n . content , daysAgo ( randBetween ( 0 , 14 ) ) )
}
fmt . Printf ( "%d created\n" , len ( notifs ) )
}
// ═════════════════════════════════════════════════════════════════════════
// PRODUCTS (marketplace — 12 products from creators)
// ═════════════════════════════════════════════════════════════════════════
type product struct { id , seller , title , desc , ptype , license , category string ; price float64 ; trackIdx int ; bpm int ; key string }
var products [ ] product
if countRows ( db , "products" ) == 0 {
fmt . Print ( "Creating marketplace products... " )
products = [ ] product {
{ uuid . NewString ( ) , marcusID , "Lo-Fi Beats Pack Vol.1" , "10 royalty-free lo-fi beats for content creators" , "sample-pack" , "non-exclusive" , "beats" , 29.99 , - 1 , 80 , "Cm" } ,
{ uuid . NewString ( ) , marcusID , "Trap Essentials" , "5 hard-hitting trap beats ready to use" , "sample-pack" , "non-exclusive" , "beats" , 19.99 , - 1 , 140 , "Gm" } ,
{ uuid . NewString ( ) , amelieID , "Neon Dreams — Exclusive License" , "Full exclusive rights to Neon Dreams" , "beat" , "exclusive" , "electronic" , 299.99 , 0 , 128 , "Am" } ,
{ uuid . NewString ( ) , amelieID , "Synth Textures Pack" , "50 custom synth one-shots and loops" , "sample-pack" , "non-exclusive" , "samples" , 14.99 , - 1 , 0 , "" } ,
{ uuid . NewString ( ) , amelieID , "Techno Stems — Midnight Protocol" , "Individual stems for remix" , "beat" , "non-exclusive" , "stems" , 49.99 , 1 , 132 , "Dm" } ,
{ uuid . NewString ( ) , renzoID , "Disco Edits Bundle" , "3 disco edits ready for DJ sets" , "sample-pack" , "non-exclusive" , "dj-tools" , 24.99 , - 1 , 120 , "G" } ,
{ uuid . NewString ( ) , renzoID , "Saturday Night Edit — License" , "Non-exclusive license for streaming" , "beat" , "non-exclusive" , "house" , 39.99 , 14 , 122 , "G" } ,
{ uuid . NewString ( ) , sakuraID , "Cinematic Foley Collection" , "200+ foley sounds from nature recordings" , "sample-pack" , "non-exclusive" , "sfx" , 34.99 , - 1 , 0 , "" } ,
{ uuid . NewString ( ) , sakuraID , "Ambient Textures Vol.1" , "Layered ambient textures for film scoring" , "sample-pack" , "non-exclusive" , "ambient" , 19.99 , - 1 , 0 , "" } ,
{ uuid . NewString ( ) , claraID , "Acoustic Guitar Loops" , "15 acoustic guitar loops in various keys" , "sample-pack" , "non-exclusive" , "acoustic" , 12.99 , - 1 , 95 , "G" } ,
{ uuid . NewString ( ) , claraID , "Paper Boats — Sync License" , "Sync license for film/TV/ads" , "beat" , "non-exclusive" , "sync" , 149.99 , 18 , 95 , "G" } ,
{ uuid . NewString ( ) , marcusID , "City Lights — Lease" , "Standard lease for City Lights beat" , "beat" , "non-exclusive" , "trap" , 49.99 , 8 , 140 , "Gm" } ,
}
for _ , p := range products {
var trackID interface { }
if p . trackIdx >= 0 && p . trackIdx < len ( tracks ) {
trackID = tracks [ p . trackIdx ] . id
}
tryExec ( db , ` INSERT INTO products ( id , seller_id , title , description , price , currency , status , product_type , track_id , license_type , bpm , musical_key , category , created_at , updated_at )
fix: stabilize frontend — 98 TS errors to 0, align API endpoints, optimize bundle
- Fix 98 TypeScript errors across 37 files:
- Service layer double-unwrapping (subscriptionService, distributionService, gearService)
- Self-referencing variables in SearchPageResults
- FeedView/ExploreView .posts→.items alignment
- useQueueSync Zustand subscribe API
- AdminAuditLogsView missing interface fields
- Toast proxy type, interceptor type narrowing
- 22 unused imports/variables removed
- 5 storybook mock data fixes
- Align frontend API calls with backend endpoints:
- Analytics: useAnalyticsView now calls /creator/analytics/dashboard (was /analytics)
- Chat: chatService uses /conversations (was mock data), WS URL from backend token
- Dashboard StatsSection: uses real /dashboard API data (was hardcoded zeros)
- Settings: suppress 2FA toast error when endpoint unavailable
- Fix marketplace products: seed uses 'active' status (was 'published')
- Enrich seed: admin follows all creators (feed has content)
- Optimize bundle: vendor catch-all 793KB→318KB gzip (-60%)
Split into vendor-charts, vendor-emoji, vendor-swagger, vendor-media, etc.
- Clean repo: remove ~100 orphaned screenshots, audit reports, logs from root
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:18:49 +00:00
VALUES ( $ 1 , $ 2 , $ 3 , $ 4 , $ 5 , ' EUR ',' active ' , $ 6 , $ 7 , $ 8 , $ 9 , $ 10 , $ 11 , NOW ( ) - interval ' 1 day ' * $ 12 , NOW ( ) ) ` ,
feat: backend, stream server & infra improvements
Backend (Go):
- Config: CORS, RabbitMQ, rate limit, main config updates
- Routes: core, distribution, tracks routing changes
- Middleware: rate limiter, endpoint limiter, response cache hardening
- Handlers: distribution, search handler fixes
- Workers: job worker improvements
- Upload validator and logging config additions
- New migrations: products, orders, performance indexes
- Seed tooling and data
Stream Server (Rust):
- Audio processing, config, routes, simple stream server updates
- Dockerfile improvements
Infrastructure:
- docker-compose.yml updates
- nginx-rtmp config changes
- Makefile improvements (config, dev, high, infra)
- Root package.json and lock file updates
- .env.example updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:36:06 +00:00
p . id , p . seller , p . title , p . desc , p . price , p . ptype , trackID , p . license , p . bpm , p . key , p . category , randBetween ( 1 , 30 ) )
}
fmt . Printf ( "%d products\n" , len ( products ) )
} else {
fmt . Println ( "Products already exist — loading IDs..." )
rows , _ := db . Query ( ` SELECT id,seller_id,title FROM products ORDER BY created_at LIMIT 12 ` )
for rows != nil && rows . Next ( ) {
var p product
_ = rows . Scan ( & p . id , & p . seller , & p . title )
products = append ( products , p )
}
if rows != nil {
rows . Close ( )
}
}
// ═════════════════════════════════════════════════════════════════════════
// ORDERS & ORDER ITEMS (4 completed purchases)
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "orders" ) == 0 && len ( products ) >= 6 {
fmt . Print ( "Creating orders... " )
orderData := [ ] struct { buyer int ; productIdxs [ ] int ; total float64 } {
{ 6 , [ ] int { 0 , 3 } , 44.98 } , // music_lover buys lo-fi pack + synth textures
{ 7 , [ ] int { 1 , 5 } , 44.98 } , // groove_hunter buys trap essentials + disco edits
{ 8 , [ ] int { 6 , 9 } , 52.98 } , // night_owl buys saturday night license + acoustic loops
{ 6 , [ ] int { 7 } , 34.99 } , // music_lover buys foley collection
}
for _ , o := range orderData {
oid := uuid . NewString ( )
tryExec ( db , ` INSERT INTO orders (id,buyer_id,total_amount,currency,status,created_at,updated_at) VALUES ($1,$2,$3,'EUR','completed',$4,$4) ` ,
oid , users [ o . buyer ] . id , o . total , daysAgo ( randBetween ( 1 , 20 ) ) )
for _ , pi := range o . productIdxs {
if pi < len ( products ) {
tryExec ( db , ` INSERT INTO order_items (order_id,product_id,price) VALUES ($1,$2,$3) ` , oid , products [ pi ] . id , products [ pi ] . price )
}
}
}
fmt . Printf ( "%d orders\n" , len ( orderData ) )
}
// ═════════════════════════════════════════════════════════════════════════
// DAILY TRACK STATS (last 30 days for top tracks)
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "daily_track_stats" ) == 0 {
fmt . Print ( "Creating daily track stats... " )
c := 0
for _ , t := range tracks [ : 10 ] { // top 10 tracks
for d := 0 ; d < 30 ; d ++ {
date := daysAgo ( d ) . Format ( "2006-01-02" )
plays := randBetween ( 1 , 25 )
uniq := randBetween ( 1 , plays )
complete := randBetween ( 0 , uniq )
totalTime := plays * t . duration * randBetween ( 60 , 100 ) / 100
avgCompl := float64 ( randBetween ( 50 , 95 ) ) / 100
tryExec ( db , ` INSERT INTO daily_track_stats (track_id,date,total_plays,unique_listeners,complete_listens,total_play_time,avg_completion_rate) VALUES ($1,$2,$3,$4,$5,$6,$7) ON CONFLICT DO NOTHING ` ,
t . id , date , plays , uniq , complete , totalTime , avgCompl )
c ++
}
}
fmt . Printf ( "%d stat rows\n" , c )
}
// ═════════════════════════════════════════════════════════════════════════
// COURSES & LESSONS (education)
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "courses" ) == 0 {
fmt . Print ( "Creating courses & lessons... " )
courseData := [ ] struct { creator , title , slug , desc , category , level string ; price int ; lessonCount int } {
{ amelieID , "Introduction to Music Production" , "intro-music-production" , "Learn the basics of music production with Ableton Live. From your first beat to a finished track." , "production" , "beginner" , 0 , 8 } ,
{ amelieID , "Melodic Techno Masterclass" , "melodic-techno-masterclass" , "Deep dive into melodic techno production techniques, sound design, and arrangement." , "production" , "intermediate" , 4999 , 12 } ,
{ marcusID , "Hip-Hop Beat Making 101" , "hiphop-beatmaking-101" , "Learn to make hard-hitting hip-hop beats from scratch. Sampling, drum programming, mixing." , "production" , "beginner" , 2999 , 10 } ,
{ sakuraID , "Field Recording & Sound Design" , "field-recording-sound-design" , "Capture the world around you and turn it into cinematic soundscapes." , "sound-design" , "intermediate" , 3999 , 6 } ,
{ claraID , "Songwriting for Beginners" , "songwriting-beginners" , "Find your voice, write meaningful lyrics, and structure your songs." , "songwriting" , "beginner" , 0 , 5 } ,
}
for _ , cd := range courseData {
cid := uuid . NewString ( )
status := "published"
var publishedAt interface { } = daysAgo ( randBetween ( 5 , 40 ) )
tryExec ( db , ` INSERT INTO courses ( id , creator_id , title , slug , description , category , tags , price_cents , currency , pricing_model , status , level , language , lesson_count , published_at , created_at , updated_at )
VALUES ( $ 1 , $ 2 , $ 3 , $ 4 , $ 5 , $ 6 , ARRAY [ ' music ',' production ' ] , $ 7 , ' EUR ',' fixed ' , $ 8 , $ 9 , ' fr ' , $ 10 , $ 11 , $ 12 , $ 12 ) ` ,
cid , cd . creator , cd . title , cd . slug , cd . desc , cd . category , cd . price , status , cd . level , cd . lessonCount , publishedAt , daysAgo ( randBetween ( 10 , 50 ) ) )
// Create lessons for this course
lessonTitles := [ ] string {
"Getting Started" , "Setting Up Your DAW" , "Understanding Audio Basics" , "Your First Beat" ,
"Melody and Harmony" , "Sound Design Fundamentals" , "Arrangement Techniques" , "Mixing Basics" ,
"EQ and Compression" , "Effects and Processing" , "Mastering Your Track" , "Final Project" ,
}
for li := 0 ; li < cd . lessonCount && li < len ( lessonTitles ) ; li ++ {
tryExec ( db , ` INSERT INTO lessons (course_id,order_index,title,description,duration_seconds,is_preview_free,transcoding_status) VALUES ($1,$2,$3,$4,$5,$6,'completed') ` ,
cid , li , lessonTitles [ li ] , fmt . Sprintf ( "Lesson %d of %s" , li + 1 , cd . title ) , randBetween ( 300 , 1800 ) , li < 2 )
}
}
fmt . Printf ( "%d courses\n" , len ( courseData ) )
// Enroll some users
rows , _ := db . Query ( ` SELECT id FROM courses LIMIT 5 ` )
var courseIDs [ ] string
for rows != nil && rows . Next ( ) {
var id string
_ = rows . Scan ( & id )
courseIDs = append ( courseIDs , id )
}
if rows != nil {
rows . Close ( )
}
for _ , cid := range courseIDs {
for _ , ui := range [ ] int { 6 , 7 , 8 } {
if rand . Intn ( 3 ) == 0 {
tryExec ( db , ` INSERT INTO course_enrollments (user_id,course_id,status,purchased_at) VALUES ($1,$2,'active',NOW()-interval '1 day'*$3) ON CONFLICT DO NOTHING ` ,
users [ ui ] . id , cid , randBetween ( 1 , 20 ) )
}
}
}
}
// ═════════════════════════════════════════════════════════════════════════
// GEAR ITEMS (creator equipment)
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "gear_items" ) == 0 {
fmt . Print ( "Creating gear inventory... " )
gearData := [ ] struct { user int ; name , cat , brand , model , status , condition string ; price float64 } {
{ 1 , "Ableton Push 3" , "controller" , "Ableton" , "Push 3" , "Active" , "Excellent" , 999 } ,
{ 1 , "Focal Shape 65" , "monitors" , "Focal" , "Shape 65" , "Active" , "Good" , 599 } ,
{ 1 , "RME Babyface Pro FS" , "audio-interface" , "RME" , "Babyface Pro FS" , "Active" , "Excellent" , 849 } ,
{ 2 , "Akai MPC One+" , "sampler" , "Akai" , "MPC One+" , "Active" , "Good" , 699 } ,
{ 2 , "Audio-Technica AT2020" , "microphone" , "Audio-Technica" , "AT2020" , "Active" , "Good" , 99 } ,
{ 2 , "Beyerdynamic DT 770 Pro" , "headphones" , "Beyerdynamic" , "DT 770 Pro" , "Active" , "Fair" , 159 } ,
{ 3 , "Zoom H6" , "recorder" , "Zoom" , "H6" , "Active" , "Excellent" , 349 } ,
{ 3 , "Sennheiser MKH 416" , "microphone" , "Sennheiser" , "MKH 416" , "Active" , "Good" , 999 } ,
{ 4 , "Pioneer DDJ-1000" , "dj-controller" , "Pioneer" , "DDJ-1000" , "Active" , "Good" , 1199 } ,
{ 4 , "Allen & Heath Xone:96" , "mixer" , "Allen & Heath" , "Xone:96" , "Active" , "Excellent" , 1899 } ,
{ 5 , "Martin D-28" , "guitar" , "Martin" , "D-28" , "Active" , "Good" , 2999 } ,
{ 5 , "Neumann U87" , "microphone" , "Neumann" , "U87" , "Active" , "Excellent" , 3199 } ,
}
for _ , g := range gearData {
tryExec ( db , ` INSERT INTO gear_items ( user_id , name , category , brand , model , status , condition , purchase_price , currency , purchase_date , is_public , created_at , updated_at )
VALUES ( $ 1 , $ 2 , $ 3 , $ 4 , $ 5 , $ 6 , $ 7 , $ 8 , ' EUR ' , $ 9 , true , NOW ( ) , NOW ( ) ) ` ,
users [ g . user ] . id , g . name , g . cat , g . brand , g . model , g . status , g . condition , g . price , daysAgo ( randBetween ( 30 , 365 ) ) . Format ( "2006-01-02" ) )
}
fmt . Printf ( "%d items\n" , len ( gearData ) )
}
// ═════════════════════════════════════════════════════════════════════════
// LIVE STREAMS (scheduled + past)
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "live_streams" ) == 0 {
fmt . Print ( "Creating live streams... " )
liveData := [ ] struct { user int ; title , desc , cat string ; isLive bool ; viewers int } {
{ 4 , "Friday Night Disco Set" , "Live disco & house set from my studio" , "dj-set" , false , 0 } ,
{ 1 , "Production Session — New EP Preview" , "Working on new melodic techno tracks live" , "production" , false , 0 } ,
{ 2 , "Beat Making LIVE — Taking Requests" , "Making beats on the spot, drop your ideas in chat" , "production" , false , 0 } ,
{ 5 , "Acoustic Session — Unplugged" , "Playing some originals and covers" , "performance" , false , 0 } ,
}
for _ , l := range liveData {
tryExec ( db , ` INSERT INTO live_streams ( user_id , title , description , category , streamer_name , is_live , viewer_count , tags , scheduled_at , created_at , updated_at )
VALUES ( $ 1 , $ 2 , $ 3 , $ 4 , $ 5 , $ 6 , $ 7 , ' [ ] ' : : jsonb , $ 8 , NOW ( ) , NOW ( ) ) ` ,
users [ l . user ] . id , l . title , l . desc , l . cat , users [ l . user ] . display , l . isLive , l . viewers ,
daysAgo ( - randBetween ( 1 , 14 ) ) ) // future scheduled
}
fmt . Printf ( "%d streams\n" , len ( liveData ) )
}
// ═════════════════════════════════════════════════════════════════════════
// ANNOUNCEMENTS
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "announcements" ) == 0 {
fmt . Print ( "Creating announcements... " )
annData := [ ] struct { title , content , atype string } {
{ "Welcome to Veza!" , "We're thrilled to launch Veza — an ethical music platform built for artists and listeners. Explore, create, and connect." , "info" } ,
{ "Marketplace Now Open" , "Buy and sell beats, samples, and presets directly on the platform. Fair pricing, transparent licensing." , "feature" } ,
{ "Scheduled Maintenance" , "Brief maintenance window planned for Sunday 3am-5am CET. Streams may be briefly interrupted." , "warning" } ,
}
for _ , a := range annData {
tryExec ( db , ` INSERT INTO announcements (title,content,type,is_active,starts_at,created_by,created_at) VALUES ($1,$2,$3,true,NOW(),$4,NOW()) ` ,
a . title , a . content , a . atype , users [ 0 ] . id )
}
fmt . Printf ( "%d announcements\n" , len ( annData ) )
}
// ═════════════════════════════════════════════════════════════════════════
// SUPPORT TICKETS
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "support_tickets" ) == 0 {
fmt . Print ( "Creating support tickets... " )
ticketData := [ ] struct { user int ; email , subject , msg , cat , status string } {
{ 6 , "listener1@veza.fr" , "Cannot upload profile picture" , "I keep getting an error when trying to upload my avatar. File is a 2MB JPEG." , "technical" , "open" } ,
{ 7 , "listener2@veza.fr" , "How to create a playlist?" , "I'm new here, how do I create a collaborative playlist?" , "general" , "resolved" } ,
{ 2 , "marcus@veza.fr" , "Payment not received for beat sale" , "Sold a beat 5 days ago but haven't received the payout yet." , "billing" , "open" } ,
{ 8 , "listener3@veza.fr" , "Feature request: dark mode scheduler" , "Would love to have dark mode auto-switch at sunset." , "feature" , "open" } ,
}
for _ , t := range ticketData {
tryExec ( db , ` INSERT INTO support_tickets (user_id,email,subject,message,category,status,created_at) VALUES ($1,$2,$3,$4,$5,$6,$7) ` ,
users [ t . user ] . id , t . email , t . subject , t . msg , t . cat , t . status , daysAgo ( randBetween ( 0 , 10 ) ) )
}
fmt . Printf ( "%d tickets\n" , len ( ticketData ) )
}
// ═════════════════════════════════════════════════════════════════════════
// API KEYS (developer portal)
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "api_keys" ) == 0 {
fmt . Print ( "Creating API keys... " )
apiKeyData := [ ] struct { user int ; name string ; scopes string } {
{ 1 , "Amelie Production Bot" , "{read,write,tracks}" } ,
{ 2 , "Marcus Beat Distributor" , "{read,tracks,marketplace}" } ,
}
for _ , k := range apiKeyData {
prefix := fmt . Sprintf ( "veza_%s" , uuid . NewString ( ) [ : 8 ] )
hashedKey , _ := bcrypt . GenerateFromPassword ( [ ] byte ( uuid . NewString ( ) ) , 10 )
tryExec ( db , ` INSERT INTO api_keys (user_id,name,prefix,hashed_key,scopes,created_at) VALUES ($1,$2,$3,$4,$5::text[],NOW()) ` ,
users [ k . user ] . id , k . name , prefix , string ( hashedKey ) , k . scopes )
}
fmt . Printf ( "%d keys\n" , len ( apiKeyData ) )
}
// ═════════════════════════════════════════════════════════════════════════
// ANALYTICS EVENTS (general platform events)
// ═════════════════════════════════════════════════════════════════════════
if countRows ( db , "analytics_events" ) == 0 {
fmt . Print ( "Creating analytics events... " )
c := 0
eventTypes := [ ] string { "page_view" , "track_play" , "search" , "playlist_create" , "follow" , "signup" , "login" }
for d := 0 ; d < 14 ; d ++ {
numEvents := randBetween ( 20 , 80 )
for e := 0 ; e < numEvents ; e ++ {
userIdx := rand . Intn ( len ( users ) )
evt := eventTypes [ rand . Intn ( len ( eventTypes ) ) ]
tryExec ( db , ` INSERT INTO analytics_events (event_name,user_id,payload,created_at) VALUES ($1,$2,$3,$4) ` ,
evt , users [ userIdx ] . id , fmt . Sprintf ( ` { "source":"web","page":"/dashboard","session_id":"%s"} ` , uuid . NewString ( ) [ : 8 ] ) ,
daysAgo ( d ) . Add ( time . Duration ( randBetween ( 0 , 86400 ) ) * time . Second ) )
c ++
}
}
fmt . Printf ( "%d events\n" , c )
}
// ═════════════════════════════════════════════════════════════════════════
// SUMMARY
// ═════════════════════════════════════════════════════════════════════════
fmt . Println ( )
fmt . Println ( "╔═══════════════════════════════════════════════╗" )
fmt . Println ( "║ Seed Complete! ║" )
fmt . Println ( "╚═══════════════════════════════════════════════╝" )
fmt . Println ( )
tables := [ ] string {
"users" , "tracks" , "playlists" , "follows" , "rooms" , "messages" ,
"track_plays" , "track_likes" , "comments" , "notifications" ,
"products" , "orders" , "order_items" , "daily_track_stats" ,
"courses" , "lessons" , "course_enrollments" , "gear_items" ,
"live_streams" , "announcements" , "support_tickets" , "api_keys" , "analytics_events" ,
}
for _ , t := range tables {
fmt . Printf ( " %-24s %d rows\n" , t , countRows ( db , t ) )
}
fmt . Println ( )
fmt . Println ( "--- Login Credentials (Password123! for all) ---" )
fmt . Println ( " Admin: admin@veza.fr" )
fmt . Println ( " Creator: amelie@veza.fr / marcus@veza.fr / sakura@veza.fr" )
fmt . Println ( " Creator: djrenzo@veza.fr / clara@veza.fr" )
fmt . Println ( " Listener: listener1@veza.fr / listener2@veza.fr / listener3@veza.fr" )
fmt . Println ( " Moderator: mod@veza.fr" )
fmt . Println ( )
fmt . Println ( " Dashboard: http://veza.fr:5173/dashboard" )
}