You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

64 lines
2.2 KiB

/**
* Кто видит тест: автор цепочки и пользователи с назначением (target user = clinic user id).
*/
import { isTestAuthor } from '../config/devAuthor.js';
import { query } from '../db/db.js';
/**
* @param {string} userId
* @param {string} testId
* @returns {Promise<{ ok: boolean, isAuthor: boolean, notFound: boolean }>}
*/
export async function userHasTestAccess(userId, testId) {
const { rows } = await query(
`SELECT t.created_by FROM tests t WHERE t.id = $1`,
[testId]
);
if (!rows.length) {
return { ok: false, isAuthor: false, notFound: true };
}
if (isTestAuthor(rows[0].created_by, userId)) {
return { ok: true, isAuthor: true, notFound: false };
}
const { rows: ar } = await query(
`SELECT 1
FROM test_assignments ta
INNER JOIN test_versions tv_a ON tv_a.id = ta.test_version_id
INNER JOIN test_assignment_targets tat ON tat.assignment_id = ta.id
WHERE tv_a.test_id = $1
AND tat.target_type = 'user'
AND tat.target_id = $2
LIMIT 1`,
[testId, userId]
);
return { ok: ar.length > 0, isAuthor: false, notFound: false };
}
/**
* Список тестов в каталоге: только `is_active` цепочка + (автор OR назначен).
*/
export async function queryTestsVisibleToUser(userId) {
return query(
`SELECT DISTINCT t.id, t.title, t.description, t.is_active AS chain_active,
t.created_at, t.updated_at, tv.id AS active_version_id, tv.version,
t.created_by, u.full_name AS author_full_name
FROM tests t
INNER JOIN test_versions tv ON tv.test_id = t.id AND tv.is_active = true
INNER JOIN users u ON u.id = t.created_by
WHERE t.is_active = true
AND (
t.created_by = $1
OR EXISTS (
SELECT 1
FROM test_assignments ta
INNER JOIN test_versions tv2 ON tv2.id = ta.test_version_id
INNER JOIN test_assignment_targets tat ON tat.assignment_id = ta.id
WHERE tv2.test_id = t.id
AND tat.target_type = 'user'
AND tat.target_id = $1
)
)
ORDER BY t.updated_at DESC NULLS LAST, t.created_at DESC`,
[userId]
);
}