Compare commits

2 Commits
1 ... master

Author SHA1 Message Date
0114a88043 TMUX перезапускал. Арсен. 2026-02-10 13:06:23 +05:00
4993816a95 Настройка запуска на Ubuntu + tmux и доступ извне (Арсен.)
- Добавлены инструкции `docs/UBUNTU_SETUP.md` и секции в README.
- Добавлены скрипты `scripts/setup-postgres-ubuntu.sh` и `scripts/start-tmux.sh` (tmux: front/back).
- Для доступа снаружи: Vite `allowedHosts: true`, бэкенд слушает `0.0.0.0`.
- Добавлен сид демо-пользователя портала `demo` / `demo123` с ролью DIRECTOR (как `its`).
- `.env` файлы добавлены в `.gitignore`, чтобы не коммитить секреты.

Выполнил: Арсен.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 11:55:20 +05:00
11 changed files with 309 additions and 12 deletions

7
.gitignore vendored
View File

@@ -12,6 +12,13 @@ dist
dist-ssr
*.local
# Env files (never commit secrets)
.env
.env.*
!.env.example
!.env.production
backend/.env
# Editor directories and files
.vscode/*
!.vscode/extensions.json

View File

@@ -86,7 +86,17 @@ VITE_DOMA_AI_PASSWORD=your-password
**Для тестирования** можно использовать тестовый стенд: https://condo.d.doma.ai/
### 3. Запуск в режиме разработки
### 3. (Ubuntu) Один раз настройте PostgreSQL
Логин и пароль БД заданы в `backend/.env` (логин: **mkd_user**, пароль: **MkdUbuntu24Secure**). Выполните в терминале (введёте пароль sudo):
```bash
sudo bash scripts/setup-postgres-ubuntu.sh
```
Затем в одном терминале: `cd backend && npm start`, в другом: `npm run dev`.
### 4. Запуск в режиме разработки
```bash
npm run dev
@@ -94,13 +104,27 @@ npm run dev
Приложение будет доступно по адресу: `http://localhost:3000`
### 4. Сборка для продакшена
### 4.1. Запуск в tmux (не зависит от SSH)
Бэкенд и фронт в tmux-сессиях **back** и **front** — после отключения SSH процессы продолжают работать.
```bash
bash scripts/start-tmux.sh
```
- Подключиться к логам: `tmux attach -t back` или `tmux attach -t front`
- Выйти из tmux без остановки: **Ctrl+B**, затем **D**
- Список сессий: `tmux ls`
Доступ снаружи (если открыты порты в файрволе): **http://&lt;IP-сервера&gt;:3000** (фронт), **http://&lt;IP-сервера&gt;:4000/api** (API). На Ubuntu при необходимости: `sudo ufw allow 3000 && sudo ufw allow 4000 && sudo ufw reload`
### 5. Сборка для продакшена
```bash
npm run build
```
### 5. Просмотр production сборки
### 6. Просмотр production сборки
```bash
npm run preview

View File

@@ -1,4 +1,5 @@
PORT=4000
DATABASE_URL=postgres://mkd_user:Nemo348ax@@localhost:5432/mkd_control_center
# Логин: mkd_user, пароль: MkdUbuntu24Secure
DATABASE_URL=postgres://mkd_user:MkdUbuntu24Secure@localhost:5432/mkd_control_center
DOMA_API_URL=https://condo.d.doma.ai/admin/api
DOMA_API_TOKEN=d-7Tf8g0r277ismVAmBnVOZvxaTBYCkz.CLBfWjkEc503Df4Nifw558wKi3w1XnvpF/L4zIDqylc

View File

@@ -12,6 +12,13 @@ const DEFAULT_ADMIN_LOGIN = 'its';
const DEFAULT_ADMIN_PASSWORD = 'iiEasy348ax@';
const DEFAULT_ADMIN_ROLE = 'DIRECTOR';
// Демо-пользователь с теми же правами, что и its (DIRECTOR)
const DEMO_EMPLOYEE_ID = 'e-demo';
const DEMO_EMPLOYEE_NAME = 'Demo';
const DEMO_LOGIN = 'demo';
const DEMO_PASSWORD = 'demo123';
const DEMO_ROLE = 'DIRECTOR';
/**
* Инициализация базы данных PostgreSQL
* Создает БД при первом запуске и проверяет целостность при последующих запусках
@@ -220,6 +227,9 @@ async function initializeDatabase() {
// Администратор портала по умолчанию (логин its) — создаётся, если ещё нет
await applyDefaultAdminSeed(client);
// Демо-пользователь (demo / demo123) с правами DIRECTOR — создаётся при каждом старте, если ещё нет
await applyDemoUserSeed(client);
return {
success: true,
initialized: !integrityCheck.isInitialized,
@@ -2572,6 +2582,55 @@ async function applyDefaultAdminSeed(client) {
}
}
/**
* Демо-пользователь портала (логин demo, пароль demo123) с правами DIRECTOR, как у its.
*/
async function applyDemoUserSeed(client) {
try {
const existingUser = await client.query(
'SELECT id FROM portal_users WHERE login = $1',
[DEMO_LOGIN]
);
if (existingUser.rows.length > 0) {
return;
}
const employeeExists = await client.query(
'SELECT id FROM employees WHERE id = $1',
[DEMO_EMPLOYEE_ID]
);
if (employeeExists.rows.length === 0) {
await client.query(
`INSERT INTO employees (id, name, position, phone, status, salary, assigned_district_id)
VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (id) DO NOTHING`,
[
DEMO_EMPLOYEE_ID,
DEMO_EMPLOYEE_NAME,
'Демо-пользователь',
'+70000000001',
'active',
0,
null,
]
);
console.log('[dbInit] Создан сотрудник для демо:', DEMO_EMPLOYEE_NAME);
}
const passwordHash = await bcrypt.hash(DEMO_PASSWORD, 10);
await client.query(
`INSERT INTO portal_users (employee_id, login, role, password_hash, is_active)
VALUES ($1, $2, $3, $4, true)
ON CONFLICT (login) DO NOTHING`,
[DEMO_EMPLOYEE_ID, DEMO_LOGIN, DEMO_ROLE, passwordHash]
);
const check = await client.query('SELECT id FROM portal_users WHERE login = $1', [DEMO_LOGIN]);
if (check.rows.length > 0) {
console.log('[dbInit] Создан демо-пользователь портала: логин', DEMO_LOGIN, ', роль', DEMO_ROLE);
}
} catch (error) {
console.warn('[dbInit] Ошибка при создании демо-пользователя:', error.message);
}
}
/**
* Таблица настроек интеграций (DaData и др.)
*/

