Files
TestingWebApp/backend/src/services/assignmentUserService.js
T
Константин Лебединский 0fe04d4d99 feat: полный бэк и фронт (попытки, разбор, импорт, ИИ, назначения)
- Сервисы: testAttemptService, testAccess, document import/gen/extract, LLM, assignment, aiEditor
- Конфиг: devAuthor, featureFlags; messages/ru; интеграция V.9 (skip без БД)
- API/роуты: app, auth, server; Dockerfile и env example
- Фронт: TestAttempt, TestAttemptReview, AttemptReviewBlock, стили, правки App/api/login/vite
- compose и README; смоук-тесты расширены

Закрывает отсутствие модулей в origin после клона.

Made-with: Cursor
2026-04-24 22:55:15 +05:00

65 lines
2.1 KiB
JavaScript

/**
* Создать/найти запись `clinic_tests.users` по staff_id (HR), чтобы назначить target_id = uuid.
*/
import { queryHr, getHrPool } from '../db/hrPool.js';
import { HR_MANAGED_PASSWORD_PLACEHOLDER } from '../config/authConstants.js';
import { RU } from '../messages/ru.js';
/**
* @param {import('pg').Pool} pool
* @param {number} staffId
* @returns {Promise<string>} uuid в clinic_tests.users
*/
export async function ensureClinicUserIdForStaff(pool, staffId) {
const n = Math.floor(Number(staffId));
if (!Number.isFinite(n) || n < 1) {
const e = new Error(RU.assignmentUserRequired);
e.status = 400;
throw e;
}
const { rows: ex } = await pool.query(
`SELECT id FROM users WHERE staff_id = $1 AND is_active = true LIMIT 1`,
[n]
);
if (ex.length) {
return ex[0].id;
}
if (!getHrPool()) {
const e = new Error('Нет HR БД: нельзя завести учётку по staff_id.');
e.status = 400;
throw e;
}
const { rows: st } = await queryHr(
`SELECT id, fio, web_login FROM staff_members WHERE id = $1`,
[n]
);
if (!st.length) {
const e = new Error('Сотрудник не найден в HR.');
e.status = 400;
throw e;
}
const fio = st[0].fio || `staff #${n}`;
const rawLogin = (st[0].web_login && String(st[0].web_login).trim()) || null;
let login = rawLogin;
if (!login) {
login = `staff_${n}@clinic.local`;
}
const { rows: taken } = await pool.query(
`SELECT 1 FROM users WHERE LOWER(TRIM(login)) = LOWER(TRIM($1)) AND (staff_id IS NULL OR staff_id <> $2) LIMIT 1`,
[login, n]
);
if (taken.length) {
login = `staff_${n}@clinic.local`;
}
const ins = await pool.query(
`INSERT INTO users (login, password_hash, full_name, role, department_id, is_active, staff_id)
VALUES ($1, $2, $3, 'employee', null, true, $4)
ON CONFLICT (staff_id) DO UPDATE SET
full_name = EXCLUDED.full_name,
is_active = true
RETURNING id`,
[login, HR_MANAGED_PASSWORD_PLACEHOLDER, fio, n]
);
return ins.rows[0].id;
}