store events into a collection

This commit is contained in:
2025-07-23 09:54:02 +05:30
parent 089c034dd6
commit 05abf66d66
7 changed files with 86 additions and 1 deletions

View File

@@ -0,0 +1,28 @@
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { getEvents } from "./events.service";
export async function eventRoutes(fastify: FastifyInstance) {
fastify.get(
"/events",
{
schema: {
querystring: {
type: "object",
properties: {
from: { type: "string" },
},
},
},
},
async (req: FastifyRequest, res: FastifyReply) => {
const { from } = req.query as { from: string };
const fmtfrom = new Date(from);
if (from && isNaN(fmtfrom.getTime()))
return res.code(400).send({ error: "invalid date" });
const events = await getEvents(req.user, from ? fmtfrom : null);
return res.code(200).send(events);
}
);
}

View File

@@ -0,0 +1,14 @@
import mongoose from "mongoose";
export const eventsModel = mongoose.model(
"event",
new mongoose.Schema({
tenantId: String,
pid: String,
type: String,
collection: String,
orgId: String,
document: Object,
createdAt: Date,
}).index({ createdAt: 1 })
);

View File

@@ -0,0 +1,26 @@
import { AuthenticatedUser } from "../auth";
import { ChangeEvent } from "../realtime";
import { generateId } from "../utils/id";
import { eventsModel } from "./events.schema";
export async function createEvent(event: ChangeEvent) {
const eventsCount = await eventsModel.countDocuments();
if (eventsCount >= 100) {
await eventsModel.deleteOne({}, { sort: { createdAt: 1 } });
}
await eventsModel.create({
pid: generateId(),
createdAt: new Date(),
...event,
});
}
export async function getEvents(user: AuthenticatedUser, from?: Date) {
const filter: any[] = [{ tenantId: user.tenantId }];
if (user.role == "client") filter.push({ orgId: user.orgId });
if (from) filter.push({ createdAt: { $gt: from } });
return await eventsModel.find({ $and: filter }).sort({ createdAt: -1 });
}

View File

@@ -21,6 +21,7 @@ export async function createOrg(input: CreateOrgInput, tenantId: string) {
dbEvents.emit(
"change",
{
tenantId: tenantId,
type: "insert",
collection: "orgs",
document: org,
@@ -99,6 +100,7 @@ export async function updateOrg(
dbEvents.emit(
"change",
{
tenantId: tenantId,
type: "update",
collection: "orgs",
document: updateOrgResult,
@@ -119,6 +121,7 @@ export async function deleteOrg(orgId: string, tenantId: string) {
dbEvents.emit(
"change",
{
tenantId: tenantId,
type: "delete",
collection: "orgs",
document: {

View File

@@ -36,8 +36,10 @@ export async function createPermit(
dbEvents.emit(
"change",
{
tenantId: user.tenantId,
type: "insert",
collection: "permits",
orgId: permit.client.toString(),
document: permit,
} as ChangeEvent,
["permit:read"]
@@ -223,8 +225,11 @@ export async function updatePermit(
dbEvents.emit(
"change",
{
tenantId: user.tenantId,
type: "update",
collection: "permits",
//@ts-ignore
orgId: updatePermitResult.client._id.toString(),
document: updatePermitResult,
} as ChangeEvent,
["permit:read"]
@@ -242,6 +247,7 @@ export async function deletePermit(permitId: string, tenantId: string) {
dbEvents.emit(
"change",
{
tenantId: tenantId,
type: "delete",
collection: "permits",
document: {

View File

@@ -1,8 +1,11 @@
import { EventEmitter } from "stream";
import { createEvent } from "./events/events.service";
export type ChangeEvent = {
tenantId: string;
type: "insert" | "update" | "delete";
collection: "permits" | "orgs";
orgId?: string;
document?: Object;
};
@@ -21,3 +24,7 @@ export type AlertEvent = {
};
export const dbEvents = new EventEmitter();
dbEvents.on("change", async (event: ChangeEvent) => {
await createEvent(event);
});

View File

@@ -17,6 +17,7 @@ import { ctaskRoutes } from "./ctask/ctask.route";
import { paymentRoutes } from "./payments/payment.route";
import { alertRoutes } from "./alert/alert.route";
import { analyticsRoutes } from "./analytics/analytics.routes";
import { eventRoutes } from "./events/events.route";
export default async function routes(fastify: FastifyInstance) {
fastify.addHook("preHandler", authHandler);
@@ -36,5 +37,5 @@ export default async function routes(fastify: FastifyInstance) {
fastify.register(paymentRoutes, { prefix: "/payments" });
fastify.register(alertRoutes, { prefix: "/alerts" });
fastify.register(analyticsRoutes, { prefix: "/analytics" });
fastify.register(realTimeRoutes);
fastify.register(eventRoutes);
}