import { Injectable } from '@nestjs/common' import { InjectModel } from '@nestjs/mongoose' import { Model, Types } from 'mongoose' import { AuditService, type AuditActor } from '../audit/audit.service.js' import { PartnerBranding, PartnerBrandingDocument, } from '../schemas/partner-branding.schema.js' import type { PartnerBrandingDto } from './dto/partner-branding.dto.js' @Injectable() export class PartnerBrandingService { constructor( @InjectModel(PartnerBranding.name) private readonly model: Model, private readonly audit: AuditService, ) {} // Return the partner's branding doc, or a default-shaped (unsaved) doc so the // portal always has a stable shape to render before anything is saved. async get( partnerId: string | Types.ObjectId, ): Promise { const existing = await this.model.findOne({ partnerId }).exec() if (existing) return existing // No saved branding yet — return a default-shaped plain object (no persisted // _id) so the portal renders a stable shape without mistaking it for a // saved document. return { partnerId: new Types.ObjectId(String(partnerId)), identity: {}, customerDefaults: [], emailTemplates: [], } } // Full replace (upsert) of the partner's branding. The page edits the whole // object and PUTs it back. async put( partnerId: string | Types.ObjectId, dto: PartnerBrandingDto, actor?: AuditActor, ): Promise { const updated = await this.model .findOneAndUpdate( { partnerId }, { $set: { identity: dto.identity ?? {}, customerDefaults: dto.customerDefaults ?? [], emailTemplates: dto.emailTemplates ?? [], }, }, { new: true, upsert: true, runValidators: true, setDefaultsOnInsert: true }, ) .exec() void this.audit.record( { action: 'partner.branding_updated', resourceType: 'partner', resourceId: String(partnerId), metadata: { templates: dto.emailTemplates?.length ?? 0, defaults: dto.customerDefaults?.length ?? 0, }, }, actor, ) return updated! } }