import { CLEAR_COMPANYHISTORY_USER as MSSQL_CLEAR_COMPANYHISTORY, CLEAR_ENTITYHISTORY_USER as MSSQL_CLEAR_ENTITYHISTORY, CLEAR_SELECTED_COMPANY as MSSQL_CLEAR_SELECTED, COUNT_ADMINS as MSSQL_COUNT_ADMINS, DELETE as MSSQL_DELETE, GET_IN_COMPANY as MSSQL_GET, } from '../../providers/mssql/queries/companyuser.js'; import { CLEAR_COMPANYHISTORY_USER as SQLITE_CLEAR_COMPANYHISTORY, CLEAR_ENTITYHISTORY_USER as SQLITE_CLEAR_ENTITYHISTORY, CLEAR_SELECTED_COMPANY as SQLITE_CLEAR_SELECTED, COUNT_ADMINS as SQLITE_COUNT_ADMINS, DELETE as SQLITE_DELETE, GET_IN_COMPANY as SQLITE_GET, } from '../../providers/sqlite3/queries/companyuser.js'; import requireAdmin from './requireAdmin.js'; import withTransaction from './withTransaction.js'; export default function remove(provider) { const isSqlite = provider?.dialect === 'sqlite3'; const pick = (mssql, sqlite) => (isSqlite ? sqlite : mssql); const getSql = pick(MSSQL_GET, SQLITE_GET); const countSql = pick(MSSQL_COUNT_ADMINS, SQLITE_COUNT_ADMINS); const deleteSql = pick(MSSQL_DELETE, SQLITE_DELETE); const clearEntityHistorySql = pick(MSSQL_CLEAR_ENTITYHISTORY, SQLITE_CLEAR_ENTITYHISTORY); const clearCompanyHistorySql = pick(MSSQL_CLEAR_COMPANYHISTORY, SQLITE_CLEAR_COMPANYHISTORY); const clearSelectedSql = pick(MSSQL_CLEAR_SELECTED, SQLITE_CLEAR_SELECTED); const admin = requireAdmin(provider); /** * Removes a member from the admin's selected company. History entries keep * existing but lose their author link; if the removed user had this company * selected, their selection is cleared. * * @param {number} googleAuthId - The id of the acting Google auth user (must be admin of the selected company). * @param {number} id - The company user id to remove. * @param {object} [tx] - Optional transaction to run within. * @returns {Promise<{id: number, googleAuthId: number}>} The removed company user. * @throws {Error} 'Not authorized', 'Company user not found', 'Cannot remove the last admin' * * @example * await store.companyuser.remove(42, 7); */ return async (googleAuthId, id, tx) => withTransaction(provider, tx, async (runner) => { const { companyId } = await admin(googleAuthId, runner); const member = (await runner.query(getSql, { id, companyId })).rows[0]; if (!member) throw new Error('Company user not found'); if (member.role === 'admin') { const { count } = (await runner.query(countSql, { companyId })).rows[0]; if (Number(count) <= 1) throw new Error('Cannot remove the last admin'); } await runner.query(clearEntityHistorySql, { id }); await runner.query(clearCompanyHistorySql, { id }); await runner.query(clearSelectedSql, { googleAuthId: member.googleAuthId, companyId }); await runner.query(deleteSql, { id }); return { id: member.id, googleAuthId: member.googleAuthId }; }); }