import { PrismaClient } from "@prisma/client"; import fs from "node:fs"; import path from "node:path"; function loadEnvFromDotEnv() { const p = path.resolve(process.cwd(), ".env"); if (!fs.existsSync(p)) return; const raw = fs.readFileSync(p, "utf8"); for (const line of raw.split("\n")) { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith("#")) continue; const idx = trimmed.indexOf("="); if (idx === -1) continue; const key = trimmed.slice(0, idx).trim(); let val = trimmed.slice(idx + 1).trim(); if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) { val = val.slice(1, -1); } if (!key) continue; // Force DATABASE_URL from local .env for scripts, to avoid inheriting a stale shell env. if (key === "DATABASE_URL") { process.env[key] = val; continue; } if (!process.env[key]) process.env[key] = val; } } loadEnvFromDotEnv(); const prisma = new PrismaClient(); function atOffset(days, hour, minute) { const d = new Date(); d.setDate(d.getDate() + days); d.setHours(hour, minute, 0, 0); return d; } async function main() { // Create default team/user for dev. const user = await prisma.user.upsert({ where: { id: "demo-user" }, update: { email: "demo@clientsflow.local", name: "Demo User" }, create: { id: "demo-user", email: "demo@clientsflow.local", name: "Demo User" }, }); const team = await prisma.team.upsert({ where: { id: "demo-team" }, update: { name: "Demo Team" }, create: { id: "demo-team", name: "Demo Team" }, }); await prisma.teamMember.upsert({ where: { teamId_userId: { teamId: team.id, userId: user.id } }, update: {}, create: { teamId: team.id, userId: user.id, role: "OWNER" }, }); // Idempotent-ish seed per team: if we already have contacts in this team, do nothing. const existing = await prisma.contact.count({ where: { teamId: team.id } }); if (existing > 0) return; const contacts = await prisma.contact.createManyAndReturn({ data: [ { teamId: team.id, name: "Anna Meyer", company: "Nordline GmbH", email: "anna@nordline.example", phone: "+49 30 123 45 67", }, { teamId: team.id, name: "Murat Ali", company: "Connect FZCO", email: "murat@connect.example", phone: "+971 50 123 4567", }, { teamId: team.id, name: "Ilya Petroff", company: "Volta Tech", email: "ilya@volta.example", phone: "+374 10 123 456", }, { teamId: team.id, name: "Carlos Rivera", company: "BluePort", email: "carlos@blueport.example", phone: "+34 600 123 456", }, { teamId: team.id, name: "Daria Ivanova", company: "Skyline Trade", email: "daria@skyline.example", phone: "+7 777 123 45 67", }, ], }); const byName = Object.fromEntries(contacts.map((c) => [c.name, c])); await prisma.contactNote.createMany({ data: [ { contactId: byName["Anna Meyer"].id, content: "Decision owner. Prefers short, concrete updates with a clear next step.\nRisk: decision date slips if we don't lock timeline.", }, { contactId: byName["Murat Ali"].id, content: "High activity. Needs legal path clarity and an explicit owner on their side.\nBest move: lock legal owner + target signature date.", }, { contactId: byName["Ilya Petroff"].id, content: "Early-stage. Wants structured onboarding before commercial details.\nBest move: onboarding plan + 2 time slots.", }, ], }); await prisma.contactMessage.createMany({ data: [ { contactId: byName["Anna Meyer"].id, direction: "IN", channel: "TELEGRAM", content: "Thanks for the demo. Can you send 2 pricing options?", occurredAt: atOffset(0, 10, 20), }, { contactId: byName["Anna Meyer"].id, direction: "OUT", channel: "EMAIL", content: "Sure. Option A/B attached. Can you confirm decision date for this cycle?", occurredAt: atOffset(0, 10, 35), }, { contactId: byName["Murat Ali"].id, direction: "IN", channel: "WHATSAPP", content: "Let's do a quick call. Need to clarify legal owner.", occurredAt: atOffset(-1, 18, 10), }, { contactId: byName["Ilya Petroff"].id, direction: "OUT", channel: "EMAIL", content: "Draft: onboarding plan + two slots for tomorrow.", occurredAt: atOffset(-1, 11, 12), }, ], }); await prisma.calendarEvent.createMany({ data: [ { teamId: team.id, contactId: byName["Anna Meyer"].id, title: "Follow-up: Anna", startsAt: atOffset(0, 12, 30), endsAt: atOffset(0, 13, 0), note: "Lock decision date + confirm option A/B.", status: "planned", }, { teamId: team.id, contactId: byName["Murat Ali"].id, title: "Call: Murat (legal owner)", startsAt: atOffset(0, 15, 0), endsAt: atOffset(0, 15, 20), note: "Confirm legal owner + target signature date.", status: "planned", }, ], }); await prisma.chatConversation.upsert({ where: { id: `pilot-${team.id}` }, update: {}, create: { id: `pilot-${team.id}`, teamId: team.id, createdByUserId: user.id, title: "Pilot", }, }); await prisma.chatMessage.createMany({ data: [ { teamId: team.id, conversationId: `pilot-${team.id}`, authorUserId: null, role: "ASSISTANT", text: "Я смотрю календарь, контакты и переписки как один поток. Спроси: \"чем заняться сегодня\" или \"покажи 10 лучших клиентов\".", planJson: { steps: ["Скажи задачу", "Я соберу срез данных", "Предложу план и действия"], tools: ["read index/contacts.json"] }, }, ], }); } main() .catch((e) => { console.error(e); process.exitCode = 1; }) .finally(async () => { await prisma.$disconnect(); });