🚀 Korea Tourism Agency - Complete implementation

 Features:
- Modern tourism website with responsive design
- AdminJS admin panel with image editor integration
- PostgreSQL database with comprehensive schema
- Docker containerization
- Image upload and gallery management

🛠 Tech Stack:
- Backend: Node.js + Express.js
- Database: PostgreSQL 13+
- Frontend: HTML/CSS/JS with responsive design
- Admin: AdminJS with custom components
- Deployment: Docker + Docker Compose
- Image Processing: Sharp with optimization

📱 Admin Features:
- Routes/Tours management (city, mountain, fishing)
- Guides profiles with specializations
- Articles and blog system
- Image editor with upload/gallery/URL options
- User management and authentication
- Responsive admin interface

🎨 Design:
- Korean tourism focused branding
- Mobile-first responsive design
- Custom CSS with modern aesthetics
- Image optimization and gallery
- SEO-friendly structure

🔒 Security:
- Helmet.js security headers
- bcrypt password hashing
- Input validation and sanitization
- CORS protection
- Environment variables
This commit is contained in:
2025-11-30 00:53:15 +09:00
parent ed871fc4d1
commit b4e513e996
36 changed files with 6894 additions and 239 deletions

View File

@@ -0,0 +1,57 @@
-- Исправление триггеров для таблиц с изображениями
-- Запускается автоматически при инициализации базы данных
-- Сначала удаляем существующие проблемные триггеры если они есть
DROP TRIGGER IF EXISTS routes_updated_at_trigger ON routes;
DROP TRIGGER IF EXISTS guides_updated_at_trigger ON guides;
-- Создаем функцию для обновления updated_at (если её нет)
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ language 'plpgsql';
-- Создаем триггеры для обновления updated_at при изменении записей
CREATE TRIGGER routes_updated_at_trigger
BEFORE UPDATE ON routes
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER guides_updated_at_trigger
BEFORE UPDATE ON guides
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- Добавляем индексы для оптимизации запросов к изображениям
CREATE INDEX IF NOT EXISTS idx_routes_image_url ON routes(image_url) WHERE image_url IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_guides_image_url ON guides(image_url) WHERE image_url IS NOT NULL;
-- Создаем таблицу для метаданных загруженных изображений (опционально)
CREATE TABLE IF NOT EXISTS image_metadata (
id SERIAL PRIMARY KEY,
url VARCHAR(500) NOT NULL UNIQUE,
filename VARCHAR(255) NOT NULL,
original_name VARCHAR(255),
size_bytes INTEGER,
width INTEGER,
height INTEGER,
mime_type VARCHAR(100),
entity_type VARCHAR(50), -- 'routes', 'guides', 'articles', etc.
entity_id INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Индекс для поиска изображений по типу сущности
CREATE INDEX IF NOT EXISTS idx_image_metadata_entity ON image_metadata(entity_type, entity_id);
-- Триггер для image_metadata
CREATE TRIGGER image_metadata_updated_at_trigger
BEFORE UPDATE ON image_metadata
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
COMMIT;