View File

@@ -862,7 +862,8 @@
"version": "0.0.1551306",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1551306.tgz",
"integrity": "sha512-CFx8QdSim8iIv+2ZcEOclBKTQY6BI1IEDa7Tm9YkwAXzEWFndTEzpTo5jAUhSnq24IC7xaDw0wvGcm96+Y3PEg==",
"license": "BSD-3-Clause"
"license": "BSD-3-Clause",
"peer": true
},
"node_modules/dom-serializer": {
"version": "2.0.0",
@@ -1929,7 +1930,6 @@
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"license": "MIT",
"peer": true,
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
@@ -2330,6 +2330,7 @@
"resolved": "https://registry.npmjs.org/pg/-/pg-8.17.2.tgz",
"integrity": "sha512-vjbKdiBJRqzcYw1fNU5KuHyYvdJ1qpcQg1CeBrHFqV1pWgHeVR6j/+kX0E1AAXfyuLUGY1ICrN2ELKA/z2HWzw==",
"license": "MIT",
"peer": true,
"dependencies": {
"pg-connection-string": "^2.10.1",
"pg-pool": "^3.11.0",
@@ -2806,7 +2807,6 @@
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
}

View File

@@ -374,8 +374,8 @@ async function startServer() {
process.exit(1);
}
}
app.listen(PORT, () => {
console.log(`Backend API running on http://localhost:${PORT}${API_PREFIX}`);
app.listen(PORT, '0.0.0.0', () => {
console.log(`Backend API running on http://0.0.0.0:${PORT}${API_PREFIX}`);
if (DATABASE_URL) {
ensureEmployeeResponsibilityTable()
.then(() => console.log('[backend] Таблица employee_responsibility проверена/создана'))

161
docs/UBUNTU_SETUP.md Normal file
View File

@@ -0,0 +1,161 @@
# Запуск проекта на Ubuntu 24.04
После переноса с Windows проект запускается на Ubuntu так же через Node.js и PostgreSQL. Ниже — пошаговая настройка.
## 1. Установка Node.js (18+)
```bash
# Через NodeSource (рекомендуется LTS)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# Проверка
node -v # v20.x.x
npm -v
```
Либо через стандартный репозиторий Ubuntu:
```bash
sudo apt update
sudo apt install -y nodejs npm
```
## 2. Установка PostgreSQL
```bash
sudo apt update
sudo apt install -y postgresql postgresql-contrib
sudo systemctl start postgresql
sudo systemctl enable postgresql
```
Создание пользователя и базы (опционально, если ещё не созданы):
```bash
sudo -u postgres psql -c "CREATE USER mkd_user WITH PASSWORD 'your_password';"
sudo -u postgres psql -c "CREATE DATABASE mkd_control_center OWNER mkd_user;"
```
Строка подключения для `.env` бэкенда:
```
postgres://mkd_user:your_password@localhost:5432/mkd_control_center
```
## 3. Зависимости для Puppeteer (бэкенд)
Бэкенд использует Puppeteer. На Ubuntu нужны системные библиотеки:
```bash
sudo apt install -y \
ca-certificates fonts-liberation libasound2 libatk-bridge2.0-0 \
libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 \
libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 \
libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 \
libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 \
libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
libxtst6 lsb-release wget xdg-utils
```
## 4. Настройка проекта
### 4.1 Клонирование / копирование
Если репозиторий уже скопирован в каталог проекта (например, `/home/its/mkd`), переходите в него:
```bash
cd /home/its/mkd
```
### 4.2 Установка зависимостей
В корне (фронтенд) и в `backend`:
```bash
npm install
cd backend && npm install && cd ..
```
### 4.3 Переменные окружения
**Корень проекта** — для фронтенда. Создайте `.env` или `.env.local` на основе `.env.example`:
```bash
cp .env.example .env.local
# Отредактируйте .env.local при необходимости (VITE_API_BASE_URL, Doma AI и т.д.)
```
**Бэкенд** — в `backend/.env` должны быть минимум:
```env
# Обязательно для работы БД
DATABASE_URL=postgres://mkd_user:your_password@localhost:5432/mkd_control_center
# Обязательно в production
JWT_SECRET=ваш-секретный-ключ-для-jwt
JWT_EXPIRES_IN=7d
# Опционально: Doma AI, Turnstile и т.д.
# DOMA_API_URL=...
# DOMA_API_TOKEN=...
```
Пути в конфигах (например, `path.join(__dirname, 'uploads')`) на Linux не меняют — Node использует `/` и `path.join` корректно.
## 5. Запуск
Нужны два процесса: бэкенд (API) и фронтенд (Vite).
### Вариант A: два терминала
**Терминал 1 — бэкенд:**
```bash
cd /home/its/mkd/backend
npm start
```
Должно появиться сообщение о запуске на порту 4000 (или вашем `PORT`).
**Терминал 2 — фронтенд:**
```bash
cd /home/its/mkd
npm run dev
```
Откройте в браузере: **http://localhost:3000**. Запросы к `/api` уйдут на бэкенд через прокси Vite (localhost:4000).
### Вариант B: один терминал (фоновый бэкенд)
```bash
cd /home/its/mkd/backend && npm start &
cd /home/its/mkd && npm run dev
```
### Сборка для production
```bash
cd /home/its/mkd
npm run build
```
Статика окажется в `dist/`. Раздавать её можно nginxом, указав API и `uploads` на бэкенд (порт 4000).
## 6. Проверка
| Компонент | URL / проверка |
|------------|----------------|
| Фронтенд | http://localhost:3000 |
| API бэкенд | http://localhost:4000/api (например, health, если есть) |
| PostgreSQL | `sudo -u postgres psql -c "\l"` — список баз |
## 7. Частые проблемы на Ubuntu
- **«DATABASE_URL не задана»** — добавьте `DATABASE_URL` в `backend/.env` и перезапустите бэкенд.
- **Puppeteer/Chromium не запускается** — установите зависимости из пункта 3; при необходимости в `backend` можно задать `PUPPETEER_EXECUTABLE_PATH` на системный chromium.
- **Порт 3000 или 4000 занят** — смените в `.env`: фронт — `server.port` в `vite.config.ts` или переменные Vite; бэкенд — `PORT` в `backend/.env`.
- **Права на каталог uploads** — если бэкенд пишет файлы от другого пользователя: `chmod 755 backend/uploads` (или 775 при необходимости).
После выполнения шагов 15 проект на Ubuntu 24.04 должен запускаться так же, как на Windows.

8
package-lock.json generated
View File

@@ -54,6 +54,7 @@
"integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.28.6",
"@babel/generator": "^7.28.6",
@@ -1221,6 +1222,7 @@
"integrity": "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -1305,6 +1307,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -1719,6 +1722,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@@ -1775,6 +1779,7 @@
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz",
"integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-diff": "^1.3.0",
"lodash.clonedeep": "^4.5.0",
@@ -1799,6 +1804,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -1808,6 +1814,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -2041,6 +2048,7 @@
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.4.4",

View File

@@ -0,0 +1,8 @@
#!/bin/bash
# Один раз выполните: sudo bash scripts/setup-postgres-ubuntu.sh
# Логин: mkd_user, пароль: MkdUbuntu24Secure
set -e
sudo -u postgres psql -c "DO \$\$ BEGIN CREATE USER mkd_user WITH PASSWORD 'MkdUbuntu24Secure'; EXCEPTION WHEN duplicate_object THEN ALTER USER mkd_user WITH PASSWORD 'MkdUbuntu24Secure'; END \$\$;"
sudo -u postgres psql -c "SELECT 1 FROM pg_database WHERE datname='mkd_control_center'" | grep -q 1 || sudo -u postgres psql -c "CREATE DATABASE mkd_control_center OWNER mkd_user;"
sudo -u postgres psql -d mkd_control_center -c "GRANT ALL ON SCHEMA public TO mkd_user; GRANT CREATE ON SCHEMA public TO mkd_user;"
echo "Готово. Логин: mkd_user, пароль: MkdUbuntu24Secure"

29
scripts/start-tmux.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
# Запуск бэкенда и фронтенда в tmux (сессии back и front).
# После отключения SSH процессы продолжают работать.
# Подключиться: tmux attach -t back или tmux attach -t front
# Список сессий: tmux ls
set -e
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
# Если порты заняты не tmux — освободите: kill процесс на 4000 и 3000, затем запустите скрипт снова.
echo "Останавливаем старые сессии tmux back/front..."
tmux kill-session -t back 2>/dev/null || true
tmux kill-session -t front 2>/dev/null || true
# Backend в сессии "back"
tmux new-session -d -s back -c "$ROOT/backend" "npm start"
# Frontend в сессии "front"
tmux new-session -d -s front -c "$ROOT" "npm run dev"
echo "Tmux сессии запущены:"
echo " back — бэкенд (порт 4000)"
echo " front — фронтенд (порт 3000)"
echo ""
echo "Подключиться: tmux attach -t back или tmux attach -t front"
echo "Выйти из tmux без остановки: Ctrl+B, затем D"
echo ""
echo "Доступ снаружи: http://<IP-сервера>:3000 (фронт), :4000/api (API)"

View File

@@ -8,7 +8,7 @@ export default defineConfig(({ mode }) => {
server: {
port: 3000,
host: '0.0.0.0',
allowedHosts: ['note.iieasy.ru'],
allowedHosts: true,
proxy: {
'/api': {
target: process.env.API_PROXY_TARGET || 'http://localhost:4000',