# Отчёт об аудите проекта TenerifeProp ## Дата аудита: 2026-05-13 ## 1. Архитектура проекта ### Стек проекта | Компонент | Реализация | |-----------|-----------| | **Runtime** | Bun (1.1.0) | | **HTTP Framework** | Hono v4.0 | | **База данных** | SQLite (через `bun:sqlite`) — WAL mode | | **Статика** | `serveStatic` из `hono/bun` | | **Auth** | Сессии в SQLite, bcrypt через Bun.password.hashSync | | **Rate Limit** | In-memory Map | | **API** | REST JSON, Hono middleware (cors, logger, csrf) | ### Критические зависимости от Bun ``` import { Database } from 'bun:sqlite' import { serveStatic } from 'hono/bun' Bun.password.hashSync(...) // Строка 583 Bun.password.verify(...) // Ожидается в auth ``` **Bun является обязательным runtime.** Node.js НЕ может запустить этот код без переписывания: - `bun:sqlite` → `better-sqlite3` - `hono/bun` → `hono/node-server` - `Bun.password` → `bcrypt` ### Структура данных База данных SQLite содержит таблицы: - `properties` — объекты недвижимости (поля title_es/title_ru, images JSON, geolocation) - `leads` — заявки клиентов - `testimonials` — отзывы - `faq` — вопросы/ответы - `services` — услуги - `settings` — настройки сайта - `users` — пользователи админки - `sessions` — авторизационные сессии - `analytics_events` / `analytics_daily` — аналитика ### API Endpoints ``` GET /api/properties — список объектов (с фильтрами) GET /api/properties/featured — избранные объекты GET /api/properties/:slug — детальная страница POST /api/leads — создание заявки GET /api/testimonials — отзывы GET /api/faq — FAQ GET /api/services — услуги GET /api/settings — настройки сайта GET /api/cities — список городов GET /api/stats — статистика POST /api/analytics/event — трекинг событий POST /api/auth/login — вход в админку POST /api/auth/logout — выход ``` ### Админ панель Путь: `/admin` — SPA с HTML-страницами (`public/admin/*.html`) ## 2. Архитектура сервера (BrainyCP) ### Обнаруженная конфигурация | Параметр | Значение | |----------|----------| | **OS** | Ubuntu 22.04 LTS | | **IP** | 46.175.149.131 | | **Панель** | BrainyCP | | **Пользователь** | nero (uid=1002) | | **Web-сервер** | Nginx 1.27.0 | | **SSL** | Let's Encrypt (активен) | | **PHP** | 5.2–8.3 (множество версий, не используется) | | **Node.js** | v20.10.0 (установлен BrainyCP, `/home/nero/usr/bin/node`) | | **Порт** | 3003 (занят заглушкой) | ### Nginx конфигурация BrainyCP настроила два vhost: - **HTTP**: `tenerifeprop.es:80` → `proxy_pass http://46.175.149.131:3003` - **HTTPS**: `tenerifeprop.es:443` → `proxy_pass http://46.175.149.131:3003` + SSL Проксирование уже работает. Nginx терминирует SSL и отправляет HTTP к backend. ### Systemd unit ``` nodejs@3003.service — запускает /home/nero/usr/bin/node index.js WorkingDirectory: /home/nero/sites/tenerifeprop.es Environment: NODE_PORT=3003 Статус: active (running) PID: 1233379 ``` ## 3. Конфликт стеков ### BrainyCP предоставляет - Node.js (v20) — **работает только через кнопку "NodeJS" в панели** - Nginx + SSL — уже настроено - PHP-FPM — избыточно для этого проекта - Apache — избыточно ### Проект требует - **Bun runtime** — Node.js не поддерживает `bun:sqlite`, `hono/bun`, `Bun.password` - Порт 3003 (или другой) — свободен - PM2 для процесс-менеджмента ### Решение **Нужно установить Bun на сервере.** Это не конфликтует с системным Node.js — Bun устанавливается в `$HOME/.bun` и не трогает системные пакеты. ## 4. Файлы, необходимые для деплоя ### Что нужно скопировать на сервер ``` src/ (TypeScript код сервера) public/ (HTML, CSS, JS, изображения) data/ (SQLite база данных — если переносим) package.json (зависимости) bun.lock (lock-файл) .env (переменные окружения) ``` ### Файлы НЕ нужны ``` Dockerfile (не используется в production на BrainyCP) docker-compose.yml (не используется) .kilo/ (конфигурация агентов — dev-only) tests/ (тесты — dev-only) node_modules/ (установятся на сервере) ``` ## 5. План деплоя (пошаговый) ### Перед деплоем — подготовка 1. Дамп БД: скопировать `data/tenerifeprop.db` с локального Docker 2. Создать `.env` с production значениями: ``` NODE_ENV=production PORT=3003 RESEND_API_KEY= TELEGRAM_BOT_TOKEN= TELEGRAM_CHAT_ID= ``` 3. Запаковать файлы в архив или подготовить для scp ### На сервере (через SSH) ```bash # 1. Установить Bun curl -fsSL https://bun.sh/install | bash source ~/.bashrc # 2. Остановить заглушку BrainyCP sudo systemctl stop nodejs@3003.service sudo systemctl disable nodejs@3003.service # 3. Очистить папку сайта (кроме .well-known для SSL) cd /home/nero/sites/tenerifeprop.es sudo rm -f index.js app.js app.css # Создать папки mkdir -p src public data # 4. Загрузить файлы (с локальной машины) scp -r src public package.json bun.lock .env root@46.175.149.131:/home/nero/sites/tenerifeprop.es/ # Загрузить БД (если переносим) scp data/tenerifeprop.db root@46.175.149.131:/home/nero/sites/tenerifeprop.es/data/ # 5. Установить зависимости bun install --production # 6. Назначить права sudo chown -R nero:nero /home/nero/sites/tenerifeprop.es sudo chmod 755 /home/nero/sites/tenerifeprop.es sudo chmod 600 .env # 7. Установить PM2 bun add -g pm2 # 8. Запустить через PM2 pm2 start "bun run src/server/index.ts" --name tenerifeprop pm2 save pm2 startup systemd # 9. Проверить curl http://localhost:3003/api/settings ``` ### В BrainyCP - Кнопка "Перезапустить хост" в панели → НЕ нажимать (перезапустит заглушку) - Nginx уже настроен, SSL работает - Нужно только убедиться, что PM2-автозапуск настроен ## 6. Риски | Риск | Уровень | Митигация | |------|---------|-----------| | BrainyCP может перезаписать Nginx-конфиг | Средний | Не редактировать `/etc/nginx` руками; использовать панель | | Обновление BrainyCP сбрасывает systemd unit | Средний | PM2 автозапуск не зависит от BrainyCP | | Bun не в репозиториях Ubuntu | Низкий | Устанавливается curl скриптом, обновляется `bun upgrade` | | SQLite WAL mode и NFS | Низкий | BrainyCP использует ext4, WAL работает | | Перезагрузка сервера | Низкий | PM2 + systemd обеспечат автозапуск | ## 7. Итог **Проект готов к деплою при условии установки Bun.** Текущая конфигурация BrainyCP (Nginx + SSL + порт 3003) идеально подходит под наш проект. Нужно: 1. Установить Bun 2. Остановить BrainyCP-заглушку 3. Загрузить файлы проекта 4. Запустить через PM2 Nginx уже проксирует домен на порт 3003 — всё будет работать сразу после запуска Bun-процесса. --- *Отчёт подготовлен после полного аудита сервера и кода проекта.*