https://project.mdnd-it.cc/work_packages/94
This commit is contained in:
2025-08-23 04:25:28 +02:00
parent 725516ad6c
commit 19cfa031d0
25823 changed files with 1095586 additions and 2801759 deletions
@@ -0,0 +1,9 @@
import { ContactType } from '../../../Domain/Contact/ContactAggregate';
export interface CreateContactCommand {
name: string;
email: string;
userid?: string;
type: ContactType;
txt: string;
}
@@ -0,0 +1,26 @@
import { IContactRepository } from '../../../Domain/IRepository/IContactRepository';
import { CreateContactCommand } from './CreateContactCommand';
import { ShortContactDto } from '../../DTOs/ContactDto';
import { ContactAggregate, ContactState } from '../../../Domain/Contact/ContactAggregate';
import { ContactMapper } from '../../DTOs/Mappers/ContactMapper';
export class CreateContactCommandHandler {
constructor(private readonly contactRepo: IContactRepository) {}
async execute(cmd: CreateContactCommand): Promise<ShortContactDto> {
try {
const contact = new ContactAggregate();
contact.name = cmd.name;
contact.email = cmd.email;
contact.userid = cmd.userid || null;
contact.type = cmd.type;
contact.txt = cmd.txt;
contact.state = ContactState.ACTIVE;
const created = await this.contactRepo.create(contact);
return ContactMapper.toShortDto(created);
} catch (error) {
throw new Error('Failed to create contact');
}
}
}
@@ -0,0 +1,4 @@
export interface DeleteContactCommand {
id: string;
hard?: boolean; // true for permanent delete, false/undefined for soft delete
}
@@ -0,0 +1,42 @@
import { IContactRepository } from '../../../Domain/IRepository/IContactRepository';
import { DeleteContactCommand } from './DeleteContactCommand';
import { AdminAuditService } from '../../Services/AdminBypassService';
import { logRequest } from '../../Services/Logger';
export class DeleteContactCommandHandler {
constructor(private readonly contactRepo: IContactRepository) {}
async execute(cmd: DeleteContactCommand): Promise<boolean> {
try {
const existingContact = await this.contactRepo.findById(cmd.id);
if (!existingContact) {
throw new Error('Contact not found');
}
if (cmd.hard) {
// Permanent delete
await this.contactRepo.delete(cmd.id);
logRequest('Contact hard deleted', undefined, undefined, {
contactId: cmd.id,
contactEmail: existingContact.email,
deleteType: 'hard'
});
} else {
// Soft delete (default)
await this.contactRepo.softDelete(cmd.id);
logRequest('Contact soft deleted', undefined, undefined, {
contactId: cmd.id,
contactEmail: existingContact.email,
deleteType: 'soft'
});
}
return true;
} catch (error) {
if (error instanceof Error && error.message === 'Contact not found') {
throw error;
}
throw new Error('Failed to delete contact');
}
}
}
@@ -0,0 +1,6 @@
export interface UpdateContactCommand {
id: string;
adminResponse?: string;
state?: number;
respondedBy?: string;
}
@@ -0,0 +1,45 @@
import { IContactRepository } from '../../../Domain/IRepository/IContactRepository';
import { UpdateContactCommand } from './UpdateContactCommand';
import { DetailContactDto } from '../../DTOs/ContactDto';
import { ContactMapper } from '../../DTOs/Mappers/ContactMapper';
import { ContactState } from '../../../Domain/Contact/ContactAggregate';
export class UpdateContactCommandHandler {
constructor(private readonly contactRepo: IContactRepository) {}
async execute(cmd: UpdateContactCommand): Promise<DetailContactDto> {
try {
const existingContact = await this.contactRepo.findById(cmd.id);
if (!existingContact) {
throw new Error('Contact not found');
}
const updateData: any = {};
if (cmd.adminResponse !== undefined) {
updateData.adminResponse = cmd.adminResponse;
updateData.responseDate = new Date();
}
if (cmd.state !== undefined) {
updateData.state = cmd.state;
}
if (cmd.respondedBy !== undefined) {
updateData.respondedBy = cmd.respondedBy;
}
const updated = await this.contactRepo.update(cmd.id, updateData);
if (!updated) {
throw new Error('Failed to update contact');
}
return ContactMapper.toDetailDto(updated);
} catch (error) {
if (error instanceof Error && error.message === 'Contact not found') {
throw error;
}
throw new Error('Failed to update contact');
}
}
}
@@ -0,0 +1,3 @@
export interface GetContactByIdQuery {
id: string;
}
@@ -0,0 +1,16 @@
import { IContactRepository } from '../../../Domain/IRepository/IContactRepository';
import { GetContactByIdQuery } from './GetContactByIdQuery';
import { DetailContactDto } from '../../DTOs/ContactDto';
import { ContactMapper } from '../../DTOs/Mappers/ContactMapper';
export class GetContactByIdQueryHandler {
constructor(private readonly contactRepo: IContactRepository) {}
async execute(query: GetContactByIdQuery): Promise<DetailContactDto | null> {
const contact = await this.contactRepo.findById(query.id);
if (!contact) {
return null;
}
return ContactMapper.toDetailDto(contact);
}
}
@@ -0,0 +1,4 @@
export interface GetContactsByPageQuery {
from: number;
to: number;
}
@@ -0,0 +1,18 @@
import { IContactRepository } from '../../../Domain/IRepository/IContactRepository';
import { GetContactsByPageQuery } from './GetContactsByPageQuery';
import { ContactPageDto } from '../../DTOs/ContactDto';
import { ContactMapper } from '../../DTOs/Mappers/ContactMapper';
export class GetContactsByPageQueryHandler {
constructor(private readonly contactRepo: IContactRepository) {}
async execute(query: GetContactsByPageQuery): Promise<ContactPageDto> {
const result = await this.contactRepo.findByPage(query.from, query.to);
return {
contacts: ContactMapper.toShortDtoList(result.contacts),
totalCount: result.totalCount,
from: query.from,
to: query.to,
};
}
}