/** * AuditLog Entity * * Tracks all important actions in the system for security and compliance * * Business Rules: * - Every sensitive action must be logged * - Audit logs are immutable (cannot be edited or deleted) * - Must capture user, action, resource, and timestamp * - Support filtering and searching for compliance audits */ export enum AuditAction { // Booking actions BOOKING_CREATED = 'booking_created', BOOKING_UPDATED = 'booking_updated', BOOKING_CANCELLED = 'booking_cancelled', BOOKING_STATUS_CHANGED = 'booking_status_changed', // User actions USER_LOGIN = 'user_login', USER_LOGOUT = 'user_logout', USER_CREATED = 'user_created', USER_UPDATED = 'user_updated', USER_DELETED = 'user_deleted', USER_ROLE_CHANGED = 'user_role_changed', // Organization actions ORGANIZATION_CREATED = 'organization_created', ORGANIZATION_UPDATED = 'organization_updated', // Document actions DOCUMENT_UPLOADED = 'document_uploaded', DOCUMENT_DOWNLOADED = 'document_downloaded', DOCUMENT_DELETED = 'document_deleted', // Rate actions RATE_SEARCHED = 'rate_searched', // Export actions DATA_EXPORTED = 'data_exported', // Settings actions SETTINGS_UPDATED = 'settings_updated', } export enum AuditStatus { SUCCESS = 'success', FAILURE = 'failure', WARNING = 'warning', } export interface AuditLogProps { id: string; action: AuditAction; status: AuditStatus; userId: string; userEmail: string; organizationId: string; resourceType?: string; // e.g., 'booking', 'user', 'document' resourceId?: string; resourceName?: string; metadata?: Record; // Additional context ipAddress?: string; userAgent?: string; errorMessage?: string; timestamp: Date; } export class AuditLog { private readonly props: AuditLogProps; private constructor(props: AuditLogProps) { this.props = props; } /** * Factory method to create a new audit log entry */ static create(props: Omit & { id: string }): AuditLog { return new AuditLog({ ...props, timestamp: new Date(), }); } /** * Factory method to reconstitute from persistence */ static fromPersistence(props: AuditLogProps): AuditLog { return new AuditLog(props); } // Getters get id(): string { return this.props.id; } get action(): AuditAction { return this.props.action; } get status(): AuditStatus { return this.props.status; } get userId(): string { return this.props.userId; } get userEmail(): string { return this.props.userEmail; } get organizationId(): string { return this.props.organizationId; } get resourceType(): string | undefined { return this.props.resourceType; } get resourceId(): string | undefined { return this.props.resourceId; } get resourceName(): string | undefined { return this.props.resourceName; } get metadata(): Record | undefined { return this.props.metadata; } get ipAddress(): string | undefined { return this.props.ipAddress; } get userAgent(): string | undefined { return this.props.userAgent; } get errorMessage(): string | undefined { return this.props.errorMessage; } get timestamp(): Date { return this.props.timestamp; } /** * Check if action was successful */ isSuccessful(): boolean { return this.props.status === AuditStatus.SUCCESS; } /** * Check if action failed */ isFailed(): boolean { return this.props.status === AuditStatus.FAILURE; } /** * Convert to plain object */ toObject(): AuditLogProps { return { ...this.props, metadata: this.props.metadata ? { ...this.props.metadata } : undefined, }; } }