Files
goodgo-platform/apps/api/src/modules/leads/domain/entities/lead.entity.ts
Ho Ngoc Hai c920934fb6 fix(lint): enforce consistent-type-imports and fix import ordering across codebase
Auto-fix 862 lint errors: convert value imports used only as types to
`import type`, fix import group ordering in seed.ts and du-an-api.ts,
remove unused imports in auth controller, and clean up stale eslint-disable
comments referencing non-existent rules.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:13:56 +07:00

102 lines
2.8 KiB
TypeScript

import { AggregateRoot, ValidationException } from '@modules/shared';
import { LeadCreatedEvent } from '../events/lead-created.event';
import { LeadStatusChangedEvent } from '../events/lead-status-changed.event';
import { type LeadScore } from '../value-objects/lead-score.vo';
export type LeadStatus = 'NEW' | 'CONTACTED' | 'QUALIFIED' | 'NEGOTIATING' | 'CONVERTED' | 'LOST';
const VALID_TRANSITIONS: Record<LeadStatus, LeadStatus[]> = {
NEW: ['CONTACTED', 'LOST'],
CONTACTED: ['QUALIFIED', 'LOST'],
QUALIFIED: ['NEGOTIATING', 'LOST'],
NEGOTIATING: ['CONVERTED', 'LOST'],
CONVERTED: [],
LOST: [],
};
export interface LeadProps {
agentId: string;
name: string;
phone: string;
email: string | null;
source: string;
score: LeadScore | null;
notes: unknown;
status: LeadStatus;
}
export class LeadEntity extends AggregateRoot<string> {
private _agentId: string;
private _name: string;
private _phone: string;
private _email: string | null;
private _source: string;
private _score: LeadScore | null;
private _notes: unknown;
private _status: LeadStatus;
constructor(id: string, props: LeadProps, createdAt?: Date, updatedAt?: Date) {
super(id, createdAt);
if (updatedAt) this.updatedAt = updatedAt;
this._agentId = props.agentId;
this._name = props.name;
this._phone = props.phone;
this._email = props.email;
this._source = props.source;
this._score = props.score;
this._notes = props.notes;
this._status = props.status;
}
get agentId(): string { return this._agentId; }
get name(): string { return this._name; }
get phone(): string { return this._phone; }
get email(): string | null { return this._email; }
get source(): string { return this._source; }
get score(): LeadScore | null { return this._score; }
get notes(): unknown { return this._notes; }
get status(): LeadStatus { return this._status; }
static createNew(
id: string,
agentId: string,
name: string,
phone: string,
email: string | null,
source: string,
score: LeadScore | null,
notes: unknown,
): LeadEntity {
const lead = new LeadEntity(id, {
agentId,
name,
phone,
email,
source,
score,
notes,
status: 'NEW',
});
lead.addDomainEvent(new LeadCreatedEvent(id, agentId));
return lead;
}
updateStatus(newStatus: LeadStatus): void {
const allowed = VALID_TRANSITIONS[this._status];
if (!allowed.includes(newStatus)) {
throw new ValidationException(
`Không thể chuyển trạng thái từ ${this._status} sang ${newStatus}`,
);
}
const oldStatus = this._status;
this._status = newStatus;
this.updatedAt = new Date();
this.addDomainEvent(
new LeadStatusChangedEvent(this.id, this._agentId, oldStatus, newStatus),
);
}
}