import bcrypt from 'bcryptjs' import { db } from './db' const HOTELS = [ { name: 'Grand Palace Hotel', slug: 'grand-palace', plan: 'pro' }, { name: 'Marina Bay Resort', slug: 'marina-bay', plan: 'enterprise' }, { name: 'City Center Inn', slug: 'city-inn', plan: 'starter' }, ] const ROOMS_TEMPLATE = [ { number: '101', type: 'Standard', floor: 1, capacity: 2, price: 3500 }, { number: '102', type: 'Standard', floor: 1, capacity: 2, price: 3500 }, { number: '103', type: 'Deluxe', floor: 1, capacity: 3, price: 5200 }, { number: '201', type: 'Deluxe', floor: 2, capacity: 3, price: 5200 }, { number: '202', type: 'Suite', floor: 2, capacity: 4, price: 8900 }, { number: '301', type: 'Suite', floor: 3, capacity: 4, price: 8900 }, { number: '302', type: 'Junior Suite', floor: 3, capacity: 4, price: 6800 }, { number: '401', type: 'Penthouse', floor: 4, capacity: 6, price: 18000 }, ] export async function seedIfEmpty() { const { rows } = await db.query('SELECT count(*)::int AS c FROM hotels') if (rows[0].c > 0) { console.log('[seed] Data already exists, skipping') return } console.log('[seed] Seeding demo data...') const passwordHash = await bcrypt.hash('demo', 12) for (const hotel of HOTELS) { // Insert hotel const { rows: [h] } = await db.query( `INSERT INTO hotels (name, slug, plan) VALUES ($1, $2, $3) RETURNING id`, [hotel.name, hotel.slug, hotel.plan], ) const hotelId = h.id // Insert rooms for (const r of ROOMS_TEMPLATE) { await db.query( `INSERT INTO rooms (hotel_id, number, type, floor, capacity, price_per_night, amenities) VALUES ($1, $2, $3, $4, $5, $6, $7)`, [hotelId, r.number, r.type, r.floor, r.capacity, r.price, ['Wi-Fi', 'TV', 'Mini-bar']], ) } // Insert channels (disabled by default) for (const name of ['booking_com', 'airbnb', 'expedia', 'vrbo']) { await db.query( `INSERT INTO channels (hotel_id, name) VALUES ($1, $2)`, [hotelId, name], ) } } // Super admin (no hotel) await db.query( `INSERT INTO users (email, password_hash, name, role, hotel_id) VALUES ($1, $2, 'Super Admin', 'super_admin', NULL)`, ['admin@hotelsync.io', passwordHash], ) // Grand Palace users const { rows: [gp] } = await db.query( `SELECT id FROM hotels WHERE slug = 'grand-palace'`, ) await db.query( `INSERT INTO users (email, password_hash, name, role, hotel_id) VALUES ($1, $2, 'Артём Голомазов', 'manager', $3), ($4, $2, 'Клавдия Иванова', 'housekeeper', $3)`, ['manager@grand-palace.ru', passwordHash, gp.id, 'cleaner@grand-palace.ru'], ) // Seed a few bookings for grand-palace const { rows: rooms } = await db.query( `SELECT id FROM rooms WHERE hotel_id = $1 LIMIT 4`, [gp.id], ) const today = new Date() const d = (offset: number) => { const dt = new Date(today) dt.setDate(dt.getDate() + offset) return dt.toISOString().slice(0, 10) } const bookingData = [ { room: 0, guest: 'Иван Петров', email: 'ivan@example.com', ci: d(-2), co: d(1), status: 'checked_in', src: 'direct' }, { room: 1, guest: 'Maria Schmidt', email: 'maria@example.com', ci: d(1), co: d(4), status: 'confirmed', src: 'booking_com' }, { room: 2, guest: 'John Smith', email: 'john@example.com', ci: d(3), co: d(7), status: 'confirmed', src: 'airbnb' }, { room: 3, guest: 'Анна Сидорова', email: 'anna@example.com', ci: d(-5), co: d(-1), status: 'checked_out', src: 'direct' }, ] for (const b of bookingData) { if (!rooms[b.room]) continue const nights = (new Date(b.co).getTime() - new Date(b.ci).getTime()) / 86400000 await db.query( `INSERT INTO bookings (hotel_id, room_id, guest_name, guest_email, check_in, check_out, status, source, total_amount) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, [gp.id, rooms[b.room].id, b.guest, b.email, b.ci, b.co, b.status, b.src, nights * 3500], ) } // Seed housekeeping tasks const taskRooms = rooms.slice(0, 3) const { rows: [cleaner] } = await db.query( `SELECT id FROM users WHERE email = 'cleaner@grand-palace.ru'`, ) const taskData = [ { r: 0, type: 'cleaning', status: 'pending', priority: 'high', notes: 'Стандартная уборка' }, { r: 1, type: 'turnover', status: 'in_progress', priority: 'urgent', notes: 'Заезд через 2 часа' }, { r: 2, type: 'inspection', status: 'pending', priority: 'medium', notes: 'Плановая проверка' }, ] for (const t of taskData) { if (!taskRooms[t.r]) continue await db.query( `INSERT INTO housekeeping_tasks (hotel_id, room_id, type, status, priority, assignee_id, notes, due_date) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, [gp.id, taskRooms[t.r].id, t.type, t.status, t.priority, cleaner.id, t.notes, d(0)], ) } console.log('[seed] ✅ Demo data seeded') console.log('[seed] admin@hotelsync.io / demo (super_admin)') console.log('[seed] manager@grand-palace.ru / demo (manager)') console.log('[seed] cleaner@grand-palace.ru / demo (housekeeper)') }