const { PrismaClient, RoleCode, TenantStatus, UserStatus, ChannelStatus, ConversationStatus, ConversationPriority, MessageDirection, MessageType, DeliveryStatus, OptInStatus, TemplateApprovalStatus, CampaignStatus, CampaignAudienceType, CampaignType, PaymentStatus } = require("@prisma/client"); const { pbkdf2Sync, randomBytes } = require("crypto"); const prisma = new PrismaClient(); function hashPassword(password) { const iterations = 120000; const salt = randomBytes(16); const digest = pbkdf2Sync(password, salt, iterations, 32, "sha256"); return `pbkdf2$${iterations}$${salt.toString("base64url")}$${digest.toString("base64url")}`; } async function main() { await prisma.campaignRecipient.deleteMany(); await prisma.broadcastCampaign.deleteMany(); await prisma.messageTemplate.deleteMany(); await prisma.segmentMember.deleteMany(); await prisma.contactSegment.deleteMany(); await prisma.conversationActivity.deleteMany(); await prisma.conversationTag.deleteMany(); await prisma.conversationNote.deleteMany(); await prisma.message.deleteMany(); await prisma.conversation.deleteMany(); await prisma.contactTag.deleteMany(); await prisma.tag.deleteMany(); await prisma.contact.deleteMany(); await prisma.webhookEvent.deleteMany(); await prisma.auditLog.deleteMany(); await prisma.usageMetric.deleteMany(); await prisma.billingInvoice.deleteMany(); await prisma.authToken.deleteMany(); await prisma.channel.deleteMany(); await prisma.user.deleteMany(); await prisma.role.deleteMany(); await prisma.tenant.deleteMany(); await prisma.subscriptionPlan.deleteMany(); await prisma.subscriptionPlan.createMany({ data: [ { id: "plan-basic", name: "Basic", code: "basic", priceMonthly: 1500000, messageQuota: 10000, seatQuota: 5, broadcastQuota: 2000, featuresJson: JSON.stringify({ inbox: true, contacts: true, analytics: "basic" }) }, { id: "plan-pro", name: "Pro", code: "pro", priceMonthly: 2500000, messageQuota: 50000, seatQuota: 15, broadcastQuota: 10000, featuresJson: JSON.stringify({ inbox: true, contacts: true, analytics: "extended", broadcast: true }) } ] }); await prisma.tenant.createMany({ data: [ { id: "tenant-acme", name: "Acme Co", slug: "acme-co", companyName: "Acme Co", timezone: "Asia/Jakarta", status: TenantStatus.ACTIVE, planId: "plan-pro" }, { id: "tenant-sinar", name: "Sinar Abadi", slug: "sinar-abadi", companyName: "PT Sinar Abadi", timezone: "Asia/Jakarta", status: TenantStatus.TRIAL, planId: "plan-basic" } ] }); await prisma.role.createMany({ data: [ { id: "role-super-admin", name: "Super Admin", code: RoleCode.SUPER_ADMIN, permissionsJson: JSON.stringify({ global: true }) }, { id: "role-admin-acme", tenantId: "tenant-acme", name: "Admin Client", code: RoleCode.ADMIN_CLIENT, permissionsJson: JSON.stringify({ tenant: true }) }, { id: "role-agent-acme", tenantId: "tenant-acme", name: "Agent", code: RoleCode.AGENT, permissionsJson: JSON.stringify({ inbox: true }) }, { id: "role-admin-sinar", tenantId: "tenant-sinar", name: "Admin Client", code: RoleCode.ADMIN_CLIENT, permissionsJson: JSON.stringify({ tenant: true }) } ] }); await prisma.user.createMany({ data: [ { id: "user-super-admin", tenantId: "tenant-acme", fullName: "Platform Owner", email: "owner@inboxsuite.test", passwordHash: hashPassword("demo123"), roleId: "role-super-admin", status: UserStatus.ACTIVE, lastLoginAt: new Date("2026-04-20T08:00:00Z") }, { id: "user-admin-001", tenantId: "tenant-acme", fullName: "Admin Operations", email: "admin@acme.test", passwordHash: hashPassword("admin123"), roleId: "role-admin-acme", status: UserStatus.ACTIVE, lastLoginAt: new Date("2026-04-20T09:00:00Z") }, { id: "user-agent-001", tenantId: "tenant-acme", fullName: "Farhan", email: "farhan@acme.test", passwordHash: hashPassword("agent123"), roleId: "role-agent-acme", status: UserStatus.ACTIVE, lastLoginAt: new Date("2026-04-20T09:12:00Z") }, { id: "user-agent-002", tenantId: "tenant-acme", fullName: "Tiara", email: "tiara@acme.test", passwordHash: hashPassword("agent123"), roleId: "role-agent-acme", status: UserStatus.ACTIVE, lastLoginAt: new Date("2026-04-20T08:54:00Z") }, { id: "user-admin-sinar", tenantId: "tenant-sinar", fullName: "Sinar Admin", email: "admin@sinar.test", passwordHash: hashPassword("sinar123"), roleId: "role-admin-sinar", status: UserStatus.INVITED } ] }); await prisma.channel.createMany({ data: [ { id: "channel-main-acme", tenantId: "tenant-acme", channelName: "Main WA", provider: "Meta BSP", wabaId: "waba-acme-main", phoneNumberId: "phone-acme-main", displayPhoneNumber: "+628111111111", status: ChannelStatus.CONNECTED, webhookStatus: "healthy", lastSyncAt: new Date("2026-04-20T09:10:00Z") }, { id: "channel-ops-acme", tenantId: "tenant-acme", channelName: "Ops WA", provider: "Meta BSP", wabaId: "waba-acme-ops", phoneNumberId: "phone-acme-ops", displayPhoneNumber: "+628222222222", status: ChannelStatus.CONNECTED, webhookStatus: "healthy", lastSyncAt: new Date("2026-04-20T08:45:00Z") }, { id: "channel-sinar", tenantId: "tenant-sinar", channelName: "Sales WA", provider: "Meta BSP", wabaId: "waba-sinar-main", phoneNumberId: "phone-sinar-main", displayPhoneNumber: "+628333333333", status: ChannelStatus.PENDING, webhookStatus: "pending" } ] }); await prisma.tag.createMany({ data: [ { id: "tag-enterprise", tenantId: "tenant-acme", name: "Enterprise", color: "#155eef" }, { id: "tag-hot-lead", tenantId: "tenant-acme", name: "Hot Lead", color: "#ff7a00" }, { id: "tag-payment", tenantId: "tenant-acme", name: "Payment Follow-up", color: "#b54708" }, { id: "tag-b2b", tenantId: "tenant-acme", name: "B2B", color: "#067647" } ] }); await prisma.contact.createMany({ data: [ { id: "contact-001", tenantId: "tenant-acme", channelId: "channel-main-acme", fullName: "Nadia Pratama", phoneNumber: "+628123456789", email: "nadia@example.com", countryCode: "ID", optInStatus: OptInStatus.OPTED_IN, lastInteractionAt: new Date("2026-04-20T09:12:00Z") }, { id: "contact-002", tenantId: "tenant-acme", channelId: "channel-ops-acme", fullName: "PT Sinar Abadi", phoneNumber: "+62219876543", email: "ops@sinarabadi.co.id", countryCode: "ID", optInStatus: OptInStatus.UNKNOWN, lastInteractionAt: new Date("2026-04-19T11:00:00Z") }, { id: "contact-003", tenantId: "tenant-acme", channelId: "channel-main-acme", fullName: "Rizky Saputra", phoneNumber: "+628777777777", email: "rizky@example.com", countryCode: "ID", optInStatus: OptInStatus.OPTED_IN, lastInteractionAt: new Date("2026-04-18T12:00:00Z") } ] }); await prisma.contactTag.createMany({ data: [ { id: "ct-001", tenantId: "tenant-acme", contactId: "contact-001", tagId: "tag-enterprise" }, { id: "ct-002", tenantId: "tenant-acme", contactId: "contact-001", tagId: "tag-hot-lead" }, { id: "ct-003", tenantId: "tenant-acme", contactId: "contact-002", tagId: "tag-b2b" }, { id: "ct-004", tenantId: "tenant-acme", contactId: "contact-003", tagId: "tag-payment" } ] }); await prisma.contactSegment.create({ data: { id: "segment-hot-leads", tenantId: "tenant-acme", name: "Hot Leads", description: "Enterprise prospects", rulesJson: JSON.stringify({ tags: ["Enterprise", "Hot Lead"] }) } }); await prisma.segmentMember.create({ data: { id: "segment-member-001", tenantId: "tenant-acme", segmentId: "segment-hot-leads", contactId: "contact-001" } }); await prisma.conversation.createMany({ data: [ { id: "conv-001", tenantId: "tenant-acme", channelId: "channel-main-acme", contactId: "contact-001", subject: "Enterprise pricing", status: ConversationStatus.OPEN, priority: ConversationPriority.HIGH, assignedUserId: "user-agent-001", firstMessageAt: new Date("2026-04-20T09:00:00Z"), lastMessageAt: new Date("2026-04-20T09:12:00Z"), lastInboundAt: new Date("2026-04-20T09:12:00Z") }, { id: "conv-002", tenantId: "tenant-acme", channelId: "channel-main-acme", contactId: "contact-003", subject: "Payment follow-up", status: ConversationStatus.PENDING, priority: ConversationPriority.NORMAL, firstMessageAt: new Date("2026-04-20T08:30:00Z"), lastMessageAt: new Date("2026-04-20T08:47:00Z"), lastInboundAt: new Date("2026-04-20T08:47:00Z") }, { id: "conv-003", tenantId: "tenant-acme", channelId: "channel-ops-acme", contactId: "contact-002", subject: "Template request", status: ConversationStatus.RESOLVED, priority: ConversationPriority.NORMAL, assignedUserId: "user-agent-002", firstMessageAt: new Date("2026-04-19T09:00:00Z"), lastMessageAt: new Date("2026-04-19T11:00:00Z"), lastInboundAt: new Date("2026-04-19T10:20:00Z"), lastOutboundAt: new Date("2026-04-19T11:00:00Z"), resolvedAt: new Date("2026-04-19T11:10:00Z") } ] }); await prisma.conversationTag.createMany({ data: [ { id: "cvt-001", tenantId: "tenant-acme", conversationId: "conv-001", tagId: "tag-enterprise" }, { id: "cvt-002", tenantId: "tenant-acme", conversationId: "conv-001", tagId: "tag-hot-lead" }, { id: "cvt-003", tenantId: "tenant-acme", conversationId: "conv-002", tagId: "tag-payment" }, { id: "cvt-004", tenantId: "tenant-acme", conversationId: "conv-003", tagId: "tag-b2b" } ] }); await prisma.message.createMany({ data: [ { id: "msg-001", tenantId: "tenant-acme", conversationId: "conv-001", channelId: "channel-main-acme", contactId: "contact-001", direction: MessageDirection.INBOUND, type: MessageType.TEXT, contentText: "Halo, saya mau tanya soal paket enterprise untuk tim saya.", deliveryStatus: DeliveryStatus.READ, createdAt: new Date("2026-04-20T09:00:00Z"), readAt: new Date("2026-04-20T09:00:00Z") }, { id: "msg-002", tenantId: "tenant-acme", conversationId: "conv-001", channelId: "channel-main-acme", direction: MessageDirection.OUTBOUND, type: MessageType.TEXT, contentText: "Tentu. Boleh saya tahu estimasi jumlah agent yang akan memakai sistem?", deliveryStatus: DeliveryStatus.DELIVERED, sentByUserId: "user-agent-001", createdAt: new Date("2026-04-20T09:05:00Z"), sentAt: new Date("2026-04-20T09:05:00Z"), deliveredAt: new Date("2026-04-20T09:05:05Z") }, { id: "msg-003", tenantId: "tenant-acme", conversationId: "conv-002", channelId: "channel-main-acme", contactId: "contact-003", direction: MessageDirection.INBOUND, type: MessageType.TEXT, contentText: "Sudah saya transfer, mohon dicek ya.", deliveryStatus: DeliveryStatus.READ, createdAt: new Date("2026-04-20T08:47:00Z"), readAt: new Date("2026-04-20T08:47:00Z") } ] }); await prisma.conversationNote.create({ data: { id: "note-001", tenantId: "tenant-acme", conversationId: "conv-001", userId: "user-agent-001", content: "Prospek enterprise, follow-up sore ini." } }); await prisma.conversationActivity.createMany({ data: [ { id: "act-001", tenantId: "tenant-acme", conversationId: "conv-001", actorUserId: "user-agent-001", activityType: "assigned", metadataJson: JSON.stringify({ assignee: "Farhan" }) }, { id: "act-002", tenantId: "tenant-acme", conversationId: "conv-001", actorUserId: "user-agent-001", activityType: "message_sent", metadataJson: JSON.stringify({ messageId: "msg-002" }) } ] }); await prisma.messageTemplate.createMany({ data: [ { id: "tpl-001", tenantId: "tenant-acme", channelId: "channel-main-acme", name: "promo_april_2026", category: "Marketing", languageCode: "id", templateType: "text", bodyText: "Halo {{1}}, ada promo spesial untuk bisnis Anda minggu ini.", approvalStatus: TemplateApprovalStatus.APPROVED }, { id: "tpl-002", tenantId: "tenant-acme", channelId: "channel-ops-acme", name: "billing_reminder", category: "Utility", languageCode: "id", templateType: "text", bodyText: "Halo {{1}}, berikut pengingat pembayaran Anda.", approvalStatus: TemplateApprovalStatus.PENDING } ] }); await prisma.broadcastCampaign.createMany({ data: [ { id: "campaign-001", tenantId: "tenant-acme", channelId: "channel-main-acme", templateId: "tpl-001", createdByUserId: "user-admin-001", name: "Promo April", campaignType: CampaignType.BROADCAST, audienceType: CampaignAudienceType.SEGMENT, segmentId: "segment-hot-leads", scheduledAt: new Date("2026-04-20T10:00:00Z"), startedAt: new Date("2026-04-20T10:00:00Z"), finishedAt: new Date("2026-04-20T10:30:00Z"), status: CampaignStatus.COMPLETED, totalRecipients: 1203, totalSent: 1203, totalDelivered: 1180, totalRead: 873, totalFailed: 23 }, { id: "campaign-002", tenantId: "tenant-acme", channelId: "channel-ops-acme", templateId: "tpl-002", createdByUserId: "user-admin-001", name: "Billing Reminder", campaignType: CampaignType.BULK_FOLLOWUP, audienceType: CampaignAudienceType.MANUAL, status: CampaignStatus.DRAFT, totalRecipients: 0 } ] }); await prisma.campaignRecipient.createMany({ data: [ { id: "recipient-001", tenantId: "tenant-acme", campaignId: "campaign-001", contactId: "contact-001", phoneNumber: "+628123456789", sendStatus: DeliveryStatus.DELIVERED, sentAt: new Date("2026-04-20T10:01:00Z"), deliveredAt: new Date("2026-04-20T10:01:05Z"), readAt: new Date("2026-04-20T11:00:00Z") }, { id: "recipient-002", tenantId: "tenant-acme", campaignId: "campaign-001", contactId: "contact-003", phoneNumber: "+628777777777", sendStatus: DeliveryStatus.FAILED, failureReason: "Template mismatch" } ] }); await prisma.usageMetric.createMany({ data: [ { id: "usage-001", tenantId: "tenant-acme", metricDate: new Date("2026-04-20T00:00:00Z"), inboundMessages: 128, outboundMessages: 96, activeContacts: 3, activeAgents: 2, broadcastSent: 1203, storageUsedMb: 512 } ] }); await prisma.billingInvoice.createMany({ data: [ { id: "invoice-001", tenantId: "tenant-acme", planId: "plan-pro", invoiceNumber: "INV-2026-001", periodStart: new Date("2026-04-01T00:00:00Z"), periodEnd: new Date("2026-04-30T23:59:59Z"), subtotal: 2500000, taxAmount: 275000, totalAmount: 2775000, paymentStatus: PaymentStatus.PAID, dueDate: new Date("2026-04-30T00:00:00Z"), paidAt: new Date("2026-04-15T00:00:00Z") }, { id: "invoice-002", tenantId: "tenant-sinar", planId: "plan-basic", invoiceNumber: "INV-2026-002", periodStart: new Date("2026-04-01T00:00:00Z"), periodEnd: new Date("2026-04-30T23:59:59Z"), subtotal: 1500000, taxAmount: 165000, totalAmount: 1665000, paymentStatus: PaymentStatus.UNPAID, dueDate: new Date("2026-05-01T00:00:00Z") } ] }); await prisma.auditLog.createMany({ data: [ { id: "audit-001", tenantId: "tenant-acme", actorUserId: "user-agent-001", entityType: "conversation", entityId: "conv-001", action: "message_sent", metadataJson: JSON.stringify({ messageId: "msg-002" }) }, { id: "audit-002", tenantId: "tenant-acme", actorUserId: "user-admin-001", entityType: "campaign", entityId: "campaign-001", action: "campaign_created", metadataJson: JSON.stringify({ recipients: 1203 }) } ] }); await prisma.webhookEvent.createMany({ data: [ { id: "webhook-001", tenantId: "tenant-acme", channelId: "channel-main-acme", eventType: "message.inbound", providerEventId: "evt_001", payloadJson: JSON.stringify({ source: "meta", conversationId: "conv-001" }), processStatus: "processed", processedAt: new Date("2026-04-20T09:00:02Z") }, { id: "webhook-002", tenantId: "tenant-acme", channelId: "channel-main-acme", eventType: "message.status", providerEventId: "evt_002", payloadJson: JSON.stringify({ source: "meta", campaignId: "campaign-001" }), processStatus: "failed", failedReason: "Temporary provider mismatch" } ] }); } main() .then(async () => { await prisma.$disconnect(); }) .catch(async (error) => { console.error(error); await prisma.$disconnect(); process.exit(1); });