Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createContainer } from "@calcom/features/di/di";
import type { BookingAuditProducerService } from "@calcom/features/booking-audit/lib/service/BookingAuditProducerService.interface";

import {
moduleLoader as bookingAuditTaskerProducerServiceModule,
} from "./BookingAuditTaskerProducerService.module";

const container = createContainer();

export function getBookingAuditProducerService() {
bookingAuditTaskerProducerServiceModule.loadModule(container);

return container.get<BookingAuditProducerService>(bookingAuditTaskerProducerServiceModule.token);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createContainer } from "@calcom/features/di/di";
import type { BookingAuditTaskConsumer } from "@calcom/features/booking-audit/lib/service/BookingAuditTaskConsumer";

import {
moduleLoader as bookingAuditTaskConsumerModule,
} from "./BookingAuditTaskConsumer.module";

const container = createContainer();

export function getBookingAuditTaskConsumer() {
bookingAuditTaskConsumerModule.loadModule(container);

return container.get<BookingAuditTaskConsumer>(bookingAuditTaskConsumerModule.token);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { BookingAuditTaskConsumer } from "@calcom/features/booking-audit/lib/service/BookingAuditTaskConsumer";
import { BOOKING_AUDIT_DI_TOKENS } from "@calcom/features/booking-audit/di/tokens";
import { moduleLoader as bookingAuditRepositoryModuleLoader } from "@calcom/features/booking-audit/di/BookingAuditRepository.module";
import { moduleLoader as auditActorRepositoryModuleLoader } from "@calcom/features/booking-audit/di/AuditActorRepository.module";
import { moduleLoader as featuresRepositoryModuleLoader } from "@calcom/features/di/modules/Features";

import { createModule, bindModuleToClassOnToken } from "../../di/di";

export const bookingAuditTaskConsumerModule = createModule();
const token = BOOKING_AUDIT_DI_TOKENS.BOOKING_AUDIT_TASK_CONSUMER;
const moduleToken = BOOKING_AUDIT_DI_TOKENS.BOOKING_AUDIT_TASK_CONSUMER_MODULE;

const loadModule = bindModuleToClassOnToken({
module: bookingAuditTaskConsumerModule,
moduleToken,
token,
classs: BookingAuditTaskConsumer,
depsMap: {
bookingAuditRepository: bookingAuditRepositoryModuleLoader,
auditActorRepository: auditActorRepositoryModuleLoader,
featuresRepository: featuresRepositoryModuleLoader,
},
});

export const moduleLoader = {
token,
loadModule
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { BookingAuditTaskerProducerService } from "@calcom/features/booking-audit/lib/service/BookingAuditTaskerProducerService";
import { BOOKING_AUDIT_DI_TOKENS } from "@calcom/features/booking-audit/di/tokens";
import { moduleLoader as taskerModuleLoader } from "@calcom/features/di/shared/services/tasker.service";

import { createModule, bindModuleToClassOnToken } from "../../di/di";

export const bookingAuditProducerServiceModule = createModule();
const token = BOOKING_AUDIT_DI_TOKENS.BOOKING_AUDIT_PRODUCER_SERVICE;
const moduleToken = BOOKING_AUDIT_DI_TOKENS.BOOKING_AUDIT_PRODUCER_SERVICE_MODULE;

const loadModule = bindModuleToClassOnToken({
module: bookingAuditProducerServiceModule,
moduleToken,
token,
classs: BookingAuditTaskerProducerService,
depsMap: {
tasker: taskerModuleLoader,
},
});

export const moduleLoader = {
token,
loadModule
};
4 changes: 4 additions & 0 deletions packages/features/booking-audit/di/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ export const BOOKING_AUDIT_DI_TOKENS = {
BOOKING_AUDIT_SERVICE_MODULE: Symbol("BookingAuditServiceModule"),
BOOKING_AUDIT_VIEWER_SERVICE: Symbol("BookingAuditViewerService"),
BOOKING_AUDIT_VIEWER_SERVICE_MODULE: Symbol("BookingAuditViewerServiceModule"),
BOOKING_AUDIT_PRODUCER_SERVICE: Symbol("BookingAuditProducerService"),
BOOKING_AUDIT_PRODUCER_SERVICE_MODULE: Symbol("BookingAuditProducerServiceModule"),
BOOKING_AUDIT_TASK_CONSUMER: Symbol("BookingAuditTaskConsumer"),
BOOKING_AUDIT_TASK_CONSUMER_MODULE: Symbol("BookingAuditTaskConsumerModule"),
BOOKING_AUDIT_REPOSITORY: Symbol("BookingAuditRepository"),
BOOKING_AUDIT_REPOSITORY_MODULE: Symbol("BookingAuditRepositoryModule"),
AUDIT_ACTOR_REPOSITORY: Symbol("AuditActorRepository"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { z } from "zod";
import type { TFunction } from "next-i18next";

import { StringChangeSchema } from "../common/changeSchemas";
import { AuditActionServiceHelper } from "./AuditActionServiceHelper";
import type { IAuditActionService } from "./IAuditActionService";

/**
* Accepted Audit Action Service
* Handles ACCEPTED action with per-action versioning
*
* Version History:
* - v1: Initial schema with status
*/

export const acceptedFieldsSchemaV1 = z.object({
status: StringChangeSchema,
});

// V1 with version wrapper (data schema stored in DB)
export const acceptedDataSchemaV1 = z.object({
version: z.literal(1),
fields: acceptedFieldsSchemaV1,
});

// Union of all versions (currently just v1)
export const acceptedDataSchemaAllVersions = acceptedDataSchemaV1;

// Always points to the latest fields schema
export const acceptedFieldsSchema = acceptedFieldsSchemaV1;

export class AcceptedAuditActionService implements IAuditActionService<typeof acceptedFieldsSchemaV1> {
private helper: AuditActionServiceHelper<typeof acceptedFieldsSchema, typeof acceptedDataSchemaAllVersions>;

readonly VERSION = 1;
readonly fieldsSchemaV1 = acceptedFieldsSchemaV1;
readonly dataSchema = z.object({
version: z.literal(this.VERSION),
fields: this.fieldsSchemaV1,
});

constructor() {
this.helper = new AuditActionServiceHelper({
latestVersion: this.VERSION,
latestFieldsSchema: acceptedFieldsSchema,
allVersionsDataSchema: acceptedDataSchemaAllVersions,
});
}

parseFieldsWithLatest(input: unknown) {
return this.helper.parseFieldsWithLatest(input);
}

parseStored(data: unknown) {
return this.helper.parseStored(data);
}

getVersion(data: unknown): number {
return this.helper.getVersion(data);
}

migrateToLatest(data: unknown) {
// V1-only: validate and return as-is (no migration needed)
const validated = this.fieldsSchemaV1.parse(data);
return { isMigrated: false, latestData: validated };
}

getDisplaySummary(storedData: { version: number; fields: z.infer<typeof acceptedFieldsSchemaV1> }, t: TFunction): string {
return t('audit.accepted_booking');
}

getDisplayDetails(storedData: { version: number; fields: z.infer<typeof acceptedFieldsSchemaV1> }, _t: TFunction): Record<string, string> {
const { fields } = storedData;
return {
'Status': `${fields.status.old ?? '-'} → ${fields.status.new ?? '-'}`,
};
}
}

export type AcceptedAuditData = z.infer<typeof acceptedFieldsSchemaV1>;

Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { z } from "zod";
import type { TFunction } from "next-i18next";

import { StringArrayChangeSchema } from "../common/changeSchemas";
import { AuditActionServiceHelper } from "./AuditActionServiceHelper";
import type { IAuditActionService } from "./IAuditActionService";

/**
* Attendee Added Audit Action Service
* Handles ATTENDEE_ADDED action with per-action versioning
*
* Version History:
* - v1: Initial schema with addedAttendees
*/

export const attendeeAddedFieldsSchemaV1 = z.object({
addedAttendees: StringArrayChangeSchema,
});

// V1 with version wrapper (data schema stored in DB)
export const attendeeAddedDataSchemaV1 = z.object({
version: z.literal(1),
fields: attendeeAddedFieldsSchemaV1,
});

// Union of all versions (currently just v1)
export const attendeeAddedDataSchemaAllVersions = attendeeAddedDataSchemaV1;

// Always points to the latest fields schema

export const attendeeAddedFieldsSchema = attendeeAddedFieldsSchemaV1;

export class AttendeeAddedAuditActionService implements IAuditActionService<typeof attendeeAddedFieldsSchemaV1> {
private helper: AuditActionServiceHelper<typeof attendeeAddedFieldsSchema, typeof attendeeAddedDataSchemaAllVersions>;

readonly VERSION = 1;
readonly fieldsSchemaV1 = attendeeAddedFieldsSchemaV1;
readonly dataSchema = z.object({
version: z.literal(this.VERSION),
fields: this.fieldsSchemaV1,
});

constructor() {
this.helper = new AuditActionServiceHelper({
latestVersion: this.VERSION,
latestFieldsSchema: attendeeAddedFieldsSchema,
allVersionsDataSchema: attendeeAddedDataSchemaAllVersions,
});
}

parseFieldsWithLatest(input: unknown) {
return this.helper.parseFieldsWithLatest(input);
}

parseStored(data: unknown) {
return this.helper.parseStored(data);
}

getVersion(data: unknown): number {
return this.helper.getVersion(data);
}

migrateToLatest(data: unknown) {
// V1-only: validate and return as-is (no migration needed)
const validated = this.fieldsSchemaV1.parse(data);
return { isMigrated: false, latestData: validated };
}

getDisplaySummary(storedData: { version: number; fields: z.infer<typeof attendeeAddedFieldsSchemaV1> }, t: TFunction): string {
const { fields } = storedData;
return t('audit.added_guests', { count: fields.addedAttendees.new.length });
}

getDisplayDetails(storedData: { version: number; fields: z.infer<typeof attendeeAddedFieldsSchemaV1> }, _t: TFunction): Record<string, string> {
const { fields } = storedData;
return {
'Added Guests': fields.addedAttendees.new.join(', '),
'Count': fields.addedAttendees.new.length.toString(),
};
}
}

export type AttendeeAddedAuditData = z.infer<typeof attendeeAddedFieldsSchemaV1>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { z } from "zod";
import type { TFunction } from "next-i18next";

import { BooleanChangeSchema } from "../common/changeSchemas";
import { AuditActionServiceHelper } from "./AuditActionServiceHelper";
import type { IAuditActionService } from "./IAuditActionService";

/**
* Attendee No-Show Updated Audit Action Service
* Handles ATTENDEE_NO_SHOW_UPDATED action with per-action versioning
*
* Version History:
* - v1: Initial schema with noShowAttendee
*/

export const attendeeNoShowUpdatedFieldsSchemaV1 = z.object({
noShowAttendee: BooleanChangeSchema,
});

// V1 with version wrapper (data schema stored in DB)
export const attendeeNoShowUpdatedDataSchemaV1 = z.object({
version: z.literal(1),
fields: attendeeNoShowUpdatedFieldsSchemaV1,
});

// Union of all versions (currently just v1)
export const attendeeNoShowUpdatedDataSchemaAllVersions = attendeeNoShowUpdatedDataSchemaV1;

// Always points to the latest fields schema

export const attendeeNoShowUpdatedFieldsSchema = attendeeNoShowUpdatedFieldsSchemaV1;

export class AttendeeNoShowUpdatedAuditActionService implements IAuditActionService<typeof attendeeNoShowUpdatedFieldsSchemaV1> {
private helper: AuditActionServiceHelper<typeof attendeeNoShowUpdatedFieldsSchema, typeof attendeeNoShowUpdatedDataSchemaAllVersions>;

readonly VERSION = 1;
readonly fieldsSchemaV1 = attendeeNoShowUpdatedFieldsSchemaV1;
readonly dataSchema = z.object({
version: z.literal(this.VERSION),
fields: this.fieldsSchemaV1,
});

constructor() {
this.helper = new AuditActionServiceHelper({
latestVersion: this.VERSION,
latestFieldsSchema: attendeeNoShowUpdatedFieldsSchema,
allVersionsDataSchema: attendeeNoShowUpdatedDataSchemaAllVersions,
});
}

parseFieldsWithLatest(input: unknown) {
return this.helper.parseFieldsWithLatest(input);
}

parseStored(data: unknown) {
return this.helper.parseStored(data);
}

getVersion(data: unknown): number {
return this.helper.getVersion(data);
}

migrateToLatest(data: unknown) {
// V1-only: validate and return as-is (no migration needed)
const validated = this.fieldsSchemaV1.parse(data);
return { isMigrated: false, latestData: validated };
}

getDisplaySummary(storedData: { version: number; fields: z.infer<typeof attendeeNoShowUpdatedFieldsSchemaV1> }, t: TFunction): string {
return t('audit.attendee_no_show_updated');
}

getDisplayDetails(storedData: { version: number; fields: z.infer<typeof attendeeNoShowUpdatedFieldsSchemaV1> }, _t: TFunction): Record<string, string> {
const { fields } = storedData;
return {
'Attendee No-Show': `${fields.noShowAttendee.old ?? false} → ${fields.noShowAttendee.new}`,
};
}
}

export type AttendeeNoShowUpdatedAuditData = z.infer<typeof attendeeNoShowUpdatedFieldsSchemaV1>;
Loading
Loading