(llm-first): context budget, validation, and eval harness, orchestration general-prompt
This commit is contained in:
145
server/src/modules/employee/employee.service.ts
Normal file
145
server/src/modules/employee/employee.service.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import type { Prisma } from '@prisma/client';
|
||||
import type { Response } from 'express';
|
||||
import { PrismaService } from '../../prisma/prisma.service';
|
||||
import { getFirst, setListHeaders, toArray, toDateValue, toDecimalValue, toNumberValue } from '../shared/query-utils';
|
||||
import { CreateEmployeeDto } from './dto/create-employee.dto';
|
||||
import { UpdateEmployeeDto } from './dto/update-employee.dto';
|
||||
|
||||
@Injectable()
|
||||
export class EmployeeService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
private toNested(item: any): Record<string, unknown> {
|
||||
return {
|
||||
id: item.code,
|
||||
code: item.code,
|
||||
fullName: item.fullName,
|
||||
role: item.role,
|
||||
position: item.position,
|
||||
bossCode: item.bossCode,
|
||||
price: item.price,
|
||||
phoneNumber: item.phoneNumber,
|
||||
};
|
||||
}
|
||||
|
||||
private toRecord(item: any): Record<string, unknown> {
|
||||
return {
|
||||
id: item.code,
|
||||
code: item.code,
|
||||
fullName: item.fullName,
|
||||
role: item.role,
|
||||
position: item.position,
|
||||
bossCode: item.bossCode,
|
||||
boss: item.boss ? this.toNested(item.boss) : null,
|
||||
subordinates: Array.isArray(item.subordinates) ? item.subordinates.map((subordinate: any) => this.toNested(subordinate)) : [],
|
||||
price: item.price,
|
||||
phoneNumber: item.phoneNumber,
|
||||
};
|
||||
}
|
||||
async findAll(query: Record<string, string | string[] | undefined>, response: Response): Promise<Record<string, unknown>[]> {
|
||||
const start = Number(getFirst(query._start) ?? 0);
|
||||
const end = Number(getFirst(query._end) ?? start + 25);
|
||||
const take = Math.max(end - start, 0) || 25;
|
||||
const where: Record<string, unknown> = {};
|
||||
const q = getFirst(query.q);
|
||||
if (q) {
|
||||
where.OR = [
|
||||
{ code: { contains: q, mode: 'insensitive' } },
|
||||
{ fullName: { contains: q, mode: 'insensitive' } },
|
||||
{ position: { contains: q, mode: 'insensitive' } },
|
||||
];
|
||||
}
|
||||
const code = getFirst(query.code);
|
||||
if (code) where.code = { contains: code, mode: 'insensitive' };
|
||||
const fullName = getFirst(query.fullName);
|
||||
if (fullName) where.fullName = { contains: fullName, mode: 'insensitive' };
|
||||
const position = getFirst(query.position);
|
||||
if (position) where.position = { contains: position, mode: 'insensitive' };
|
||||
const roleValues = toArray(query.role);
|
||||
if (roleValues.length > 0) where.role = { in: Array.from(new Set(roleValues)) };
|
||||
const boss = getFirst(query.boss);
|
||||
if (boss) where.bossCode = boss;
|
||||
const sortField = getFirst(query._sort) ?? 'code';
|
||||
const prismaSortField = sortField === 'id' ? 'code' : sortField;
|
||||
const sortOrder = (String(getFirst(query._order) ?? 'ASC').toLowerCase() === 'desc' ? 'desc' : 'asc') as Prisma.SortOrder;
|
||||
|
||||
const [items, total] = await this.prisma.$transaction([
|
||||
this.prisma.employee.findMany({
|
||||
where,
|
||||
skip: start,
|
||||
take,
|
||||
orderBy: { [prismaSortField]: sortOrder },
|
||||
include: {
|
||||
boss: true,
|
||||
subordinates: true,
|
||||
},
|
||||
}),
|
||||
this.prisma.employee.count({ where }),
|
||||
]);
|
||||
|
||||
setListHeaders(response, total, start, end, 'employees');
|
||||
return items.map((item) => this.toRecord(item));
|
||||
}
|
||||
|
||||
async findOne(code: string): Promise<Record<string, unknown>> {
|
||||
const item = await this.prisma.employee.findUnique({ where: { code },
|
||||
include: {
|
||||
boss: true,
|
||||
subordinates: true,
|
||||
}, });
|
||||
if (!item) throw new NotFoundException('Employee not found');
|
||||
return this.toRecord(item);
|
||||
}
|
||||
|
||||
async create(dto: CreateEmployeeDto): Promise<Record<string, unknown>> {
|
||||
const created = await this.prisma.employee.create({ data: this.prepareCreateData(dto) as any,
|
||||
include: {
|
||||
boss: true,
|
||||
subordinates: true,
|
||||
}, });
|
||||
return this.toRecord(created);
|
||||
}
|
||||
|
||||
async update(code: string, dto: UpdateEmployeeDto): Promise<Record<string, unknown>> {
|
||||
const updated = await this.prisma.employee.update({ where: { code }, data: this.prepareUpdateData(dto) as any,
|
||||
include: {
|
||||
boss: true,
|
||||
subordinates: true,
|
||||
}, });
|
||||
return this.toRecord(updated);
|
||||
}
|
||||
|
||||
async remove(code: string): Promise<Record<string, unknown>> {
|
||||
const deleted = await this.prisma.employee.delete({ where: { code },
|
||||
include: {
|
||||
boss: true,
|
||||
subordinates: true,
|
||||
}, });
|
||||
return this.toRecord(deleted);
|
||||
}
|
||||
|
||||
private prepareCreateData(dto: CreateEmployeeDto): Record<string, unknown> {
|
||||
return {
|
||||
code: dto.code,
|
||||
fullName: dto.fullName,
|
||||
role: dto.role,
|
||||
position: dto.position,
|
||||
bossCode: dto.boss ?? null,
|
||||
price: toNumberValue(dto.price),
|
||||
phoneNumber: toNumberValue(dto.phoneNumber),
|
||||
};
|
||||
}
|
||||
|
||||
private prepareUpdateData(dto: UpdateEmployeeDto): Record<string, unknown> {
|
||||
const { id, code: _pk, ...rest } = dto as Record<string, unknown> & { id?: string; code?: string };
|
||||
return {
|
||||
fullName: rest.fullName,
|
||||
role: rest.role,
|
||||
position: rest.position,
|
||||
bossCode: rest.boss ?? null,
|
||||
price: toNumberValue(rest.price),
|
||||
phoneNumber: toNumberValue(rest.phoneNumber),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user