feat: full clinera platform — auth, appointments, WhatsApp, chatbot canvas, reminders, leads, campaigns, inbox

This commit is contained in:
Obaid alah Saleh
2026-03-13 12:45:14 +02:00
parent fe044c91b4
commit 66a3568d01
195 changed files with 41621 additions and 4568 deletions
+211
View File
@@ -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);