Merge pull request #3784 from bluewave-labs/chore/refactor-utils

chore: refactor utils
This commit is contained in:
Alexander Holliday authored and GitHub committed 2026-07-15 10:24:51 -07:00
commit 507b96164f
16 files changed
+89 -268

No files matched your search

@@ -1,26 +1,13 @@
import mongoose, { type UpdateQuery } from "mongoose";
import { type UpdateQuery } from "mongoose";
import { ISettingsRepository } from "@/domain/app-settings/app-settings-repository.interface.js";
import type { Settings, SettingsUpdate } from "@/domain/app-settings/app-settings.type.js";
import { AppSettingsModel, type AppSettingsDocument } from "@/domain/app-settings/app-settings.model.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
class MongoSettingsRepository implements ISettingsRepository {
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
protected toEntity = (doc: AppSettingsDocument): Settings => {
return {
id: this.toStringId(doc._id),
id: toStringId(doc._id),
checkTTL: doc.checkTTL,
language: doc.language,
jwtSecret: doc.jwtSecret ?? undefined,
@@ -41,8 +28,8 @@ class MongoSettingsRepository implements ISettingsRepository {
singleton: doc.singleton,
version: doc.version ?? 1,
globalThresholds: doc.globalThresholds ?? undefined,
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
createdAt: toDateString(doc.createdAt),
updatedAt: toDateString(doc.updatedAt),
};
};
@@ -17,6 +17,7 @@ import { CheckModel, type CheckDocument } from "@/domain/checks/check.model.js";
import mongoose from "mongoose";
import { getDateForRange } from "@/utils/dataUtils.js";
import { ILogger } from "@/utils/logger.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
import { getHardwareUpChecks, getHardwareStats, getHardwareTotalChecks } from "@/domain/checks/check.hardware.aggregations.js";
@@ -33,20 +34,6 @@ class MongoChecksRepository implements IChecksRepository {
}
private toEntity = (doc: CheckDocument): Check => {
const toStringId = (value: mongoose.Types.ObjectId | string | undefined | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
const toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
const mapTimings = (timings?: GotTimings): GotTimings => {
const phases = timings?.phases ?? {
wait: 0,
+7 -21
View File
@@ -4,36 +4,22 @@ import type { DLQItem } from "@/domain/dlq/dlq.type.js";
import type { IDLQRepository, DLQQueryFilters, DLQStatusCount } from "@/domain/dlq/dlq.repository.interface.js";
import mongoose from "mongoose";
import { AppError } from "@/utils/AppError.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
class MongoDLQRepository implements IDLQRepository {
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
protected toEntity = (doc: DLQItemDocument): DLQItem => {
return {
id: this.toStringId(doc._id),
id: toStringId(doc._id),
type: doc.type,
status: doc.status,
payload: doc.payload,
monitorId: this.toStringId(doc.monitorId),
teamId: this.toStringId(doc.teamId),
monitorId: toStringId(doc.monitorId),
teamId: toStringId(doc.teamId),
retryCount: doc.retryCount,
maxRetries: doc.maxRetries,
lastError: doc.lastError,
nextRetryAt: this.toDateString(doc.nextRetryAt),
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
nextRetryAt: toDateString(doc.nextRetryAt),
createdAt: toDateString(doc.createdAt),
updatedAt: toDateString(doc.updatedAt),
};
};
@@ -5,6 +5,7 @@ import { GeoCheckMetadataDocument, GeoCheckModel, type GeoCheckDocument } from "
import mongoose, { PipelineStage } from "mongoose";
import { getDateForRange } from "@/utils/dataUtils.js";
import { ILogger } from "@/utils/logger.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
const SERVICE_NAME = "GeoChecksRepository";
@@ -17,20 +18,6 @@ class MongoGeoChecksRepository implements IGeoChecksRepository {
}
private toEntity = (doc: GeoCheckDocument): GeoCheck => {
const toStringId = (value: mongoose.Types.ObjectId | string | undefined | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
const toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
const mapMetadata = (metadata: GeoCheckMetadataDocument): GeoCheckMetadata => ({
monitorId: toStringId(metadata.monitorId),
teamId: toStringId(metadata.teamId),
@@ -4,22 +4,9 @@ import type { Incident, IncidentSummary } from "@/domain/incidents/incident.type
import type { IIncidentsRepository } from "@/domain/incidents/incident.repository.interface.js";
import mongoose from "mongoose";
import { AppError } from "@/utils/AppError.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
class MongoIncidentsRepository implements IIncidentsRepository {
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
private buildMatchStage({
teamId,
startDate,
@@ -48,20 +35,20 @@ class MongoIncidentsRepository implements IIncidentsRepository {
protected toEntity = (doc: IncidentDocument): Incident => {
return {
id: this.toStringId(doc._id),
monitorId: this.toStringId(doc.monitorId),
teamId: this.toStringId(doc.teamId),
startTime: this.toDateString(doc.startTime),
endTime: doc.endTime ? this.toDateString(doc.endTime) : null,
id: toStringId(doc._id),
monitorId: toStringId(doc.monitorId),
teamId: toStringId(doc.teamId),
startTime: toDateString(doc.startTime),
endTime: doc.endTime ? toDateString(doc.endTime) : null,
status: doc.status,
message: doc.message ?? null,
statusCode: doc.statusCode ?? null,
resolutionType: doc.resolutionType ?? null,
resolvedBy: doc.resolvedBy ? this.toStringId(doc.resolvedBy) : null,
resolvedBy: doc.resolvedBy ? toStringId(doc.resolvedBy) : null,
resolvedByEmail: doc.resolvedByEmail ?? null,
comment: doc.comment ?? null,
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
createdAt: toDateString(doc.createdAt),
updatedAt: toDateString(doc.updatedAt),
};
};
@@ -254,22 +241,22 @@ class MongoIncidentsRepository implements IIncidentsRepository {
avgResolutionTimeHours,
topMonitor: monitorResult[0]
? {
monitorId: this.toStringId(monitorResult[0].monitorId),
monitorId: toStringId(monitorResult[0].monitorId),
monitorName: monitorResult[0].monitorName ?? null,
incidentCount: monitorResult[0].count,
}
: null,
latestIncidents: latestIncidents.map((incident) => ({
id: this.toStringId(incident._id),
monitorId: this.toStringId(incident.monitorId),
id: toStringId(incident._id),
monitorId: toStringId(incident.monitorId),
monitorName: incident.monitorName ?? null,
status: incident.status,
startTime: this.toDateString(incident.startTime),
endTime: incident.endTime ? this.toDateString(incident.endTime) : null,
startTime: toDateString(incident.startTime),
endTime: incident.endTime ? toDateString(incident.endTime) : null,
resolutionType: incident.resolutionType ?? null,
message: incident.message ?? null,
statusCode: incident.statusCode ?? null,
createdAt: this.toDateString(incident.createdAt),
createdAt: toDateString(incident.createdAt),
})),
};
};
@@ -2,34 +2,20 @@ import { IInvitesRepository } from "@/domain/invites/invite.repository.interface
import type { Invite } from "@/domain/invites/invite.type.js";
import { type InviteDocument, InviteModel } from "@/domain/invites/invite.model.js";
import { AppError } from "@/utils/AppError.js";
import mongoose from "mongoose";
import crypto from "crypto";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
class MongoInvitesRepository implements IInvitesRepository {
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
protected toEntity = (doc: InviteDocument): Invite => {
return {
id: this.toStringId(doc._id),
id: toStringId(doc._id),
email: doc.email,
teamId: this.toStringId(doc.teamId),
teamId: toStringId(doc.teamId),
role: doc.role ?? [],
token: doc.token,
expiry: this.toDateString(doc.expiry),
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
expiry: toDateString(doc.expiry),
createdAt: toDateString(doc.createdAt),
updatedAt: toDateString(doc.updatedAt),
};
};
@@ -3,22 +3,8 @@ import { type MaintenanceWindowDocument, MaintenanceWindowModel } from "@/domain
import { IMaintenanceWindowsRepository } from "./maintenance-window.repository.interface.js";
import mongoose, { SortOrder } from "mongoose";
import { AppError } from "@/utils/AppError.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
class MongoMaintenanceWindowsRepository implements IMaintenanceWindowsRepository {
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
private mapDocuments = (documents: MaintenanceWindowDocument[]): MaintenanceWindow[] => {
if (!documents?.length) {
return [];
@@ -28,18 +14,18 @@ class MongoMaintenanceWindowsRepository implements IMaintenanceWindowsRepository
private toEntity = (doc: MaintenanceWindowDocument): MaintenanceWindow => {
return {
id: this.toStringId(doc._id),
monitorIds: doc.monitorIds.map(this.toStringId),
teamId: this.toStringId(doc.teamId),
id: toStringId(doc._id),
monitorIds: doc.monitorIds.map(toStringId),
teamId: toStringId(doc.teamId),
active: doc.active,
name: doc.name,
duration: doc.duration,
durationUnit: doc.durationUnit,
repeat: doc.repeat,
start: this.toDateString(doc.start),
end: this.toDateString(doc.end),
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
start: toDateString(doc.start),
end: toDateString(doc.end),
createdAt: toDateString(doc.createdAt),
updatedAt: toDateString(doc.updatedAt),
};
};
@@ -3,19 +3,9 @@ import type { CheckResultInput, MonitorStats } from "@/domain/monitor-stats/moni
import { IMonitorStatsRepository } from "@/domain/monitor-stats/monitor-stats.repository.interface.js";
import mongoose from "mongoose";
import { AppError } from "@/utils/AppError.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
class MongoMonitorStatsRepository implements IMonitorStatsRepository {
private toEntity = (doc: MonitorStatsDocument): MonitorStats => {
const toStringId = (value: unknown): string => {
if (value instanceof mongoose.Types.ObjectId) {
return value.toString();
}
return value?.toString() ?? "";
};
const toDateString = (value: Date | string): string => {
return value instanceof Date ? value.toISOString() : value;
};
return {
id: toStringId(doc._id),
monitorId: toStringId(doc.monitorId),
@@ -6,6 +6,7 @@ import mongoose, { type FilterQuery, type PipelineStage } from "mongoose";
import { MongoBulkWriteError } from "mongodb";
import { AppError } from "@/utils/AppError.js";
import { IMonitorsRepository, TeamQueryConfig, SummaryConfig } from "@/domain/monitors/monitor.repository.interface.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
class MongoMonitorsRepository implements IMonitorsRepository {
create = async (monitor: Monitor, teamId: string, userId: string) => {
const monitorModel = new MonitorModel({ ...monitor, teamId, userId });
@@ -440,18 +441,6 @@ class MongoMonitorsRepository implements IMonitorsRepository {
};
private toEntity = (doc: MonitorDocument): Monitor => {
const toStringId = (value: unknown): string => {
if (value instanceof mongoose.Types.ObjectId) {
return value.toString();
}
return value?.toString() ?? "";
};
const toDateString = (value: Date | string): string => {
if (!value) return "";
return value instanceof Date ? value.toISOString() : value;
};
const notificationIds = (doc.notifications ?? []).map((notification) => toStringId(notification));
const tagIds = (doc.tags ?? []).map((tag) => toStringId(tag));
return {
@@ -506,10 +495,6 @@ class MongoMonitorsRepository implements IMonitorsRepository {
};
private toCheckSnapshot = (doc: CheckSnapshotDocument): CheckSnapshot => {
const toDateString = (value: Date | string): string => {
return value instanceof Date ? value.toISOString() : value;
};
return {
id: doc.id,
status: doc.status,
@@ -3,6 +3,7 @@ import { NotificationModel, type NotificationDocument } from "@/domain/notificat
import { INotificationsRepository } from "@/domain/notifications/notification.repository.interface.js";
import type { Notification } from "@/domain/notifications/notification.type.js";
import { AppError } from "@/utils/AppError.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
class MongoNotificationsRepository implements INotificationsRepository {
private mapDocuments = (documents: NotificationDocument[]): Notification[] => {
@@ -13,14 +14,6 @@ class MongoNotificationsRepository implements INotificationsRepository {
};
private toEntity = (doc: NotificationDocument): Notification => {
const toStringId = (value: mongoose.Types.ObjectId | string): string => {
return value instanceof mongoose.Types.ObjectId ? value.toString() : value;
};
const toDateString = (value: Date | string): string => {
return value instanceof Date ? value.toISOString() : value;
};
return {
id: toStringId(doc._id),
userId: toStringId(doc.userId),
@@ -2,35 +2,22 @@ import type { RecoveryToken } from "@/domain/recovery-tokens/recovery-token.type
import type { IRecoveryTokensRepository } from "./recovery-token.repository.interface.js";
import type { RecoveryTokenDocument } from "@/domain/recovery-tokens/recovery-token.model.js";
import { RecoveryTokenModel } from "@/domain/recovery-tokens/recovery-token.model.js";
import mongoose from "mongoose";
import crypto from "crypto";
import { AppError } from "@/utils/AppError.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
const SERVICE_NAME = "MongoRecoveryTokensRepository";
class MongoRecoveryTokensRepository implements IRecoveryTokensRepository {
static SERVICE_NAME = SERVICE_NAME;
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
protected toEntity = (doc: RecoveryTokenDocument): RecoveryToken => {
return {
id: this.toStringId(doc._id),
id: toStringId(doc._id),
email: doc.email,
token: doc.token,
expiry: this.toDateString(doc.expiry),
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
expiry: toDateString(doc.expiry),
createdAt: toDateString(doc.createdAt),
updatedAt: toDateString(doc.updatedAt),
};
};
@@ -4,28 +4,15 @@ import type { StatusPage, StatusPageLogo, StatusPageLogoDocument } from "@/domai
import mongoose from "mongoose";
import { AppError } from "@/utils/AppError.js";
import { normalizeStatusPageDomain } from "@/utils/statusPageDomain.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
// Type for update data that can include document-level fields (Buffer for logo)
type StatusPageUpdateData = Partial<Omit<StatusPage, "id" | "userId" | "teamId" | "logo" | "createdAt" | "updatedAt">> & {
logo?: StatusPageLogoDocument | null;
};
class MongoStatusPagesRepository implements IStatusPagesRepository {
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
private mapIdArray = (values?: Array<mongoose.Types.ObjectId | string>): string[] => {
return values?.map((value) => this.toStringId(value)) ?? [];
return values?.map((value) => toStringId(value)) ?? [];
};
private mapLogo = (logo?: StatusPageLogoDocument | null): StatusPageLogo | undefined => {
@@ -42,9 +29,9 @@ class MongoStatusPagesRepository implements IStatusPagesRepository {
private toEntity = (doc: StatusPageDocument): StatusPage => {
return {
id: this.toStringId(doc._id),
userId: this.toStringId(doc.userId),
teamId: this.toStringId(doc.teamId),
id: toStringId(doc._id),
userId: toStringId(doc.userId),
teamId: toStringId(doc.teamId),
type: doc.type,
companyName: doc.companyName,
url: doc.url,
@@ -63,8 +50,8 @@ class MongoStatusPagesRepository implements IStatusPagesRepository {
customCSS: doc.customCSS,
theme: doc.theme,
themeMode: doc.themeMode,
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
createdAt: toDateString(doc.createdAt),
updatedAt: toDateString(doc.updatedAt),
};
};
+5 -19
View File
@@ -1,36 +1,22 @@
import { ITagsRepository } from "@/domain/tags/tag.repository.interface.js";
import { Tag } from "@/domain/tags/tag.type.js";
import { TagDocument, TagModel } from "@/domain/tags/tag.model.js";
import mongoose from "mongoose";
import { AppError } from "@/utils/AppError.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
const SERVICE_NAME = "TagsRepository";
class MongoTagsRepository implements ITagsRepository {
static SERVICE_NAME = SERVICE_NAME;
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
protected toEntity = (doc: TagDocument): Tag => {
return {
id: this.toStringId(doc._id),
teamId: this.toStringId(doc.teamId),
id: toStringId(doc._id),
teamId: toStringId(doc.teamId),
name: doc.name,
color: doc.color,
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
createdAt: toDateString(doc.createdAt),
updatedAt: toDateString(doc.updatedAt),
};
};
@@ -1,29 +1,14 @@
import { Team } from "@/domain/teams/team.type.js";
import { TeamDocument, TeamModel } from "@/domain/teams/team.model.js";
import { ITeamsRepository } from "@/domain/teams/team.repository.interface.js";
import mongoose from "mongoose";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
class MongoTeamsRepository implements ITeamsRepository {
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
private toEntity = (doc: TeamDocument): Team => {
return {
id: this.toStringId(doc._id),
id: toStringId(doc._id),
email: doc.email,
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
createdAt: toDateString(doc.createdAt),
updatedAt: toDateString(doc.updatedAt),
};
};
@@ -34,7 +19,7 @@ class MongoTeamsRepository implements ITeamsRepository {
findAllTeamIds = async (): Promise<string[]> => {
const teams = await TeamModel.find({}, { _id: 1 }).lean();
return teams.map((team) => this.toStringId(team._id));
return teams.map((team) => toStringId(team._id));
};
}
@@ -1,27 +1,14 @@
import mongoose from "mongoose";
import { IUsersRepository } from "@/domain/users/user.repository.interface.js";
import { UserModel, type UserDocument } from "@/domain/users/user.model.js";
import type { User, UserProfileImage } from "@/domain/users/user.type.js";
import { GenerateAvatarImage } from "@/utils/imageProcessing.js";
import { ParseBoolean } from "@/utils/utils.js";
import { AppError } from "@/utils/AppError.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
const SERVICE_NAME = "MongoUsersRepository";
class MongoUsersRepository implements IUsersRepository {
static SERVICE_NAME = SERVICE_NAME;
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
private mapProfileImage = (image?: (UserProfileImage & { data?: Buffer }) | null) => {
if (!image) {
@@ -35,7 +22,7 @@ class MongoUsersRepository implements IUsersRepository {
protected toEntity = (doc: UserDocument): User => {
return {
id: this.toStringId(doc._id),
id: toStringId(doc._id),
firstName: doc.firstName,
lastName: doc.lastName,
email: doc.email,
@@ -45,10 +32,10 @@ class MongoUsersRepository implements IUsersRepository {
isActive: doc.isActive ?? false,
isVerified: doc.isVerified ?? false,
role: doc.role ?? [],
teamId: this.toStringId(doc.teamId),
teamId: toStringId(doc.teamId),
checkTTL: doc.checkTTL ?? undefined,
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
createdAt: toDateString(doc.createdAt),
updatedAt: toDateString(doc.updatedAt),
};
};
+15
View File
@@ -0,0 +1,15 @@
import mongoose from "mongoose";
export const toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
export const toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};