import { Inject, Injectable } from '@nestjs/common'; import { eq } from 'drizzle-orm'; import { DateTime } from '../../../common/value-objects/date-time/date-time'; import { Status } from '../../../common/value-objects/status/status'; import { DRIZZLE, type DrizzleDB } from '../../../database/database.module'; import { companySettings, type CompanySettingsRow, } from '../../../database/company-settings-table'; import type { CompanySetting, UpsertCompanySettingInput, } from './company-setting'; @Injectable() export class CompanySettingsRepository { constructor(@Inject(DRIZZLE) private readonly db: DrizzleDB) {} async find(): Promise { const rows: CompanySettingsRow[] = await this.db .select() .from(companySettings) .limit(1); const row = rows[0]; return row ? this.toDomain(row) : null; } async upsert(input: UpsertCompanySettingInput): Promise { const now = DateTime.fromUnixMs(Date.now()); const existing = await this.find(); if (!existing) { const inserted = await this.db .insert(companySettings) .values({ cycleStartDate: input.cycleStartDate.value, checkInRadiusMeters: input.checkInRadiusMeters ?? 100, gpsIntervalSeconds: input.gpsIntervalSeconds ?? 5, checkoutWarningRadiusMeters: input.checkoutWarningRadiusMeters ?? 200, status: Status.create(Status.DEFAULT).value, createdAt: now.value, updatedAt: now.value, createdBy: input.userId, updatedBy: input.userId, }) .returning(); return this.toDomain(inserted[0]); } const updated = await this.db .update(companySettings) .set({ cycleStartDate: input.cycleStartDate.value, ...(input.checkInRadiusMeters !== undefined ? { checkInRadiusMeters: input.checkInRadiusMeters } : {}), ...(input.gpsIntervalSeconds !== undefined ? { gpsIntervalSeconds: input.gpsIntervalSeconds } : {}), ...(input.checkoutWarningRadiusMeters !== undefined ? { checkoutWarningRadiusMeters: input.checkoutWarningRadiusMeters } : {}), updatedAt: now.value, updatedBy: input.userId, }) .where(eq(companySettings.id, existing.id)) .returning(); return this.toDomain(updated[0]); } private toDomain(row: CompanySettingsRow): CompanySetting { return { id: row.id, cycleStartDate: DateTime.fromUnixMs(row.cycleStartDate), checkInRadiusMeters: row.checkInRadiusMeters, gpsIntervalSeconds: row.gpsIntervalSeconds, checkoutWarningRadiusMeters: row.checkoutWarningRadiusMeters, status: Status.create(row.status), createdAt: DateTime.fromUnixMs(row.createdAt), updatedAt: DateTime.fromUnixMs(row.updatedAt), createdBy: row.createdBy, updatedBy: row.updatedBy, }; } }