import _ from 'lodash' import * as z from 'zod' import { type FastifyPluginCallbackZod } from 'fastify-type-provider-zod' import { RoleSchema } from '../../schemas/db.ts' import { jsonObjectFrom } from 'kysely/helpers/postgres' const rolesPlugin: FastifyPluginCallbackZod = (fastify, _options, done) => { const { db } = fastify fastify.addHook('onRequest', fastify.auth) fastify.route({ url: '/', method: 'GET', schema: { response: { 200: z.array( RoleSchema.extend({ createdBy: z.object({ id: z.number(), email: z.string(), }), modifiedBy: z .object({ id: z.number(), email: z.string(), }) .nullable(), }), ), }, }, handler() { return db .selectFrom('role as r') .selectAll() .select((eb) => [ jsonObjectFrom(eb.selectFrom('user as u').select(['u.id', 'u.email']).whereRef('u.id', '=', 'r.createdById')) .$notNull() .as('createdBy'), jsonObjectFrom( eb.selectFrom('user as u').select(['u.id', 'u.email']).whereRef('u.id', '=', 'r.modifiedById'), ).as('modifiedBy'), ]) .execute() }, }) fastify.route({ url: '/', method: 'POST', schema: { body: RoleSchema.pick({ name: true }), response: { 201: RoleSchema, }, }, handler(request) { return db .insertInto('role') .values({ ...request.body, createdById: request.session.userId, }) .returningAll() .executeTakeFirstOrThrow() }, }) fastify.route({ url: '/:id', method: 'DELETE', schema: { params: z.object({ id: z.number(), }), response: { 204: {}, 404: {}, }, }, handler(request) { return db.deleteFrom('role').where('id', '=', request.params.id).execute() }, }) fastify.route({ url: '/:id', method: 'PATCH', schema: { params: z.object({ id: z.number(), }), body: RoleSchema.pick({ name: true }), response: { 204: {}, }, }, async handler(request) { return db .updateTable('role') .set({ ...request.body, modifiedById: request.session.userId, }) .where('id', '=', request.params.id) .returningAll() .execute() }, }) done() } export default rolesPlugin