Major UX improvements across multiple pages
Шахматка: - Date/period picker dropdown on navigation button (choose start date + days window) - Cancelled bookings fade out with animation after 1 second Бронирования: - Clickable column headers with sort asc/desc (Гость, Заезд, Выезд, Статус, Источник, Сумма) Страница входа: - Removed role-based account selector — just email + password - System auto-detects role/hotel from credentials Настройки: - New "Бронирование" section with room assignment strategy (spread/together/sequential/manual) - Notifications: SMTP email config + SMS provider config (SMSC, SMS.ru, МТС, etc.) Модули: - Added Housekeeping and Channel Manager as proper modules - Channel Manager lists: Booking.com, Airbnb, Яндекс Путешествия, Островок, Суточно.ру, OneTwoTrip - Housekeeping visible to all roles (including housekeeper) via module status - Sidebar now uses module status to show/hide Уборка and Каналы Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
48
backend/src/migrate.ts
Normal file
48
backend/src/migrate.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { db } from './db'
|
||||
|
||||
export async function runMigrations() {
|
||||
const migrationsDir = path.join(process.cwd(), 'migrations')
|
||||
|
||||
// Create migrations tracking table
|
||||
await db.query(`
|
||||
CREATE TABLE IF NOT EXISTS _migrations (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)
|
||||
`)
|
||||
|
||||
const files = fs.readdirSync(migrationsDir)
|
||||
.filter(f => f.endsWith('.sql'))
|
||||
.sort()
|
||||
|
||||
for (const file of files) {
|
||||
const { rows } = await db.query(
|
||||
'SELECT id FROM _migrations WHERE name = $1',
|
||||
[file],
|
||||
)
|
||||
if (rows.length > 0) continue // already applied
|
||||
|
||||
const sql = fs.readFileSync(path.join(migrationsDir, file), 'utf8')
|
||||
console.log(`[migrate] Applying ${file}...`)
|
||||
|
||||
const client = await db.connect()
|
||||
try {
|
||||
await client.query('BEGIN')
|
||||
await client.query(sql)
|
||||
await client.query('INSERT INTO _migrations (name) VALUES ($1)', [file])
|
||||
await client.query('COMMIT')
|
||||
console.log(`[migrate] ✅ ${file} applied`)
|
||||
} catch (err) {
|
||||
await client.query('ROLLBACK')
|
||||
console.error(`[migrate] ❌ ${file} failed:`, err)
|
||||
throw err
|
||||
} finally {
|
||||
client.release()
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[migrate] All migrations up to date')
|
||||
}
|
||||
Reference in New Issue
Block a user