Files
CRM_Montzar/apps/api/src/public-api/public-api-v1.controller.ts
T

165 lines
4.0 KiB
TypeScript
Raw Normal View History

import {
Controller,
Get,
Param,
Query,
UseGuards,
} from '@nestjs/common';
import { IsInt, IsOptional, IsString, Max, Min } from 'class-validator';
import { Type } from 'class-transformer';
import { CurrentUser } from '../auth/current-user.decorator';
import type { Prisma } from '@prisma/client';
import { PrismaService } from '../prisma/prisma.service';
import { buildSearchWhere, ci } from '../common/search';
import { ApiKeyAuthGuard } from './api-key-auth.guard';
class ListQueryDto {
@IsOptional()
@IsString()
q?: string;
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
page?: number = 1;
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
@Max(100)
limit?: number = 20;
}
@Controller('public/v1')
@UseGuards(ApiKeyAuthGuard)
export class PublicApiV1Controller {
constructor(private readonly prisma: PrismaService) {}
@Get('people')
async listPeople(
@CurrentUser() user: { organizationId: string },
@Query() query: ListQueryDto,
) {
const page = query.page ?? 1;
const limit = query.limit ?? 20;
const search = buildSearchWhere<Prisma.PersonWhereInput>(query.q, (t) => [
{ firstName: ci(t) },
{ lastName: ci(t) },
{ mobile: { contains: t } },
{ phone: { contains: t } },
{ email: ci(t) },
]);
const where: Prisma.PersonWhereInput = {
organizationId: user.organizationId,
...(search ? { AND: [search] } : {}),
};
const [total, items] = await Promise.all([
this.prisma.person.count({ where }),
this.prisma.person.findMany({
where,
select: {
id: true,
firstName: true,
lastName: true,
email: true,
mobile: true,
phone: true,
createdAt: true,
updatedAt: true,
},
orderBy: { updatedAt: 'desc' },
skip: (page - 1) * limit,
take: limit,
}),
]);
return {
total,
page,
limit,
items: items.map((p) => ({
...p,
fullName: `${p.firstName} ${p.lastName}`.trim(),
createdAt: p.createdAt.toISOString(),
updatedAt: p.updatedAt.toISOString(),
})),
};
}
@Get('people/:id')
async getPerson(
@CurrentUser() user: { organizationId: string },
@Param('id') id: string,
) {
const p = await this.prisma.person.findFirst({
where: { id, organizationId: user.organizationId },
select: {
id: true,
firstName: true,
lastName: true,
email: true,
mobile: true,
phone: true,
notes: true,
tags: true,
createdAt: true,
updatedAt: true,
},
});
if (!p) return null;
return {
...p,
fullName: `${p.firstName} ${p.lastName}`.trim(),
createdAt: p.createdAt.toISOString(),
updatedAt: p.updatedAt.toISOString(),
};
}
@Get('deals')
async listDeals(
@CurrentUser() user: { organizationId: string },
@Query() query: ListQueryDto,
) {
const page = query.page ?? 1;
const limit = query.limit ?? 20;
const search = buildSearchWhere<Prisma.DealWhereInput>(query.q, (t) => [{ title: ci(t) }]);
const where: Prisma.DealWhereInput = {
organizationId: user.organizationId,
...(search ? { AND: [search] } : {}),
};
const [total, items] = await Promise.all([
this.prisma.deal.count({ where }),
this.prisma.deal.findMany({
where,
select: {
id: true,
title: true,
status: true,
amount: true,
currency: true,
source: true,
stageId: true,
pipelineId: true,
createdAt: true,
updatedAt: true,
},
orderBy: { updatedAt: 'desc' },
skip: (page - 1) * limit,
take: limit,
}),
]);
return {
total,
page,
limit,
items: items.map((d) => ({
...d,
amount: d.amount == null ? null : Number(d.amount),
createdAt: d.createdAt.toISOString(),
updatedAt: d.updatedAt.toISOString(),
})),
};
}
}