Files
Moniki_uslugi/apps/cms/src/seed/index.ts
T

378 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dotenv/config'
import { getPayload } from 'payload'
import { paidDoctors } from './paid-doctors'
import { seedPromotions } from './import-promotions'
import { seedReviews } from './import-reviews'
import config from '../payload.config'
const translations = {
ru: {
branchMain: 'КДЦ МОНИКИ (основной)',
branchReutov: 'Филиал КДЦ МОНИКИ в г. Реутов',
addrMain:
'г. Москва, ул. Щепкина, 61/2. Станция метро «Проспект Мира», выход к спорткомплексу «Олимпийский».',
addrReutov: 'Московская область, г. Реутов, проспект Мира, д. 53',
howMain: 'От метро «Проспект Мира» пешком по улице Щепкина до корпуса института.',
howReutov:
'Московская область, г. Реутов, проспект Мира, д. 53. Удобно доехать наземным транспортом от метро «Новокосино» и от станции Реутов.',
},
en: {
branchMain: 'MONIKI CDC (main)',
branchReutov: 'MONIKI CDC branch in Reutov',
addrMain: 'Moscow, Shchepkina St., 61/2. Prospect Mira metro station.',
addrReutov: 'Moscow Region, Reutov, Prospekt Mira, 53',
howMain: 'From Prospect Mira metro walk along Shchepkina Street to the institute campus.',
howReutov:
'Moscow Region, Reutov, Prospekt Mira, 53. Convenient by surface transport from Novokosino metro and Reutov station.',
},
}
async function findOne(payload: Awaited<ReturnType<typeof getPayload>>, collection: 'branches' | 'specialties' | 'services' | 'doctors' | 'users' | 'posts', slugOrEmail: string) {
const field = collection === 'users' ? 'email' : 'slug'
const res = await payload.find({
collection,
where: { [field]: { equals: slugOrEmail } },
limit: 1,
})
return res.docs[0]
}
async function ensureBranchesSchema(payload: Awaited<ReturnType<typeof getPayload>>) {
const adapter = payload.db as {
drizzle: { execute: (query: unknown) => Promise<unknown> }
}
const { sql } = await import('@payloadcms/db-postgres')
await adapter.drizzle.execute(sql`
ALTER TABLE branches ADD COLUMN IF NOT EXISTS sort_order numeric DEFAULT 100
`)
await adapter.drizzle.execute(sql`
UPDATE branches
SET sort_order = 10, is_main = true, lat = 55.786637, lng = 37.627265
WHERE slug = 'kdc-moniki'
`)
await adapter.drizzle.execute(sql`
UPDATE branches
SET sort_order = 20, is_main = false, lat = 55.771049, lng = 37.862507
WHERE slug = 'kdc-reutov'
`)
await adapter.drizzle.execute(sql`
UPDATE branches_locales
SET
name = 'КДЦ МОНИКИ (основной)',
address = 'г. Москва, ул. Щепкина, 61/2. Станция метро «Проспект Мира», выход к спорткомплексу «Олимпийский».',
city = 'Москва',
metro = 'Проспект Мира',
how_to_get = 'От метро «Проспект Мира» пешком по улице Щепкина до корпуса института.'
WHERE _locale = 'ru'
AND _parent_id IN (SELECT id FROM branches WHERE slug = 'kdc-moniki')
`)
await adapter.drizzle.execute(sql`
UPDATE branches_locales
SET
name = 'Филиал КДЦ МОНИКИ в г. Реутов',
address = 'Московская область, г. Реутов, проспект Мира, д. 53',
city = 'Реутов',
how_to_get = 'Московская область, г. Реутов, проспект Мира, д. 53. Удобно доехать наземным транспортом от метро «Новокосино» и от станции Реутов.'
WHERE _locale = 'ru'
AND _parent_id IN (SELECT id FROM branches WHERE slug = 'kdc-reutov')
`)
await adapter.drizzle.execute(sql`
UPDATE branches_locales
SET
name = 'MONIKI CDC (main)',
address = 'Moscow, Shchepkina St., 61/2. Prospect Mira metro station.',
city = 'Moscow',
metro = 'Prospect Mira',
how_to_get = 'From Prospect Mira metro walk along Shchepkina Street to the institute campus.'
WHERE _locale = 'en'
AND _parent_id IN (SELECT id FROM branches WHERE slug = 'kdc-moniki')
`)
await adapter.drizzle.execute(sql`
UPDATE branches_locales
SET
name = 'MONIKI CDC branch in Reutov',
address = 'Moscow Region, Reutov, Prospekt Mira, 53',
city = 'Reutov',
how_to_get = 'Moscow Region, Reutov, Prospekt Mira, 53. Convenient by surface transport from Novokosino metro and Reutov station.'
WHERE _locale = 'en'
AND _parent_id IN (SELECT id FROM branches WHERE slug = 'kdc-reutov')
`)
}
async function seed() {
const payload = await getPayload({ config })
await ensureBranchesSchema(payload)
console.log('Seeding MONIKI demo data...')
const adminEmail = 'admin@moniki.local'
const existingAdmin = await payload.find({
collection: 'users',
where: { email: { equals: adminEmail } },
limit: 1,
})
if (!existingAdmin.docs.length) {
await payload.create({
collection: 'users',
data: {
email: adminEmail,
password: 'Admin123!',
fullName: 'Администратор МОНИКИ',
role: 'admin',
phone: '+7 (499) 674-07-09',
},
})
}
const patientEmail = 'patient@demo.local'
const existingPatient = await payload.find({
collection: 'users',
where: { email: { equals: patientEmail } },
limit: 1,
})
if (!existingPatient.docs.length) {
await payload.create({
collection: 'users',
data: {
email: patientEmail,
password: 'Patient123!',
fullName: 'Иванова Анна Сергеевна',
role: 'patient',
phone: '+7 (900) 123-45-67',
smsOptIn: true,
},
})
}
let branchMain = await findOne(payload, 'branches', 'kdc-moniki')
if (!branchMain) {
branchMain = await payload.create({
collection: 'branches',
locale: 'ru',
data: {
name: translations.ru.branchMain,
slug: 'kdc-moniki',
address: translations.ru.addrMain,
city: 'Москва',
phone: '+7 (499) 674-07-09',
email: 'mail@monikiweb.ru',
metro: 'Проспект Мира',
howToGet: translations.ru.howMain,
isMain: true,
sortOrder: 10,
lat: 55.786637,
lng: 37.627265,
workHours: [
{ day: 'Пн–Сб', hours: '08:00–20:00' },
{ day: 'Вс', hours: '09:00–16:00' },
],
},
})
}
let branchReutov = await findOne(payload, 'branches', 'kdc-reutov')
if (!branchReutov) {
branchReutov = await payload.create({
collection: 'branches',
locale: 'ru',
data: {
name: translations.ru.branchReutov,
slug: 'kdc-reutov',
address: translations.ru.addrReutov,
city: 'Реутов',
phone: '+7 (499) 674-07-09',
howToGet: translations.ru.howReutov,
isMain: false,
sortOrder: 20,
lat: 55.771049,
lng: 37.862507,
workHours: [{ day: 'Пн–Сб', hours: '08:00–20:00' }],
},
})
}
const specialtyDefs = [
{ title: 'Терапия', slug: 'therapy', icon: 'heart' },
{ title: 'Кардиология', slug: 'cardiology', icon: 'activity' },
{ title: 'Неврология', slug: 'neurology', icon: 'cpu-chip' },
{ title: 'Гастроэнтерология', slug: 'gastro', icon: 'beaker' },
{ title: 'Эндокринология', slug: 'endo', icon: 'flash' },
{ title: 'Диагностика', slug: 'diagnostics', icon: 'scan' },
]
const specialties: Record<string, string | number> = {}
for (const [i, s] of specialtyDefs.entries()) {
let doc = await findOne(payload, 'specialties', s.slug)
if (!doc) {
doc = await payload.create({
collection: 'specialties',
locale: 'ru',
data: {
title: s.title,
slug: s.slug,
description: `Платные услуги направления «${s.title}» в МОНИКИ`,
icon: s.icon,
sortOrder: i,
},
})
}
specialties[s.slug] = doc.id
await payload.update({
collection: 'specialties',
id: doc.id,
locale: 'en',
data: {
title: s.slug.charAt(0).toUpperCase() + s.slug.slice(1),
description: `Paid ${s.slug} services at MONIKI`,
},
})
}
const serviceDefs = [
{
title: 'Консультация терапевта',
slug: 'consult-therapy',
price: 3500,
durationMinutes: 30,
specialty: 'therapy',
category: 'consultation' as const,
isPopular: true,
},
{
title: 'Консультация кардиолога',
slug: 'consult-cardio',
price: 4500,
durationMinutes: 40,
specialty: 'cardiology',
category: 'consultation' as const,
isPopular: true,
},
{
title: 'Консультация невролога',
slug: 'consult-neuro',
price: 4200,
durationMinutes: 40,
specialty: 'neurology',
category: 'consultation' as const,
isPopular: false,
},
{
title: 'УЗИ органов брюшной полости',
slug: 'uzi-abdomen',
price: 3200,
durationMinutes: 30,
specialty: 'diagnostics',
category: 'diagnostics' as const,
isPopular: true,
},
{
title: 'ЭКГ с расшифровкой',
slug: 'ecg',
price: 1800,
durationMinutes: 20,
specialty: 'cardiology',
category: 'diagnostics' as const,
isPopular: true,
},
{
title: 'Комплексное обследование «Чек-ап»',
slug: 'checkup',
price: 18900,
durationMinutes: 120,
specialty: 'diagnostics',
category: 'package' as const,
isPopular: true,
},
]
const services: Record<string, string | number> = {}
for (const s of serviceDefs) {
let doc = await findOne(payload, 'services', s.slug)
if (!doc) {
doc = await payload.create({
collection: 'services',
locale: 'ru',
data: {
title: s.title,
slug: s.slug,
description: `${s.title} в платных отделениях МОНИКИ. Полная оплата через СБП.`,
price: s.price,
durationMinutes: s.durationMinutes,
specialty: specialties[s.specialty],
category: s.category,
branches: [branchMain.id, branchReutov.id],
isPopular: s.isPopular,
isPublished: true,
},
})
}
services[s.slug] = doc.id
}
const doctors: Record<string, string | number> = {}
for (const d of paidDoctors) {
let doc = await findOne(payload, 'doctors', d.slug)
if (!doc) {
doc = await payload.create({
collection: 'doctors',
locale: 'ru',
data: {
fullName: d.fullName,
slug: d.slug,
position: [d.position, d.specialty]
.filter((value, index, arr) => value && arr.indexOf(value) === index)
.join(' · '),
degree: d.degree || undefined,
experienceYears: d.experienceYears,
bio: d.bio,
photoUrl: d.photo,
photoPending: d.photoPending,
specialties: d.specialtySlugs.map((s) => specialties[s]).filter(Boolean),
branches: [branchMain.id],
education: d.education.map((item) => ({ item })),
defaultSlotMinutes: d.defaultSlotMinutes,
isPublished: true,
rating: 0,
reviewsCount: 0,
},
})
await payload.create({
collection: 'schedules',
data: {
title: `Расписание: ${d.fullName}`,
doctor: doc.id,
branch: branchMain.id,
slotMinutes: d.defaultSlotMinutes,
isActive: true,
weekdays: [
{ day: '1', startTime: '09:00', endTime: '14:00' },
{ day: '2', startTime: '09:00', endTime: '14:00' },
{ day: '3', startTime: '14:00', endTime: '19:00' },
{ day: '4', startTime: '09:00', endTime: '14:00' },
{ day: '5', startTime: '09:00', endTime: '13:00' },
],
},
})
}
doctors[d.slug] = doc.id
}
const existingReviews = await payload.find({ collection: 'reviews', limit: 1 })
if (!existingReviews.docs.length) {
await seedReviews(payload)
}
await seedPromotions(payload)
console.log('Seed complete.')
console.log('Admin: admin@moniki.local / Admin123!')
console.log('Patient: patient@demo.local / Patient123!')
process.exit(0)
}
seed().catch((err) => {
console.error(err)
process.exit(1)
})