import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); // ── Marketplace catalogue (faithful to the shop mockups) ──────────────────── // Prices are centi-credits (mockup € → credits): 9.99 → 999. const PRODUCTS = [ { id: "cadre-pub", category: "publicite", name: "Cadre de Pub", subtitle: "1 000 impressions garanties · 130×180 px · lien cliquable", kind: "ad-frame", basePrice: 1500, promoPrice: 999, badge: "-33% FLASH PROMO", sortOrder: 10, metaJson: JSON.stringify({ durations: [ { days: 7, extra: 0 }, { days: 14, extra: 800 }, { days: 30, extra: 2000 }, ], formats: [ { id: "static", label: "Image statique", extra: 0 }, { id: "gif", label: "GIF animé", extra: 300 }, ], }), }, { id: "noads", category: "abonnements", name: "Abonnement NoAds", subtitle: "Supprime toutes les pubs du chat", kind: "subscription", basePrice: 499, badge: "POPULAIRE", sortOrder: 20, metaJson: JSON.stringify({ plans: [ { id: "monthly", label: "Mensuel", price: 499 }, { id: "annual", label: "Annuel", price: 3999 }, ], }), }, { id: "style-dore", category: "cosmetiques", name: "Style Doré", subtitle: "Ton IP en or brillant, visible de tous", kind: "ip-skin", basePrice: 999, badge: "LIMITÉ 50 ex.", stockLimit: 50, sortOrder: 30, metaJson: JSON.stringify({ variant: "gold" }), }, { id: "pet", category: "cosmetiques", name: "Pet de Nom", subtitle: "Un petit élément décoratif autour de ton IP", kind: "pet", basePrice: 799, badge: "NOUVEAU", sortOrder: 40, metaJson: JSON.stringify({ designs: [ { id: "coeur", char: "♥" }, { id: "etoile", char: "★" }, { id: "diamant", char: "♦" }, { id: "trefle", char: "♣" }, { id: "couronne", char: "♚" }, { id: "crane", char: "☠" }, { id: "eclair", char: "⚡" }, { id: "fleur", char: "✿" }, { id: "note", char: "♫" }, { id: "feu", char: "🔥" }, ], positions: ["left", "right", "both"], }), }, { id: "bundle-cosmetic", category: "promotions", name: "Pack Cosmétique", subtitle: "Style Doré + 1 Pet au choix", kind: "bundle", basePrice: 1798, promoPrice: 1499, badge: "-3 CR", sortOrder: 50, metaJson: JSON.stringify({ includes: ["style-dore", "pet"] }), }, { // id == entitlement kind, so the "unlock" branch grants "element-skin". id: "element-skin", category: "cosmetiques", name: "Skin d'éléments", subtitle: "Relooke ta barre de saisie et ton bouton d'envoi", kind: "unlock", basePrice: 599, sortOrder: 45, metaJson: JSON.stringify({}), }, { id: "rich-htmlcss", category: "premium", name: "Messages HTML / CSS", subtitle: "Mets en forme tes messages (sans script)", kind: "rich", basePrice: 2999, sortOrder: 60, metaJson: JSON.stringify({}), }, { id: "rich-js", category: "premium", name: "Messages JavaScript", subtitle: "Scripts interactifs (isolés). TRÈS cher.", kind: "rich", basePrice: 19999, badge: "TRÈS TRÈS CHER", sortOrder: 70, metaJson: JSON.stringify({}), }, { id: "no-file-limit", category: "premium", name: "Fichiers illimités", subtitle: "Plus de limite de 1 Mo sur tes pièces jointes", kind: "unlock", basePrice: 1499, sortOrder: 80, metaJson: JSON.stringify({}), }, { id: "audio-alert", category: "premium", name: "Alerte audio générale", subtitle: "Fais hurler un son chez tout le monde (cooldown)", kind: "consumable", basePrice: 999, badge: "CONSOMMABLE", sortOrder: 90, metaJson: JSON.stringify({ cooldownMs: 60000, maxDurationMs: 5000 }), }, // ── Cosmetics: IP color + send button skins ────────────────────────────── { id: "ip-colors", category: "cosmetiques", name: "Palette IP", subtitle: "Personnalise la couleur de ton adresse IP dans le chat", kind: "unlock", basePrice: 299, sortOrder: 46, metaJson: JSON.stringify({}), }, { id: "send-skin-honker", category: "cosmetiques", name: "Doigt d'honneur", subtitle: "Bouton d'envoi qui exprime tout", kind: "send-skin", basePrice: 149, sortOrder: 47, metaJson: JSON.stringify({ char: "🖕", label: "Doigt d'honneur" }), }, { id: "send-skin-skull", category: "cosmetiques", name: "Crâne", subtitle: "Envoyer avec style... macabre", kind: "send-skin", basePrice: 149, sortOrder: 48, metaJson: JSON.stringify({ char: "💀", label: "Crâne" }), }, { id: "send-skin-rocket", category: "cosmetiques", name: "Fusée", subtitle: "Tes messages décollent", kind: "send-skin", basePrice: 149, sortOrder: 49, metaJson: JSON.stringify({ char: "🚀", label: "Fusée" }), }, { id: "send-skin-ghost", category: "cosmetiques", name: "Fantôme", subtitle: "Boo !", kind: "send-skin", basePrice: 149, sortOrder: 50, metaJson: JSON.stringify({ char: "👻", label: "Fantôme" }), }, { id: "send-skin-bomb", category: "cosmetiques", name: "Bombe", subtitle: "Message explosif", kind: "send-skin", basePrice: 149, sortOrder: 51, metaJson: JSON.stringify({ char: "💣", label: "Bombe" }), }, { id: "send-skin-sword", category: "cosmetiques", name: "Épée", subtitle: "Tranche le silence", kind: "send-skin", basePrice: 149, sortOrder: 52, metaJson: JSON.stringify({ char: "⚔️", label: "Épée" }), }, ] as const; // ── Ad inventory (the 4 hardcoded joke ads, now real data) ────────────────── const ADS = [ { brand: "NOVA", subtitle: "STORE 2026", url: "https://nova-store.io", cta: "DÉCOUVRIR", icon: "🛒", tone: "blue", kind: "band", weight: 1 }, { brand: "APEX GEAR", subtitle: "Gaming Setup", url: "https://apex-gear.com", cta: "ACHETER", icon: "🎮", tone: "green", kind: "band", weight: 1 }, { brand: "SHIELDVPN", subtitle: "Sécurité totale", url: "https://shieldvpn.net", cta: "ESSAI GRATUIT", icon: "🔒", tone: "purple", kind: "band", weight: 1 }, { brand: "CASINO LUCKY", subtitle: "OFFRE EXCLUSIVE · +200% · 500€ max", url: "https://casino-lucky.bet", cta: "JOUER MAINTENANT", icon: "♠", tone: "casino", kind: "casino", weight: 1 }, ] as const; async function seedProducts() { for (const p of PRODUCTS) { await prisma.product.upsert({ where: { id: p.id }, create: p as any, update: p as any, }); } console.log(`✅ ${PRODUCTS.length} produits upsertés.`); } async function seedAds() { for (const a of ADS) { // Idempotent on brand: only seed the canonical (non-user) ads once. const existing = await prisma.ad.findFirst({ where: { brand: a.brand, ownerIp: null } }); if (existing) { await prisma.ad.update({ where: { id: existing.id }, data: a as any }); } else { await prisma.ad.create({ data: a as any }); } } console.log(`✅ ${ADS.length} pubs upsertées.`); } async function seedMessages() { const count = await prisma.message.count(); if (count > 0) { console.log("⏭️ Messages déjà présents, seed messages ignoré."); return; } const root1 = await prisma.message.create({ data: { content: "Bienvenue sur XIP — le réseau social sans filtre ni compte.", authorIp: "1.2.3.4", }, }); await prisma.message.create({ data: { content: "Pas de compte, ton IP c'est toi.", authorIp: "5.6.7.8" }, }); await prisma.message.create({ data: { content: "Réponse au premier message !", authorIp: "9.10.11.12", parentId: root1.id }, }); console.log("✅ 3 messages de démo créés."); } async function main() { await seedProducts(); await seedAds(); await seedMessages(); } main() .catch(console.error) .finally(() => prisma.$disconnect());