96 lines
2.8 KiB
TypeScript
96 lines
2.8 KiB
TypeScript
import type EventEmitter from 'node:events'
|
|
import type { Knex } from 'knex'
|
|
import _ from 'lodash'
|
|
|
|
import RestQueriesFactory from '../../lib/knex_rest_queries.ts'
|
|
|
|
import type { NewAdmission } from './types.ts'
|
|
|
|
export const columns = ['id', 'regex', 'createdAt', 'createdById', 'modifiedAt', 'modifiedById']
|
|
|
|
export const Selects = (knex: Knex) => ({
|
|
roles: knex
|
|
.select(knex.raw('json_agg(roles)'))
|
|
.from(
|
|
knex
|
|
.select('id', 'name')
|
|
.from('role')
|
|
.innerJoin('admissions_roles', 'role.id', 'admissions_roles.role_id')
|
|
.where('admissions_roles.admission_id', knex.ref('admission.id'))
|
|
.orderBy('name')
|
|
.as('roles'),
|
|
),
|
|
|
|
createdBy: knex
|
|
.select(knex.raw('row_to_json("user")'))
|
|
.from(knex.select('id', 'email').from('user').where('id', knex.ref('admission.created_by_id')).as('user')),
|
|
})
|
|
|
|
export default ({ knex, emitter }: { emitter: EventEmitter; knex: Knex }) => {
|
|
const selects = Selects(knex)
|
|
const queries = RestQueriesFactory({
|
|
knex,
|
|
emitter,
|
|
table: 'admission',
|
|
columns,
|
|
selects,
|
|
})
|
|
|
|
return {
|
|
...queries,
|
|
|
|
create(json: NewAdmission, client = knex) {
|
|
return client.transaction(async (trx) => {
|
|
const admission = await queries.create(_.omit(json, 'roles'), trx)
|
|
|
|
const roles = json.roles.map((role) => ({
|
|
admission_id: admission.id,
|
|
role_id: role,
|
|
}))
|
|
|
|
await trx.table('admissions_roles').insert(roles)
|
|
|
|
return queries.findById(admission.id, trx)
|
|
})
|
|
},
|
|
|
|
update(id: number, json: NewAdmission, client = knex) {
|
|
return client.transaction(async (trx) => {
|
|
await queries.update(id, _.omit(json, ['roles']), trx)
|
|
|
|
// TODO decide how to handle this, ie should an empty array delete all?
|
|
if (json.roles?.length) {
|
|
await trx.table('admissions_roles').delete().where('admission_id', id).whereNotIn('role_id', json.roles)
|
|
|
|
await trx.raw(
|
|
`INSERT INTO admissions_roles(admission_id, role_id)
|
|
SELECT :admissionId, role_ids FROM unnest(:roleIds::int[]) AS role_ids WHERE NOT EXISTS
|
|
(SELECT 1 FROM admissions_roles WHERE admission_id = :admissionId AND role_id = role_ids)`,
|
|
{ admissionId: id, roleIds: json.roles },
|
|
)
|
|
}
|
|
|
|
return queries.findById(id, trx)
|
|
})
|
|
},
|
|
|
|
findMatches(email: string, client = knex) {
|
|
return client('admission')
|
|
.select([...columns, selects])
|
|
.then((admissions) => {
|
|
if (admissions) {
|
|
admissions = admissions.filter((admission) => {
|
|
const regex = new RegExp(admission.regex)
|
|
|
|
return regex.test(email)
|
|
})
|
|
|
|
// if (!admissions.length) admissions = undefined
|
|
}
|
|
|
|
return admissions
|
|
})
|
|
},
|
|
}
|
|
}
|