Spaces:
Sleeping
Sleeping
| import Database from "better-sqlite3"; | |
| import { hashSync } from "bcryptjs"; | |
| import path from "path"; | |
| import fs from "fs"; | |
| const dataDir = path.join(process.cwd(), "data"); | |
| if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir, { recursive: true }); | |
| const dbPath = path.join(dataDir, "crm.db"); | |
| const sqlite = new Database(dbPath); | |
| sqlite.pragma("journal_mode = WAL"); | |
| sqlite.pragma("foreign_keys = ON"); | |
| function seed() { | |
| console.log("Seeding database..."); | |
| sqlite.exec(` | |
| CREATE TABLE IF NOT EXISTS users ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| email TEXT NOT NULL UNIQUE, | |
| name TEXT NOT NULL, | |
| password_hash TEXT NOT NULL, | |
| created_at TEXT NOT NULL | |
| ); | |
| CREATE TABLE IF NOT EXISTS companies ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| name TEXT NOT NULL, | |
| domain TEXT, | |
| phone TEXT, | |
| address TEXT, | |
| notes TEXT, | |
| user_id INTEGER NOT NULL REFERENCES users(id), | |
| created_at TEXT NOT NULL, | |
| updated_at TEXT NOT NULL | |
| ); | |
| CREATE TABLE IF NOT EXISTS contacts ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| first_name TEXT NOT NULL, | |
| last_name TEXT NOT NULL, | |
| email TEXT, | |
| phone TEXT, | |
| job_title TEXT, | |
| company_id INTEGER REFERENCES companies(id), | |
| user_id INTEGER NOT NULL REFERENCES users(id), | |
| created_at TEXT NOT NULL, | |
| updated_at TEXT NOT NULL | |
| ); | |
| CREATE TABLE IF NOT EXISTS pipelines ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| name TEXT NOT NULL, | |
| user_id INTEGER NOT NULL REFERENCES users(id), | |
| created_at TEXT NOT NULL | |
| ); | |
| CREATE TABLE IF NOT EXISTS pipeline_stages ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| name TEXT NOT NULL, | |
| position INTEGER NOT NULL, | |
| probability INTEGER NOT NULL DEFAULT 0, | |
| pipeline_id INTEGER NOT NULL REFERENCES pipelines(id), | |
| created_at TEXT NOT NULL | |
| ); | |
| CREATE TABLE IF NOT EXISTS deals ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| title TEXT NOT NULL, | |
| value REAL NOT NULL DEFAULT 0, | |
| status TEXT NOT NULL DEFAULT 'open', | |
| position INTEGER NOT NULL DEFAULT 0, | |
| expected_close_date TEXT, | |
| stage_id INTEGER NOT NULL REFERENCES pipeline_stages(id), | |
| contact_id INTEGER REFERENCES contacts(id), | |
| company_id INTEGER REFERENCES companies(id), | |
| pipeline_id INTEGER NOT NULL REFERENCES pipelines(id), | |
| user_id INTEGER NOT NULL REFERENCES users(id), | |
| created_at TEXT NOT NULL, | |
| updated_at TEXT NOT NULL | |
| ); | |
| CREATE TABLE IF NOT EXISTS activities ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| type TEXT NOT NULL, | |
| subject TEXT NOT NULL, | |
| description TEXT, | |
| due_date TEXT, | |
| is_done INTEGER NOT NULL DEFAULT 0, | |
| deal_id INTEGER REFERENCES deals(id), | |
| contact_id INTEGER REFERENCES contacts(id), | |
| company_id INTEGER REFERENCES companies(id), | |
| user_id INTEGER NOT NULL REFERENCES users(id), | |
| created_at TEXT NOT NULL, | |
| updated_at TEXT NOT NULL | |
| ); | |
| `); | |
| // Check if already seeded | |
| const existing = sqlite.prepare("SELECT COUNT(*) as cnt FROM users").get() as { cnt: number }; | |
| if (existing.cnt > 0) { | |
| console.log("Database already seeded, skipping."); | |
| return; | |
| } | |
| const now = new Date().toISOString(); | |
| // Seed user | |
| const userResult = sqlite | |
| .prepare("INSERT INTO users (email, name, password_hash, created_at) VALUES (?, ?, ?, ?) RETURNING id") | |
| .get("admin@local.host", "Admin User", hashSync("admin123", 10), now) as { id: number }; | |
| const userId = userResult.id; | |
| // Seed pipeline | |
| const pipResult = sqlite | |
| .prepare("INSERT INTO pipelines (name, user_id, created_at) VALUES (?, ?, ?) RETURNING id") | |
| .get("Sales Pipeline", userId, now) as { id: number }; | |
| const pipelineId = pipResult.id; | |
| // Seed stages | |
| const stageData = [ | |
| { name: "Lead In", position: 0, probability: 10 }, | |
| { name: "Contact Made", position: 1, probability: 25 }, | |
| { name: "Proposal Sent", position: 2, probability: 50 }, | |
| { name: "Negotiation", position: 3, probability: 75 }, | |
| { name: "Won", position: 4, probability: 100 }, | |
| { name: "Lost", position: 5, probability: 0 }, | |
| ]; | |
| const stageInsert = sqlite.prepare( | |
| "INSERT INTO pipeline_stages (name, position, probability, pipeline_id, created_at) VALUES (?, ?, ?, ?, ?) RETURNING id" | |
| ); | |
| const stageIds: number[] = []; | |
| for (const s of stageData) { | |
| const r = stageInsert.get(s.name, s.position, s.probability, pipelineId, now) as { id: number }; | |
| stageIds.push(r.id); | |
| } | |
| // Seed companies | |
| const companyData = [ | |
| { name: "Acme Corp", domain: "acme.com", phone: "+1-555-0100", address: "123 Main St, New York, NY", notes: "Enterprise client" }, | |
| { name: "TechStart Inc", domain: "techstart.io", phone: "+1-555-0200", address: "456 Innovation Dr, San Francisco, CA", notes: "Series B startup" }, | |
| { name: "Global Media", domain: "globalmedia.com", phone: "+1-555-0300", address: "789 Broadway, New York, NY", notes: "Media conglomerate" }, | |
| { name: "DataFlow Systems", domain: "dataflow.dev", phone: "+1-555-0400", address: "321 Tech Park, Austin, TX", notes: "Data analytics company" }, | |
| { name: "GreenEnergy Co", domain: "greenenergy.com", phone: "+1-555-0500", address: "555 Solar Way, Denver, CO", notes: "Renewable energy" }, | |
| { name: "HealthPlus", domain: "healthplus.org", phone: "+1-555-0600", address: "100 Medical Dr, Boston, MA", notes: "Healthcare provider" }, | |
| { name: "FinanceHub", domain: "financehub.com", phone: "+1-555-0700", address: "200 Wall St, New York, NY", notes: "Financial services" }, | |
| { name: "EduLearn", domain: "edulearn.com", phone: "+1-555-0800", address: "300 Campus Rd, Chicago, IL", notes: "EdTech platform" }, | |
| { name: "RetailMax", domain: "retailmax.com", phone: "+1-555-0900", address: "400 Commerce Ave, Seattle, WA", notes: "E-commerce retailer" }, | |
| { name: "BuildRight", domain: "buildright.com", phone: "+1-555-1000", address: "500 Construction Blvd, Phoenix, AZ", notes: "Construction firm" }, | |
| { name: "CloudNine", domain: "cloudnine.io", phone: "+1-555-1100", address: "600 Cloud Ln, Portland, OR", notes: "Cloud infrastructure" }, | |
| { name: "FoodFresh", domain: "foodfresh.com", phone: "+1-555-1200", address: "700 Farm Rd, Sacramento, CA", notes: "Food delivery service" }, | |
| { name: "AutoDrive", domain: "autodrive.com", phone: "+1-555-1300", address: "800 Motor Way, Detroit, MI", notes: "Automotive tech" }, | |
| { name: "SafeGuard", domain: "safeguard.com", phone: "+1-555-1400", address: "900 Security Blvd, Washington, DC", notes: "Cybersecurity firm" }, | |
| { name: "TravelWise", domain: "travelwise.com", phone: "+1-555-1500", address: "150 Journey St, Miami, FL", notes: "Travel booking platform" }, | |
| { name: "SmartHome", domain: "smarthome.com", phone: "+1-555-1600", address: "250 IoT Ave, San Jose, CA", notes: "Smart home devices" }, | |
| { name: "BioGenix", domain: "biogenix.com", phone: "+1-555-1700", address: "350 Bio Ln, San Diego, CA", notes: "Biotech research" }, | |
| { name: "LogiTrack", domain: "logitrack.com", phone: "+1-555-1800", address: "450 Shipping Rd, Memphis, TN", notes: "Logistics & tracking" }, | |
| { name: "MediaBuzz", domain: "mediabuzz.com", phone: "+1-555-1900", address: "550 Content St, Los Angeles, CA", notes: "Digital marketing agency" }, | |
| { name: "LegalEdge", domain: "legaledge.com", phone: "+1-555-2000", address: "650 Court Ave, Philadelphia, PA", notes: "Legal tech platform" }, | |
| ]; | |
| const companyInsert = sqlite.prepare( | |
| "INSERT INTO companies (name, domain, phone, address, notes, user_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING id" | |
| ); | |
| const companyIds: number[] = []; | |
| for (const c of companyData) { | |
| const r = companyInsert.get(c.name, c.domain, c.phone, c.address, c.notes, userId, now, now) as { id: number }; | |
| companyIds.push(r.id); | |
| } | |
| // Seed contacts | |
| const contactData = [ | |
| { firstName: "John", lastName: "Smith", email: "john@acme.com", phone: "+1-555-0101", jobTitle: "CEO", compIdx: 0 }, | |
| { firstName: "Sarah", lastName: "Johnson", email: "sarah@acme.com", phone: "+1-555-0102", jobTitle: "VP Sales", compIdx: 0 }, | |
| { firstName: "Mike", lastName: "Chen", email: "mike@techstart.io", phone: "+1-555-0201", jobTitle: "CTO", compIdx: 1 }, | |
| { firstName: "Emily", lastName: "Davis", email: "emily@techstart.io", phone: "+1-555-0202", jobTitle: "Product Manager", compIdx: 1 }, | |
| { firstName: "David", lastName: "Wilson", email: "david@globalmedia.com", phone: "+1-555-0301", jobTitle: "Head of Marketing", compIdx: 2 }, | |
| { firstName: "Lisa", lastName: "Brown", email: "lisa@dataflow.dev", phone: "+1-555-0401", jobTitle: "Data Scientist", compIdx: 3 }, | |
| { firstName: "James", lastName: "Taylor", email: "james@greenenergy.com", phone: "+1-555-0501", jobTitle: "Operations Director", compIdx: 4 }, | |
| { firstName: "Anna", lastName: "Martinez", email: "anna@healthplus.org", phone: "+1-555-0601", jobTitle: "IT Director", compIdx: 5 }, | |
| { firstName: "Robert", lastName: "Anderson", email: "robert@financehub.com", phone: "+1-555-0701", jobTitle: "CFO", compIdx: 6 }, | |
| { firstName: "Jennifer", lastName: "Thomas", email: "jennifer@edulearn.com", phone: "+1-555-0801", jobTitle: "Head of Partnerships", compIdx: 7 }, | |
| { firstName: "William", lastName: "Jackson", email: "william@retailmax.com", phone: "+1-555-0901", jobTitle: "Procurement Lead", compIdx: 8 }, | |
| { firstName: "Patricia", lastName: "White", email: "patricia@buildright.com", phone: "+1-555-1001", jobTitle: "Project Manager", compIdx: 9 }, | |
| { firstName: "Daniel", lastName: "Harris", email: "daniel@cloudnine.io", phone: "+1-555-1101", jobTitle: "Solutions Architect", compIdx: 10 }, | |
| { firstName: "Karen", lastName: "Clark", email: "karen@foodfresh.com", phone: "+1-555-1201", jobTitle: "Supply Chain Manager", compIdx: 11 }, | |
| { firstName: "Matthew", lastName: "Lewis", email: "matthew@autodrive.com", phone: "+1-555-1301", jobTitle: "Engineering Lead", compIdx: 12 }, | |
| { firstName: "Nancy", lastName: "Robinson", email: "nancy@safeguard.com", phone: "+1-555-1401", jobTitle: "CISO", compIdx: 13 }, | |
| { firstName: "Andrew", lastName: "Walker", email: "andrew@travelwise.com", phone: "+1-555-1501", jobTitle: "Business Development", compIdx: 14 }, | |
| { firstName: "Betty", lastName: "Young", email: "betty@smarthome.com", phone: "+1-555-1601", jobTitle: "Product Lead", compIdx: 15 }, | |
| { firstName: "Christopher", lastName: "King", email: "chris@biogenix.com", phone: "+1-555-1701", jobTitle: "Research Director", compIdx: 16 }, | |
| { firstName: "Susan", lastName: "Wright", email: "susan@logitrack.com", phone: "+1-555-1801", jobTitle: "Operations Manager", compIdx: 17 }, | |
| { firstName: "Mark", lastName: "Hill", email: "mark@mediabuzz.com", phone: "+1-555-1901", jobTitle: "Creative Director", compIdx: 18 }, | |
| { firstName: "Sandra", lastName: "Scott", email: "sandra@legaledge.com", phone: "+1-555-2001", jobTitle: "Managing Partner", compIdx: 19 }, | |
| { firstName: "Kevin", lastName: "Green", email: "kevin@acme.com", phone: "+1-555-0103", jobTitle: "CFO", compIdx: 0 }, | |
| { firstName: "Donna", lastName: "Adams", email: "donna@techstart.io", phone: "+1-555-0203", jobTitle: "Designer", compIdx: 1 }, | |
| { firstName: "Brian", lastName: "Nelson", email: "brian@globalmedia.com", phone: "+1-555-0302", jobTitle: "Editor in Chief", compIdx: 2 }, | |
| { firstName: "Carol", lastName: "Baker", email: "carol@dataflow.dev", phone: "+1-555-0402", jobTitle: "VP Engineering", compIdx: 3 }, | |
| { firstName: "George", lastName: "Gonzalez", email: "george@greenenergy.com", phone: "+1-555-0502", jobTitle: "Sales Director", compIdx: 4 }, | |
| { firstName: "Dorothy", lastName: "Perez", email: "dorothy@healthplus.org", phone: "+1-555-0602", jobTitle: "CEO", compIdx: 5 }, | |
| { firstName: "Timothy", lastName: "Roberts", email: "timothy@financehub.com", phone: "+1-555-0702", jobTitle: "Risk Manager", compIdx: 6 }, | |
| { firstName: "Helen", lastName: "Turner", email: "helen@edulearn.com", phone: "+1-555-0802", jobTitle: "Content Lead", compIdx: 7 }, | |
| { firstName: "Jason", lastName: "Phillips", email: "jason@retailmax.com", phone: "+1-555-0902", jobTitle: "CTO", compIdx: 8 }, | |
| { firstName: "Ruth", lastName: "Campbell", email: "ruth@buildright.com", phone: "+1-555-1002", jobTitle: "CEO", compIdx: 9 }, | |
| { firstName: "Gary", lastName: "Parker", email: "gary@cloudnine.io", phone: "+1-555-1102", jobTitle: "DevOps Lead", compIdx: 10 }, | |
| { firstName: "Sharon", lastName: "Evans", email: "sharon@foodfresh.com", phone: "+1-555-1202", jobTitle: "Marketing Director", compIdx: 11 }, | |
| { firstName: "Ronald", lastName: "Edwards", email: "ronald@autodrive.com", phone: "+1-555-1302", jobTitle: "CEO", compIdx: 12 }, | |
| { firstName: "Laura", lastName: "Collins", email: "laura@safeguard.com", phone: "+1-555-1402", jobTitle: "VP Sales", compIdx: 13 }, | |
| { firstName: "Frank", lastName: "Stewart", email: "frank@travelwise.com", phone: "+1-555-1502", jobTitle: "CTO", compIdx: 14 }, | |
| { firstName: "Virginia", lastName: "Sanchez", email: "virginia@smarthome.com", phone: "+1-555-1602", jobTitle: "CEO", compIdx: 15 }, | |
| { firstName: "Paul", lastName: "Morris", email: "paul@biogenix.com", phone: "+1-555-1702", jobTitle: "VP Sales", compIdx: 16 }, | |
| { firstName: "Deborah", lastName: "Rogers", email: "deborah@logitrack.com", phone: "+1-555-1802", jobTitle: "CEO", compIdx: 17 }, | |
| { firstName: "Stephen", lastName: "Reed", email: "stephen@mediabuzz.com", phone: "+1-555-1902", jobTitle: "Account Manager", compIdx: 18 }, | |
| { firstName: "Margaret", lastName: "Cook", email: "margaret@legaledge.com", phone: "+1-555-2002", jobTitle: "Senior Counsel", compIdx: 19 }, | |
| { firstName: "Raymond", lastName: "Morgan", email: "raymond@acme.com", phone: "+1-555-0104", jobTitle: "Sales Rep", compIdx: 0 }, | |
| { firstName: "Cynthia", lastName: "Bell", email: "cynthia@techstart.io", phone: "+1-555-0204", jobTitle: "Marketing Lead", compIdx: 1 }, | |
| { firstName: "Edward", lastName: "Murphy", email: "edward@globalmedia.com", phone: "+1-555-0303", jobTitle: "Sales Rep", compIdx: 2 }, | |
| { firstName: "Kathleen", lastName: "Bailey", email: "kathleen@dataflow.dev", phone: "+1-555-0403", jobTitle: "Account Executive", compIdx: 3 }, | |
| { firstName: "Dennis", lastName: "Rivera", email: "dennis@greenenergy.com", phone: "+1-555-0503", jobTitle: "Account Manager", compIdx: 4 }, | |
| { firstName: "Angela", lastName: "Cooper", email: "angela@healthplus.org", phone: "+1-555-0603", jobTitle: "Sales Manager", compIdx: 5 }, | |
| { firstName: "Patrick", lastName: "Richardson", email: "patrick@financehub.com", phone: "+1-555-0703", jobTitle: "VP Products", compIdx: 6 }, | |
| { firstName: "Marie", lastName: "Cox", email: "marie@edulearn.com", phone: "+1-555-0803", jobTitle: "CEO", compIdx: 7 }, | |
| ]; | |
| const contactInsert = sqlite.prepare( | |
| "INSERT INTO contacts (first_name, last_name, email, phone, job_title, company_id, user_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id" | |
| ); | |
| const contactIds: number[] = []; | |
| for (const c of contactData) { | |
| const r = contactInsert.get(c.firstName, c.lastName, c.email, c.phone, c.jobTitle, companyIds[c.compIdx], userId, now, now) as { id: number }; | |
| contactIds.push(r.id); | |
| } | |
| // Seed deals | |
| const dealInsert = sqlite.prepare( | |
| "INSERT INTO deals (title, value, status, position, expected_close_date, stage_id, contact_id, company_id, pipeline_id, user_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" | |
| ); | |
| const dealData = [ | |
| { title: "Acme Enterprise License", value: 125000, stIdx: 3, cIdx: 0, coIdx: 0, days: -5 }, | |
| { title: "TechStart Platform Integration", value: 45000, stIdx: 2, cIdx: 2, coIdx: 1, days: 10 }, | |
| { title: "Global Media Ad Campaign", value: 85000, stIdx: 1, cIdx: 4, coIdx: 2, days: 15 }, | |
| { title: "DataFlow Analytics Suite", value: 62000, stIdx: 0, cIdx: 5, coIdx: 3, days: 20 }, | |
| { title: "GreenEnergy Monitoring System", value: 38000, stIdx: 2, cIdx: 6, coIdx: 4, days: 7 }, | |
| { title: "HealthPlus EHR Integration", value: 95000, stIdx: 3, cIdx: 7, coIdx: 5, days: -2 }, | |
| { title: "FinanceHub Trading Platform", value: 200000, stIdx: 1, cIdx: 8, coIdx: 6, days: 30 }, | |
| { title: "EduLearn LMS Upgrade", value: 32000, stIdx: 0, cIdx: 9, coIdx: 7, days: 25 }, | |
| { title: "RetailMax POS System", value: 55000, stIdx: 2, cIdx: 10, coIdx: 8, days: 12 }, | |
| { title: "BuildRight Project Tracker", value: 28000, stIdx: 1, cIdx: 11, coIdx: 9, days: 18 }, | |
| { title: "Acme Support Contract", value: 48000, stIdx: 4, cIdx: 1, coIdx: 0, days: -30 }, | |
| { title: "CloudNine Migration", value: 72000, stIdx: 3, cIdx: 12, coIdx: 10, days: 5 }, | |
| { title: "FoodFresh Route Optimization", value: 41000, stIdx: 0, cIdx: 13, coIdx: 11, days: 22 }, | |
| { title: "AutoDrive Fleet Management", value: 110000, stIdx: 2, cIdx: 14, coIdx: 12, days: 8 }, | |
| { title: "SafeGuard Security Audit", value: 65000, stIdx: 1, cIdx: 15, coIdx: 13, days: 14 }, | |
| { title: "TravelWise Booking Engine", value: 88000, stIdx: 5, cIdx: 16, coIdx: 14, days: -15 }, | |
| { title: "SmartHome API Integration", value: 35000, stIdx: 0, cIdx: 17, coIdx: 15, days: 28 }, | |
| { title: "BioGenix Lab System", value: 150000, stIdx: 3, cIdx: 18, coIdx: 16, days: 3 }, | |
| { title: "LogiTrack Delivery Platform", value: 58000, stIdx: 2, cIdx: 19, coIdx: 17, days: 11 }, | |
| { title: "MediaBuzz Campaign Manager", value: 42000, stIdx: 1, cIdx: 20, coIdx: 18, days: 16 }, | |
| { title: "LegalEdge Document System", value: 75000, stIdx: 0, cIdx: 21, coIdx: 19, days: 24 }, | |
| { title: "TechStart Mobile App", value: 67000, stIdx: 4, cIdx: 3, coIdx: 1, days: -20 }, | |
| { title: "FinanceHub Compliance Tool", value: 130000, stIdx: 2, cIdx: 28, coIdx: 6, days: 9 }, | |
| { title: "GreenEnergy Dashboard", value: 25000, stIdx: 4, cIdx: 26, coIdx: 4, days: -10 }, | |
| { title: "DataFlow ML Pipeline", value: 90000, stIdx: 1, cIdx: 25, coIdx: 3, days: 19 }, | |
| { title: "HealthPlus Telehealth", value: 115000, stIdx: 5, cIdx: 27, coIdx: 5, days: -8 }, | |
| { title: "RetailMax Inventory System", value: 47000, stIdx: 3, cIdx: 30, coIdx: 8, days: 6 }, | |
| { title: "BuildRight Safety App", value: 33000, stIdx: 0, cIdx: 31, coIdx: 9, days: 21 }, | |
| { title: "AutoDrive Diagnostics", value: 78000, stIdx: 4, cIdx: 34, coIdx: 12, days: -25 }, | |
| { title: "SafeGuard Pen Testing", value: 52000, stIdx: 3, cIdx: 35, coIdx: 13, days: 4 }, | |
| ]; | |
| dealData.forEach((d, idx) => { | |
| const closeDate = new Date(); | |
| closeDate.setDate(closeDate.getDate() + d.days); | |
| const status = d.stIdx === 4 ? "won" : d.stIdx === 5 ? "lost" : "open"; | |
| dealInsert.run( | |
| d.title, d.value, status, idx, | |
| closeDate.toISOString().split("T")[0], | |
| stageIds[d.stIdx], contactIds[d.cIdx], companyIds[d.coIdx], | |
| pipelineId, userId, now, now | |
| ); | |
| }); | |
| // Seed activities | |
| const actInsert = sqlite.prepare( | |
| "INSERT INTO activities (type, subject, description, due_date, is_done, deal_id, contact_id, company_id, user_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" | |
| ); | |
| // Get deal IDs | |
| const dealIds = (sqlite.prepare("SELECT id FROM deals ORDER BY id").all() as { id: number }[]).map(r => r.id); | |
| const activityData = [ | |
| { type: "call", subject: "Discovery call with John Smith", cIdx: 0, coIdx: 0, dIdx: 0, days: -3, done: 1 }, | |
| { type: "email", subject: "Sent proposal to TechStart", cIdx: 2, coIdx: 1, dIdx: 1, days: -2, done: 1 }, | |
| { type: "meeting", subject: "Demo with Global Media team", cIdx: 4, coIdx: 2, dIdx: 2, days: -1, done: 1 }, | |
| { type: "task", subject: "Prepare pricing sheet for DataFlow", cIdx: 5, coIdx: 3, dIdx: 3, days: 0, done: 0 }, | |
| { type: "note", subject: "GreenEnergy budget approved for Q2", cIdx: 6, coIdx: 4, dIdx: 4, days: -4, done: 1 }, | |
| { type: "call", subject: "Follow-up with HealthPlus IT team", cIdx: 7, coIdx: 5, dIdx: 5, days: 1, done: 0 }, | |
| { type: "email", subject: "Contract draft to FinanceHub", cIdx: 8, coIdx: 6, dIdx: 6, days: -1, done: 1 }, | |
| { type: "meeting", subject: "Quarterly review with EduLearn", cIdx: 9, coIdx: 7, dIdx: 7, days: 2, done: 0 }, | |
| { type: "task", subject: "Create RetailMax demo environment", cIdx: 10, coIdx: 8, dIdx: 8, days: 1, done: 0 }, | |
| { type: "call", subject: "Intro call with BuildRight PM", cIdx: 11, coIdx: 9, dIdx: 9, days: -5, done: 1 }, | |
| { type: "note", subject: "Acme contract signed - won!", cIdx: 1, coIdx: 0, dIdx: 10, days: -30, done: 1 }, | |
| { type: "email", subject: "CloudNine migration timeline", cIdx: 12, coIdx: 10, dIdx: 11, days: 0, done: 0 }, | |
| { type: "meeting", subject: "FoodFresh logistics walkthrough", cIdx: 13, coIdx: 11, dIdx: 12, days: 3, done: 0 }, | |
| { type: "call", subject: "AutoDrive fleet requirements", cIdx: 14, coIdx: 12, dIdx: 13, days: -2, done: 1 }, | |
| { type: "task", subject: "Prepare SafeGuard audit scope", cIdx: 15, coIdx: 13, dIdx: 14, days: 2, done: 0 }, | |
| { type: "note", subject: "TravelWise deal lost - budget cut", cIdx: 16, coIdx: 14, dIdx: 15, days: -15, done: 1 }, | |
| { type: "email", subject: "SmartHome API documentation", cIdx: 17, coIdx: 15, dIdx: 16, days: 1, done: 0 }, | |
| { type: "meeting", subject: "BioGenix lab requirements workshop", cIdx: 18, coIdx: 16, dIdx: 17, days: 4, done: 0 }, | |
| { type: "call", subject: "LogiTrack platform demo", cIdx: 19, coIdx: 17, dIdx: 18, days: -1, done: 1 }, | |
| { type: "email", subject: "MediaBuzz campaign specs", cIdx: 20, coIdx: 18, dIdx: 19, days: 0, done: 0 }, | |
| { type: "task", subject: "Draft LegalEdge proposal", cIdx: 21, coIdx: 19, dIdx: 20, days: 3, done: 0 }, | |
| { type: "call", subject: "TechStart renewal discussion", cIdx: 3, coIdx: 1, dIdx: 21, days: -20, done: 1 }, | |
| { type: "meeting", subject: "FinanceHub compliance review", cIdx: 28, coIdx: 6, dIdx: 22, days: 5, done: 0 }, | |
| { type: "note", subject: "GreenEnergy dashboard delivered", cIdx: 26, coIdx: 4, dIdx: 23, days: -10, done: 1 }, | |
| { type: "email", subject: "DataFlow ML requirements doc", cIdx: 25, coIdx: 3, dIdx: 24, days: -1, done: 1 }, | |
| { type: "call", subject: "HealthPlus telehealth post-mortem", cIdx: 27, coIdx: 5, dIdx: 25, days: -7, done: 1 }, | |
| { type: "task", subject: "Setup RetailMax test environment", cIdx: 30, coIdx: 8, dIdx: 26, days: 2, done: 0 }, | |
| { type: "meeting", subject: "BuildRight safety demo", cIdx: 31, coIdx: 9, dIdx: 27, days: 6, done: 0 }, | |
| { type: "note", subject: "AutoDrive diagnostics launched", cIdx: 34, coIdx: 12, dIdx: 28, days: -25, done: 1 }, | |
| { type: "call", subject: "SafeGuard pen test scheduling", cIdx: 35, coIdx: 13, dIdx: 29, days: 1, done: 0 }, | |
| { type: "email", subject: "Weekly pipeline update to team", cIdx: -1, coIdx: -1, dIdx: -1, days: -1, done: 1 }, | |
| { type: "task", subject: "Update CRM contact records", cIdx: -1, coIdx: -1, dIdx: -1, days: 0, done: 0 }, | |
| { type: "meeting", subject: "Sales team standup", cIdx: -1, coIdx: -1, dIdx: -1, days: 1, done: 0 }, | |
| { type: "call", subject: "Follow up with Acme on expansion", cIdx: 0, coIdx: 0, dIdx: -1, days: 3, done: 0 }, | |
| { type: "email", subject: "Send case study to TechStart", cIdx: 2, coIdx: 1, dIdx: -1, days: 2, done: 0 }, | |
| { type: "task", subject: "Research competitor pricing", cIdx: -1, coIdx: -1, dIdx: -1, days: 4, done: 0 }, | |
| { type: "meeting", subject: "Product roadmap review", cIdx: -1, coIdx: -1, dIdx: -1, days: 5, done: 0 }, | |
| { type: "note", subject: "Q1 target reached - 85% of quota", cIdx: -1, coIdx: -1, dIdx: -1, days: -7, done: 1 }, | |
| { type: "call", subject: "Cold call campaign - batch 12", cIdx: -1, coIdx: -1, dIdx: -1, days: 0, done: 0 }, | |
| { type: "email", subject: "Newsletter to prospects", cIdx: -1, coIdx: -1, dIdx: -1, days: -2, done: 1 }, | |
| ]; | |
| for (const a of activityData) { | |
| const dueDate = new Date(); | |
| dueDate.setDate(dueDate.getDate() + a.days); | |
| actInsert.run( | |
| a.type, a.subject, null, | |
| dueDate.toISOString().split("T")[0], | |
| a.done, | |
| a.dIdx >= 0 ? dealIds[a.dIdx] : null, | |
| a.cIdx >= 0 ? contactIds[a.cIdx] : null, | |
| a.coIdx >= 0 ? companyIds[a.coIdx] : null, | |
| userId, now, now | |
| ); | |
| } | |
| console.log("Seeded: 1 user, 1 pipeline, 6 stages, 20 companies, 50 contacts, 30 deals, 40 activities"); | |
| } | |
| seed(); | |
| sqlite.close(); | |