veza/veza-backend-api/cmd/tools/seed/seed_misc.go

196 lines
8 KiB
Go
Raw Normal View History

package main
import (
"database/sql"
"fmt"
"time"
)
// SeedMisc creates support_tickets, api_keys, announcements, data_exports,
// login_history, audit_logs, and user_preferences.
func SeedMisc(db *sql.DB, cfg Config, users []SeededUser) error {
fmt.Println("\n═══ MISC ═══")
artists := GetArtists(users)
admins := GetAdmins(users)
// ── 1. Support tickets ───────────────────────────────────────────────────
p := NewProgress("support_tickets", cfg.SupportTickets)
ticketRows := make([][]interface{}, 0, cfg.SupportTickets)
ticketCategories := []string{"technical", "billing", "general", "feature", "account"}
ticketStatuses := []string{"open", "open", "in_progress", "resolved", "closed"}
ticketSubjects := []string{
"Cannot upload audio file", "Payment not received", "Account access issue",
"Feature request: dark mode", "Playlist sync problem", "Mobile app crash",
"Stream quality issues", "Profile picture upload failed", "How to sell beats?",
"Collaboration feature not working", "Missing analytics data", "Copyright claim dispute",
"Email notifications not arriving", "Two-factor auth setup", "Delete my account",
}
for i := 0; i < cfg.SupportTickets; i++ {
user := users[rng.Intn(len(users))]
subject := pick(ticketSubjects)
ticketRows = append(ticketRows, []interface{}{
newUUID(), user.ID, user.Email,
subject, fmt.Sprintf("Details about: %s. Please help!", subject),
pick(ticketCategories), pick(ticketStatuses),
RandomTimeAfter(user.CreatedAt),
})
}
_, _ = BulkInsert(db, "support_tickets",
"id, user_id, email, subject, message, category, status, created_at",
ticketRows)
p.Update(cfg.SupportTickets)
p.Done()
// ── 2. API keys ──────────────────────────────────────────────────────────
p = NewProgress("api_keys", cfg.APIKeys)
apiRows := make([][]interface{}, 0, cfg.APIKeys)
apiNames := []string{
"Production Bot", "Beat Distributor", "Analytics Dashboard",
"Auto-Upload Script", "Playlist Sync", "Stream Monitor",
}
for i := 0; i < cfg.APIKeys && i < len(artists); i++ {
artist := artists[i%len(artists)]
prefix := fmt.Sprintf("veza_%s", newUUID()[:8])
hashedKey := fmt.Sprintf("$2a$10$%s", newUUID()) // Placeholder hash
name := apiNames[i%len(apiNames)]
scopes := pick([]string{"{read,write,tracks}", "{read,tracks,marketplace}", "{read}", "{read,write}"})
apiRows = append(apiRows, []interface{}{
newUUID(), artist.ID, name, prefix, hashedKey, scopes, time.Now(),
})
}
_, _ = BulkInsert(db, "api_keys",
"id, user_id, name, prefix, hashed_key, scopes, created_at",
apiRows)
p.Update(len(apiRows))
p.Done()
// ── 3. Announcements ─────────────────────────────────────────────────────
p = NewProgress("announcements", cfg.Announcements)
annRows := make([][]interface{}, 0, cfg.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.", "info"},
{"Marketplace Now Open", "Buy and sell beats, samples, and presets directly on the platform.", "feature"},
{"New: Live Streaming", "Stream your sessions live to your followers. Available now for all creators.", "feature"},
{"Scheduled Maintenance", "Brief maintenance window planned for this weekend. Streams may be briefly interrupted.", "warning"},
{"Community Guidelines Updated", "We've updated our community guidelines. Please review them.", "info"},
{"Mobile App Beta", "The mobile app is now in beta. Sign up to be a tester!", "feature"},
{"Holiday Sale", "Special discounts on marketplace products this week.", "info"},
{"New Audio Quality Options", "Hi-Res audio streaming is now available for premium users.", "feature"},
{"Creator Fund Launched", "Earn more from your music with our new creator support fund.", "info"},
{"Platform Update v2.0", "Major platform update with improved UI, faster streaming, and new features.", "feature"},
}
adminID := ""
if len(admins) > 0 {
adminID = admins[0].ID
} else {
adminID = users[0].ID
}
for i := 0; i < cfg.Announcements && i < len(annData); i++ {
a := annData[i]
annRows = append(annRows, []interface{}{
newUUID(), a.title, a.content, a.atype,
true, time.Now(), adminID, DaysAgo(cfg.Announcements - i),
})
}
_, _ = BulkInsert(db, "announcements",
"id, title, content, type, is_active, starts_at, created_by, created_at",
annRows)
p.Update(len(annRows))
p.Done()
// ── 4. Data exports (RGPD) ───────────────────────────────────────────────
p = NewProgress("data_exports", cfg.DataExports)
exportRows := make([][]interface{}, 0, cfg.DataExports)
exportStatuses := []string{"completed", "completed", "pending", "processing"}
for i := 0; i < cfg.DataExports; i++ {
user := users[rng.Intn(len(users))]
status := pick(exportStatuses)
createdAt := RandomTimeAfter(user.CreatedAt)
expiresAt := createdAt.Add(7 * 24 * time.Hour) // 7 day expiry
var completedAt interface{}
var s3Key interface{}
var fileSize interface{}
if status == "completed" {
completedAt = RandomTimeAfter(createdAt)
s3Key = fmt.Sprintf("exports/%s/%s.zip", user.ID, newUUID()[:8])
fs := int64(randInt(1000000, 50000000)) // 1MB - 50MB
fileSize = fs
}
exportRows = append(exportRows, []interface{}{
newUUID(), user.ID, status, s3Key, fileSize,
expiresAt, createdAt, completedAt, nil,
})
}
_, _ = BulkInsert(db, "data_exports",
"id, user_id, status, s3_key, file_size_bytes, expires_at, created_at, completed_at, error_message",
exportRows)
p.Update(cfg.DataExports)
p.Done()
// ── 5. Login history ─────────────────────────────────────────────────────
loginCount := len(users) * 3 // ~3 login entries per user on average
p = NewProgress("login_history", loginCount)
loginRows := make([][]interface{}, 0, loginCount)
for i := 0; i < loginCount; i++ {
user := users[rng.Intn(len(users))]
loginAt := RandomTimeAfter(user.CreatedAt)
loginAt = RealisticHour(loginAt)
success := randChance(95) // 95% success rate
reason := ""
if !success {
reason = pick([]string{"invalid_password", "account_locked", "expired_session"})
}
loginRows = append(loginRows, []interface{}{
newUUID(), user.ID, GenIP(), GenUserAgent(),
success, reason, loginAt,
})
}
_, _ = BulkInsert(db, "login_history",
"id, user_id, ip_address, user_agent, success, reason, created_at",
loginRows)
p.Update(loginCount)
p.Done()
// ── 6. User preferences ──────────────────────────────────────────────────
prefCount := len(users) / 3 // ~33% have explicit preferences
p = NewProgress("user_preferences", prefCount)
prefRows := make([][]interface{}, 0, prefCount)
themes := []string{"light", "dark", "auto"}
langs := []string{"fr", "en", "de", "es"}
contrasts := []string{"normal", "high"}
densities := []string{"comfortable", "compact", "spacious"}
prefSeen := make(map[string]bool)
for i := 0; i < prefCount; i++ {
user := users[rng.Intn(len(users))]
if prefSeen[user.ID] {
continue
}
prefSeen[user.ID] = true
prefRows = append(prefRows, []interface{}{
user.ID, pick(themes), pick(langs), "UTC",
"{}", "{}", `{"quality":"high","autoplay":true}`,
pick(contrasts), pick(densities),
randInt(180, 280), randInt(14, 20),
time.Now(),
})
}
_, _ = BulkInsert(db, "user_preferences",
"user_id, theme, language, timezone, notifications, privacy, audio, contrast, density, accent_hue, font_size, updated_at",
prefRows)
p.Update(len(prefRows))
p.Done()
return nil
}