import mongoose from "mongoose"; import { AuthenticatedUser } from "../auth"; import { getFilterObject, getSortObject, PageQueryParams } from "../pagination"; import { ChangeEvent, dbEvents } from "../realtime"; import { generateId } from "../utils/id"; import { CreateOrgInput, orgFields, orgModel, UpdateOrgInput, } from "./organization.schema"; export async function createOrg(input: CreateOrgInput, tenantId: string) { const org = await orgModel.create({ tenantId: tenantId, pid: generateId(), createdAt: new Date(), ...input, }); dbEvents.emit( "change", { tenantId: tenantId, type: "insert", collection: "orgs", document: org, } as ChangeEvent, ["org:read"] ); return org; } export async function getOrg(orgId: string, tenantId: string) { return await orgModel.findOne({ $and: [{ tenantId: tenantId }, { pid: orgId }], }); } export async function listOrgs( params: PageQueryParams, user: AuthenticatedUser ) { const page = params.page || 1; const pageSize = params.pageSize || 10; const sortObj = getSortObject(params, orgFields); const filterObj = getFilterObject(params) || []; if (user.role === "client") { filterObj.push({ $or: [ { type: "county" }, { _id: new mongoose.Types.ObjectId(user.orgId) }, ], }); } const orgs = await orgModel.aggregate([ { $match: { $and: [{ tenantId: user.tenantId }, ...filterObj] } }, { $facet: { metadata: [{ $count: "count" }], data: [ { $sort: sortObj }, { $skip: (page - 1) * pageSize }, { $limit: pageSize }, ], }, }, ]); if (orgs[0].data.length === 0) return { orgs: [], metadata: { count: 0, page, pageSize } }; return { orgs: orgs[0].data, metadata: { count: orgs[0].metadata[0].count, page, pageSize, }, }; } export async function updateOrg( input: UpdateOrgInput, orgId: string, tenantId: string ) { const updateOrgResult = await orgModel.findOneAndUpdate( { $and: [{ tenantId: tenantId }, { pid: orgId }], }, { ...input, updatedAt: new Date() }, { new: true } ); if (updateOrgResult) { dbEvents.emit( "change", { tenantId: tenantId, type: "update", collection: "orgs", document: updateOrgResult, } as ChangeEvent, ["org:read"] ); } return updateOrgResult; } export async function deleteOrg(orgId: string, tenantId: string) { const res = await orgModel.deleteOne({ $and: [{ tenantId: tenantId }, { pid: orgId }], }); if (res.deletedCount > 0) { dbEvents.emit( "change", { tenantId: tenantId, type: "delete", collection: "orgs", document: { pid: orgId, }, } as ChangeEvent, ["org:read"] ); } return res; } export async function searchOrgs( params: PageQueryParams, user: AuthenticatedUser ) { const page = params.page || 1; const pageSize = params.pageSize || 10; const sortObj = getSortObject(params, orgFields); const filterObj = getFilterObject(params) || []; if (user.role === "client") { filterObj.push({ $or: [ { type: "county" }, { _id: new mongoose.Types.ObjectId(user.orgId) }, ], }); } if (!params.searchToken) return { orgs: [], metadata: { count: 0, page, pageSize } }; const regex = new RegExp(params.searchToken, "i"); const orgs = await orgModel.aggregate([ { $match: { $and: [{ tenantId: user.tenantId }, ...filterObj] } }, { $match: { $or: [{ name: { $regex: regex } }, { domain: { $regex: regex } }], }, }, { $facet: { metadata: [{ $count: "count" }], data: [ { $sort: sortObj }, { $skip: (page - 1) * pageSize }, { $limit: pageSize }, ], }, }, ]); if (orgs[0].data.length === 0) return { orgs: [], metadata: { count: 0, page, pageSize } }; return { orgs: orgs[0].data, metadata: { count: orgs[0].metadata[0].count, page, pageSize, }, }; } export async function getUniqueValuesOrg(field: string, tenenatId: string) { return await orgModel.distinct(field, { tenantId: tenenatId }); }