feat: 🗃️ Add event table to schema, add EventLogger class to server

This commit is contained in:
Maxime Cannoodt 2022-08-08 22:46:50 +02:00
parent 68b65ab0e0
commit e7f17dbe4d
4 changed files with 154 additions and 0 deletions

View File

@ -0,0 +1,12 @@
-- CreateTable
CREATE TABLE "event" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"time" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"type" TEXT NOT NULL,
"success" BOOLEAN NOT NULL,
"size_bytes" INTEGER,
"purge_count" INTEGER,
"host" TEXT,
"error" TEXT,
"expire_window_days" INTEGER
);

View File

@ -17,3 +17,15 @@ model EncryptedNote {
ciphertext String
hmac String
}
model event {
id Int @id @default(autoincrement())
time DateTime @default(now())
type String
success Boolean
size_bytes Int?
purge_count Int?
host String?
error String?
expire_window_days Int?
}

View File

@ -0,0 +1,79 @@
import { describe, it, expect } from "vitest";
import EventLogger, { EventType } from "./EventLogger";
import prisma from "./client";
describe("Logging write events", () => {
it("Should write a write event to database", async () => {
const testWriteEvent = {
host: "localhost",
size_bytes: 100,
success: true,
expire_window_days: 30,
};
// Is event written successfully?
const logged = await EventLogger.writeEvent(testWriteEvent);
expect(logged).not.toBeNull();
expect(logged).toMatchObject(testWriteEvent);
// Is event in database?
const results = await prisma.event.findMany({
where: { type: EventType.WRITE },
});
expect(results.length).toBe(1);
// Are default fields populated?
expect(logged.time).not.toBeNull();
expect(logged.id).not.toBeNull();
});
it("Should log a read event to database", async () => {
const testReadEvent = {
host: "localhost",
size_bytes: 100,
success: true,
};
// Is event written successfully?
const logged = await EventLogger.readEvent({
host: "localhost",
size_bytes: 100,
success: true,
});
expect(logged).not.toBeNull();
expect(logged).toMatchObject(testReadEvent);
// Is event in database?
const results = await prisma.event.findMany({
where: { type: EventType.READ },
});
expect(results.length).toBe(1);
// Are default fields populated?
expect(logged.time).not.toBeNull();
expect(logged.id).not.toBeNull();
});
it("Should log a purge event to database", async () => {
const testPurgeEvent = {
success: true,
purge_count: 1,
size_bytes: 100,
};
// Is event written successfully?
const logged = await EventLogger.purgeEvent(testPurgeEvent);
expect(logged).not.toBeNull();
expect(logged).toMatchObject(testPurgeEvent);
// Is event in database?
const results = await prisma.event.findMany({
where: { type: EventType.PURGE },
});
expect(results.length).toBe(1);
// Are default fields populated?
expect(logged.time).not.toBeNull();
expect(logged.id).not.toBeNull();
});
});

51
server/src/EventLogger.ts Normal file
View File

@ -0,0 +1,51 @@
import prisma from "./client";
import { event } from "@prisma/client";
export enum EventType {
WRITE = "WRITE",
READ = "READ",
PURGE = "PURGE",
}
interface Event {
success: boolean;
error?: string;
}
interface ClientEvent extends Event {
host: string;
size_bytes: number;
success: boolean;
}
interface WriteEvent extends ClientEvent {
expire_window_days: number;
}
interface ReadEvent extends ClientEvent {}
interface PurgeEvent extends Event {
success: boolean;
purge_count: number;
size_bytes: number;
}
export default class EventLogger {
public static writeEvent(event: WriteEvent): Promise<event> {
return prisma.event.create({
data: { type: EventType.WRITE, ...event },
});
}
public static readEvent(event: ReadEvent): Promise<event> {
return prisma.event.create({
data: { type: EventType.READ, ...event },
});
}
public static purgeEvent(event: PurgeEvent): Promise<event> {
return prisma.event.create({
data: { type: EventType.PURGE, ...event },
});
}
}