feat: full clinera platform — auth, appointments, WhatsApp, chatbot canvas, reminders, leads, campaigns, inbox
This commit is contained in:
+211
@@ -0,0 +1,211 @@
|
||||
// Quick setup script for Clinera database
|
||||
const { PrismaClient } = require('@prisma/client');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
const DEFAULT_TEMPLATES = [
|
||||
{
|
||||
trigger: "booking_confirmed",
|
||||
offsetMinutes: 0,
|
||||
sortOrder: 1,
|
||||
message: `Hi {{name}}! ✅
|
||||
|
||||
Your {{treatment}} appointment at {{clinic}} is confirmed:
|
||||
|
||||
📅 {{date}}
|
||||
🕐 {{time}}
|
||||
|
||||
✅ *Tap here to confirm:*
|
||||
{{confirmLink}}
|
||||
|
||||
Or simply reply *YES* to confirm.
|
||||
|
||||
If you need to reschedule, reply *RESCHEDULE* and we'll find a new time for you.
|
||||
|
||||
We're looking forward to seeing you! 😊`,
|
||||
},
|
||||
{
|
||||
trigger: "3_days_before",
|
||||
offsetMinutes: -4320,
|
||||
sortOrder: 2,
|
||||
message: `Hi {{name}}! 👋
|
||||
|
||||
Your {{treatment}} appointment is in 3 days:
|
||||
📅 {{date}} at {{time}}
|
||||
|
||||
Here's how to prepare:
|
||||
{{prepInstructions}}
|
||||
|
||||
Any questions? Just reply to this message and our team will help you right away.
|
||||
|
||||
See you soon! 😊`,
|
||||
},
|
||||
{
|
||||
trigger: "1_day_before",
|
||||
offsetMinutes: -1440,
|
||||
sortOrder: 3,
|
||||
message: `Hi {{name}}! Your appointment is *tomorrow*:
|
||||
|
||||
📅 {{date}} at {{time}}
|
||||
📍 {{clinic}}
|
||||
|
||||
Please arrive 10 minutes early.
|
||||
|
||||
✅ *Tap here to confirm:*
|
||||
{{confirmLink}}
|
||||
|
||||
Or reply *CONFIRM* if you're all set ✅
|
||||
Reply *RESCHEDULE* if you need to change 📅
|
||||
|
||||
We're looking forward to seeing you!`,
|
||||
},
|
||||
{
|
||||
trigger: "2_hours_before",
|
||||
offsetMinutes: -120,
|
||||
sortOrder: 4,
|
||||
message: `See you in 2 hours, {{name}}! 🙌
|
||||
|
||||
Your {{treatment}} appointment:
|
||||
🕐 {{time}} at {{clinic}}
|
||||
|
||||
Safe travels! 😊`,
|
||||
},
|
||||
{
|
||||
trigger: "30_min_before",
|
||||
offsetMinutes: -30,
|
||||
sortOrder: 5,
|
||||
message: `{{name}}, we're ready for you! 😊
|
||||
|
||||
Your appointment starts in 30 minutes at {{time}}.
|
||||
|
||||
See you very soon! ✨`,
|
||||
},
|
||||
];
|
||||
|
||||
async function main() {
|
||||
console.log('🚀 Setting up Clinera database...');
|
||||
|
||||
try {
|
||||
// 1. Create default clinic
|
||||
const hashedPassword = await bcrypt.hash('admin123', 10);
|
||||
|
||||
const clinic = await prisma.clinic.upsert({
|
||||
where: { email: 'admin@clinera.com' },
|
||||
update: {
|
||||
wahaStatus: 'connected',
|
||||
wahaSessionId: 'default',
|
||||
wahaLastChecked: new Date(),
|
||||
},
|
||||
create: {
|
||||
name: 'Clinera Medical Center',
|
||||
slug: 'clinera-medical-center',
|
||||
email: 'admin@clinera.com',
|
||||
phone: '+96170774480',
|
||||
passwordHash: hashedPassword,
|
||||
timezone: 'Asia/Riyadh',
|
||||
quietHoursStart: 22,
|
||||
quietHoursEnd: 8,
|
||||
wahaStatus: 'connected',
|
||||
wahaSessionId: 'default',
|
||||
wahaLastChecked: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
console.log('✅ Clinic created:', clinic.name);
|
||||
|
||||
// 2. Seed reminder templates
|
||||
for (const template of DEFAULT_TEMPLATES) {
|
||||
await prisma.reminderTemplate.create({
|
||||
data: {
|
||||
...template,
|
||||
clinicId: clinic.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
console.log('✅ Reminder templates seeded:', DEFAULT_TEMPLATES.length);
|
||||
|
||||
// 3. Create sample treatments
|
||||
const treatments = await Promise.all([
|
||||
prisma.treatment.create({
|
||||
data: {
|
||||
clinicId: clinic.id,
|
||||
name: 'General Consultation',
|
||||
duration: 30,
|
||||
price: 150,
|
||||
prepInstructions: 'Please bring your ID and insurance card. No special preparation needed.',
|
||||
aftercareInstructions: 'Follow the prescribed medication. Contact us if you have any concerns.',
|
||||
},
|
||||
}),
|
||||
prisma.treatment.create({
|
||||
data: {
|
||||
clinicId: clinic.id,
|
||||
name: 'Dental Cleaning',
|
||||
duration: 60,
|
||||
price: 200,
|
||||
prepInstructions: 'Please brush your teeth before coming. Avoid eating 2 hours before appointment.',
|
||||
aftercareInstructions: 'Avoid eating for 1 hour. Use the prescribed mouthwash twice daily.',
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
console.log('✅ Treatments created:', treatments.length);
|
||||
|
||||
// 4. Create sample lead
|
||||
const lead = await prisma.lead.create({
|
||||
data: {
|
||||
clinicId: clinic.id,
|
||||
name: 'HABLI',
|
||||
phone: '+96170774480',
|
||||
status: 'new',
|
||||
source: 'whatsapp',
|
||||
},
|
||||
});
|
||||
|
||||
console.log('✅ Sample lead created:', lead.name);
|
||||
|
||||
// 5. Create sample appointment for testing
|
||||
const appointment = await prisma.appointment.create({
|
||||
data: {
|
||||
clinicId: clinic.id,
|
||||
leadId: lead.id,
|
||||
treatmentId: treatments[0].id,
|
||||
dateTime: new Date(Date.now() + 2 * 60 * 60 * 1000), // 2 hours from now
|
||||
status: 'scheduled',
|
||||
confirmToken: require('crypto').randomBytes(32).toString('hex'),
|
||||
},
|
||||
});
|
||||
|
||||
console.log('✅ Sample appointment created for:', new Date(appointment.dateTime).toLocaleString());
|
||||
|
||||
// 6. Check final counts
|
||||
const counts = await Promise.all([
|
||||
prisma.clinic.count(),
|
||||
prisma.reminderTemplate.count(),
|
||||
prisma.treatment.count(),
|
||||
prisma.lead.count(),
|
||||
prisma.appointment.count(),
|
||||
]);
|
||||
|
||||
console.log('\n📊 Database Status:');
|
||||
console.log(` Clinics: ${counts[0]}`);
|
||||
console.log(` Templates: ${counts[1]}`);
|
||||
console.log(` Treatments: ${counts[2]}`);
|
||||
console.log(` Leads: ${counts[3]}`);
|
||||
console.log(` Appointments: ${counts[4]}`);
|
||||
|
||||
console.log('\n🎉 Setup complete! You can now:');
|
||||
console.log(' 1. Login with: admin@clinera.com / admin123');
|
||||
console.log(' 2. Start the app: npm run dev');
|
||||
console.log(' 3. Check reminders in the admin panel');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Setup failed:', error);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
Reference in New Issue
Block a user