feat: Оптимизация навигации AdminJS в логические группы

- Объединены ресурсы в 5 логических групп: Контент сайта, Бронирования, Отзывы и рейтинги, Персонал и гиды, Администрирование
- Удалены дублирующие настройки navigation для чистой группировки
- Добавлены CSS стили для визуального отображения иерархии с отступами
- Добавлены эмодзи-иконки для каждого типа ресурсов через CSS
- Улучшена навигация с правильной вложенностью элементов
This commit is contained in:
2025-11-30 21:57:58 +09:00
parent 1e7d7c06eb
commit 13c752b93a
47 changed files with 14148 additions and 61 deletions

View File

@@ -0,0 +1,22 @@
-- Создание таблицы расписания работы гидов
CREATE TABLE IF NOT EXISTS guide_schedules (
id SERIAL PRIMARY KEY,
guide_id INTEGER NOT NULL REFERENCES guides(id) ON DELETE CASCADE,
work_date DATE NOT NULL,
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- Уникальный индекс для предотвращения дублирования
UNIQUE(guide_id, work_date)
);
-- Индексы для оптимизации запросов
CREATE INDEX IF NOT EXISTS idx_guide_schedules_guide_id ON guide_schedules(guide_id);
CREATE INDEX IF NOT EXISTS idx_guide_schedules_work_date ON guide_schedules(work_date);
CREATE INDEX IF NOT EXISTS idx_guide_schedules_date_range ON guide_schedules(guide_id, work_date);
-- Комментарии
COMMENT ON TABLE guide_schedules IS 'Расписание рабочих дней гидов';
COMMENT ON COLUMN guide_schedules.guide_id IS 'ID гида';
COMMENT ON COLUMN guide_schedules.work_date IS 'Дата рабочего дня';
COMMENT ON COLUMN guide_schedules.notes IS 'Дополнительные заметки о рабочем дне';

View File

@@ -0,0 +1,22 @@
-- Создание новой таблицы для конкретных рабочих дней гидов
CREATE TABLE IF NOT EXISTS guide_working_days (
id SERIAL PRIMARY KEY,
guide_id INTEGER NOT NULL REFERENCES guides(id) ON DELETE CASCADE,
work_date DATE NOT NULL,
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- Уникальный индекс для предотвращения дублирования
UNIQUE(guide_id, work_date)
);
-- Индексы для оптимизации запросов
CREATE INDEX IF NOT EXISTS idx_guide_working_days_guide_id ON guide_working_days(guide_id);
CREATE INDEX IF NOT EXISTS idx_guide_working_days_work_date ON guide_working_days(work_date);
CREATE INDEX IF NOT EXISTS idx_guide_working_days_date_range ON guide_working_days(guide_id, work_date);
-- Комментарии
COMMENT ON TABLE guide_working_days IS 'Конкретные рабочие дни гидов';
COMMENT ON COLUMN guide_working_days.guide_id IS 'ID гида';
COMMENT ON COLUMN guide_working_days.work_date IS 'Дата рабочего дня';
COMMENT ON COLUMN guide_working_days.notes IS 'Дополнительные заметки о рабочем дне';

View File

@@ -15,11 +15,55 @@ export async function initDatabase() {
await db.query('SELECT 1');
console.log('✅ Database connection successful');
// 1. Create schema
// 1. Create schema with trigger safety
console.log('📋 Creating database schema...');
// Сначала создаем или заменяем функцию
await db.query(`
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ language 'plpgsql';
`);
const schemaPath = path.join(__dirname, 'schema.sql');
const schema = fs.readFileSync(schemaPath, 'utf8');
await db.query(schema);
// Проверяем и создаем триггеры только если не существуют
const existingTriggers = await db.query(`
SELECT trigger_name
FROM information_schema.triggers
WHERE event_object_schema = 'public'
AND trigger_name LIKE '%update%updated_at%'
`);
const triggerNames = new Set(existingTriggers.rows.map(row => row.trigger_name));
const triggersToCreate = [
{ table: 'admins', name: 'update_admins_updated_at' },
{ table: 'routes', name: 'update_routes_updated_at' },
{ table: 'articles', name: 'update_articles_updated_at' },
{ table: 'guides', name: 'update_guides_updated_at' }
];
for (const { table, name } of triggersToCreate) {
if (!triggerNames.has(name)) {
await db.query(`
CREATE TRIGGER ${name}
BEFORE UPDATE ON ${table}
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
`);
console.log(`✅ Created trigger ${name}`);
} else {
console.log(` Trigger ${name} already exists`);
}
}
console.log('✅ Database schema created successfully');
// 2. Check if tables are empty (first run)