Настройка запуска на 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>
This commit is contained in:
@@ -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 и др.)
|
||||
*/
|
||||
|
||||
6
backend/package-lock.json
generated
6
backend/package-lock.json
generated
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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 проверена/создана'))
|
||||
|
||||
Reference in New Issue
Block a user