Ajustes e add usurios
This commit is contained in:
10
package.json
10
package.json
@@ -25,7 +25,7 @@
|
|||||||
"@nestjs/core": "11.0.1",
|
"@nestjs/core": "11.0.1",
|
||||||
"@nestjs/passport": "11.0.5",
|
"@nestjs/passport": "11.0.5",
|
||||||
"@nestjs/platform-express": "11.0.1",
|
"@nestjs/platform-express": "11.0.1",
|
||||||
"@prisma/client": "6.14.0",
|
"@prisma/client": "6.18.0",
|
||||||
"axios": "1.12.0",
|
"axios": "1.12.0",
|
||||||
"bcrypt": "6.0.0",
|
"bcrypt": "6.0.0",
|
||||||
"class-transformer": "0.5.1",
|
"class-transformer": "0.5.1",
|
||||||
@@ -34,12 +34,8 @@
|
|||||||
"dayjs": "1.11.13",
|
"dayjs": "1.11.13",
|
||||||
"jwks-rsa": "3.2.0",
|
"jwks-rsa": "3.2.0",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
"ollama": "0.6.0",
|
|
||||||
"openai": "6.1.0",
|
|
||||||
"passport": "0.7.0",
|
"passport": "0.7.0",
|
||||||
"passport-jwt": "4.0.1",
|
"passport-jwt": "4.0.1"
|
||||||
"reflect-metadata": "0.2.2",
|
|
||||||
"rxjs": "7.8.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "3.2.0",
|
"@eslint/eslintrc": "3.2.0",
|
||||||
@@ -60,7 +56,7 @@
|
|||||||
"globals": "16.0.0",
|
"globals": "16.0.0",
|
||||||
"jest": "30.0.0",
|
"jest": "30.0.0",
|
||||||
"prettier": "3.4.2",
|
"prettier": "3.4.2",
|
||||||
"prisma": "6.14.0",
|
"prisma": "6.18.0",
|
||||||
"source-map-support": "0.5.21",
|
"source-map-support": "0.5.21",
|
||||||
"supertest": "7.0.0",
|
"supertest": "7.0.0",
|
||||||
"ts-jest": "29.2.5",
|
"ts-jest": "29.2.5",
|
||||||
|
|||||||
@@ -36,21 +36,21 @@ enum eboolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model videos {
|
model videos {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
uuid String @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
uuid String @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||||
datetime_download DateTime? @db.Timestamp(6)
|
datetime_download DateTime? @db.Timestamp(6)
|
||||||
datetime_convert DateTime? @db.Timestamp(6)
|
datetime_convert DateTime? @db.Timestamp(6)
|
||||||
url String @db.VarChar(244)
|
url String @db.VarChar(244)
|
||||||
situation video_situation
|
situation video_situation @default(FILA)
|
||||||
error_message String? @db.VarChar(244)
|
error_message String? @db.VarChar(244)
|
||||||
clips_quantity Int?
|
clips_quantity Int?
|
||||||
duration String? @db.VarChar(16)
|
duration String? @db.VarChar(16)
|
||||||
title String? @db.VarChar(244)
|
title String? @db.VarChar(244)
|
||||||
filename String? @db.VarChar(244)
|
filename String? @db.VarChar(244)
|
||||||
videoid String? @db.VarChar(244)
|
videoid String? @db.VarChar(244)
|
||||||
datetime_posted DateTime? @db.Timestamp(6)
|
datetime_posted DateTime? @db.Timestamp(6)
|
||||||
usuario_id Int?
|
usuario_id Int?
|
||||||
usuario Usuario? @relation(fields: [usuario_id], references: [id])
|
usuario Usuario? @relation(fields: [usuario_id], references: [id])
|
||||||
|
|
||||||
@@map("videos")
|
@@map("videos")
|
||||||
}
|
}
|
||||||
|
|||||||
35
src/modules/usuarios/dto/list-usuarios-query.dto.ts
Normal file
35
src/modules/usuarios/dto/list-usuarios-query.dto.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { Transform } from 'class-transformer';
|
||||||
|
import { IsBoolean, IsNumber, IsOptional, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
const trimString = ({ value }: { value: unknown }): string | undefined =>
|
||||||
|
typeof value === 'string' ? value.trim() : undefined;
|
||||||
|
|
||||||
|
export class ListUsuariosQueryDto {
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@Transform(trimString)
|
||||||
|
name?: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@Transform(trimString)
|
||||||
|
email?: string;
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@IsOptional()
|
||||||
|
@Transform(({ value }) => (value ? Number(value) : 1))
|
||||||
|
page?: number;
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@IsOptional()
|
||||||
|
@Transform(({ value }) => (value ? Number(value) : 10))
|
||||||
|
perPage?: number = 10;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
direction: 'asc' | 'desc' = 'desc';
|
||||||
|
|
||||||
|
@Transform(({ value }) => value !== 'false')
|
||||||
|
@IsBoolean()
|
||||||
|
@IsOptional()
|
||||||
|
pageable: boolean = true;
|
||||||
|
}
|
||||||
@@ -1,24 +1,42 @@
|
|||||||
import {
|
import {
|
||||||
|
Body,
|
||||||
Controller,
|
Controller,
|
||||||
Get,
|
Get,
|
||||||
Param,
|
Param,
|
||||||
|
Patch,
|
||||||
Post,
|
Post,
|
||||||
Body,
|
Query,
|
||||||
UsePipes,
|
UsePipes,
|
||||||
ValidationPipe,
|
ValidationPipe,
|
||||||
Patch,
|
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { UsuariosService } from './usuarios.service';
|
import { UsuariosService } from './usuarios.service';
|
||||||
import { UsuariosResponseDto } from './dto/usuarios.response';
|
import { UsuariosResponseDto } from './dto/usuarios.response';
|
||||||
import { CreateUsuarioDto } from './dto/create-usuario-dto';
|
import { CreateUsuarioDto } from './dto/create-usuario-dto';
|
||||||
|
import { PaginatedResponse } from '@shared/dto/paginated';
|
||||||
|
import { ListUsuariosQueryDto } from './dto/list-usuarios-query.dto';
|
||||||
|
|
||||||
@Controller('usuarios')
|
@Controller('usuarios')
|
||||||
export class UsuariosController {
|
export class UsuariosController {
|
||||||
constructor(private readonly usuariosService: UsuariosService) {}
|
constructor(private readonly usuariosService: UsuariosService) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
async list(): Promise<UsuariosResponseDto[]> {
|
async list(
|
||||||
return this.usuariosService.list();
|
@Query() query: ListUsuariosQueryDto,
|
||||||
|
): Promise<PaginatedResponse<UsuariosResponseDto> | UsuariosResponseDto[]> {
|
||||||
|
if (query.pageable || query.page || query.perPage) {
|
||||||
|
return this.usuariosService.listPaginated({
|
||||||
|
page: query.page,
|
||||||
|
perPage: query.perPage,
|
||||||
|
direction: query.direction,
|
||||||
|
name: query.name,
|
||||||
|
email: query.email,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.usuariosService.list({
|
||||||
|
name: query.name,
|
||||||
|
email: query.email,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':uuid')
|
@Get(':uuid')
|
||||||
|
|||||||
@@ -9,6 +9,17 @@ import { PaginatedResponse } from '@shared/dto/paginated';
|
|||||||
import { UsuariosResponseDto } from './dto/usuarios.response';
|
import { UsuariosResponseDto } from './dto/usuarios.response';
|
||||||
import { CreateUsuarioDto } from './dto/create-usuario-dto';
|
import { CreateUsuarioDto } from './dto/create-usuario-dto';
|
||||||
|
|
||||||
|
type ListUsuariosFilters = {
|
||||||
|
name?: string;
|
||||||
|
email?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ListUsuariosPaginatedParams = ListUsuariosFilters & {
|
||||||
|
page?: number;
|
||||||
|
perPage?: number;
|
||||||
|
direction?: 'asc' | 'desc';
|
||||||
|
};
|
||||||
|
|
||||||
const SELECT = {
|
const SELECT = {
|
||||||
id: true,
|
id: true,
|
||||||
uuid: true,
|
uuid: true,
|
||||||
@@ -30,9 +41,37 @@ const SELECT = {
|
|||||||
export class UsuariosService {
|
export class UsuariosService {
|
||||||
constructor(private readonly prisma: PrismaService) {}
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
async list(): Promise<UsuariosResponseDto[]> {
|
private buildWhere({
|
||||||
|
name,
|
||||||
|
email,
|
||||||
|
}: ListUsuariosFilters): Prisma.UsuarioWhereInput {
|
||||||
|
const andConditions: Prisma.UsuarioWhereInput[] = [
|
||||||
|
{ email: { not: 'admin@clipperia.com' } },
|
||||||
|
];
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
andConditions.push({
|
||||||
|
OR: [
|
||||||
|
{ nome: { contains: name, mode: 'insensitive' } },
|
||||||
|
{ sobrenome: { contains: name, mode: 'insensitive' } },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (email) {
|
||||||
|
andConditions.push({ email: { contains: email, mode: 'insensitive' } });
|
||||||
|
}
|
||||||
|
|
||||||
|
return { AND: andConditions };
|
||||||
|
}
|
||||||
|
|
||||||
|
async list(
|
||||||
|
filters: ListUsuariosFilters = {},
|
||||||
|
): Promise<UsuariosResponseDto[]> {
|
||||||
|
const where = this.buildWhere(filters);
|
||||||
|
|
||||||
const data = await this.prisma.usuario.findMany({
|
const data = await this.prisma.usuario.findMany({
|
||||||
where: { email: { not: 'admin@clipperia.com' } },
|
where,
|
||||||
orderBy: { id: 'desc' },
|
orderBy: { id: 'desc' },
|
||||||
select: SELECT,
|
select: SELECT,
|
||||||
});
|
});
|
||||||
@@ -43,20 +82,35 @@ export class UsuariosService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async listPaginated(
|
async listPaginated(
|
||||||
page: number,
|
params: ListUsuariosPaginatedParams,
|
||||||
perPage: number,
|
|
||||||
direction: 'asc' | 'desc' = 'desc',
|
|
||||||
): Promise<PaginatedResponse<UsuariosResponseDto>> {
|
): Promise<PaginatedResponse<UsuariosResponseDto>> {
|
||||||
const skip = page >= 1 ? page * perPage : 0;
|
const parsedPage = Number(params.page);
|
||||||
|
const safePage =
|
||||||
|
Number.isFinite(parsedPage) && parsedPage > 0
|
||||||
|
? Math.floor(parsedPage)
|
||||||
|
: 1;
|
||||||
|
|
||||||
|
const parsedPerPage = Number(params.perPage);
|
||||||
|
const safePerPage =
|
||||||
|
Number.isFinite(parsedPerPage) && parsedPerPage > 0
|
||||||
|
? Math.floor(parsedPerPage)
|
||||||
|
: 10;
|
||||||
|
|
||||||
|
const safeDirection: 'asc' | 'desc' =
|
||||||
|
params.direction === 'asc' ? 'asc' : 'desc';
|
||||||
|
|
||||||
|
const where = this.buildWhere(params);
|
||||||
|
const skip = (safePage - 1) * safePerPage;
|
||||||
|
|
||||||
const [rows, total] = await Promise.all([
|
const [rows, total] = await Promise.all([
|
||||||
this.prisma.usuario.findMany({
|
this.prisma.usuario.findMany({
|
||||||
orderBy: { id: direction },
|
where,
|
||||||
|
orderBy: { id: safeDirection },
|
||||||
skip,
|
skip,
|
||||||
take: perPage ?? 1,
|
take: safePerPage,
|
||||||
select: SELECT,
|
select: SELECT,
|
||||||
}),
|
}),
|
||||||
this.prisma.usuario.count(),
|
this.prisma.usuario.count({ where }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const content: UsuariosResponseDto[] = plainToInstance(
|
const content: UsuariosResponseDto[] = plainToInstance(
|
||||||
@@ -65,18 +119,18 @@ export class UsuariosService {
|
|||||||
{ excludeExtraneousValues: true },
|
{ excludeExtraneousValues: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
const totalPages = Math.max(1, Math.ceil(total / perPage));
|
const totalPages = Math.max(1, Math.ceil(total / safePerPage));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content,
|
content,
|
||||||
pagination: {
|
pagination: {
|
||||||
page,
|
page: safePage,
|
||||||
direction,
|
direction: safeDirection,
|
||||||
perPage,
|
perPage: safePerPage,
|
||||||
total,
|
total,
|
||||||
totalPages,
|
totalPages,
|
||||||
hasNext: page < totalPages,
|
hasNext: safePage < totalPages,
|
||||||
hasPrev: page > 1,
|
hasPrev: safePage > 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ export class VideosService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createNewVideo(data: CreateVideoDto): Promise<void> {
|
async createNewVideo(data: CreateVideoDto): Promise<void> {
|
||||||
const { url, videoid, duration, qualidade, title, timestamp } = data;
|
const { url, videoid, duration, qualidade, title } = data;
|
||||||
|
|
||||||
const query: Prisma.videosWhereInput = { url };
|
const query: Prisma.videosWhereInput = { url };
|
||||||
|
|
||||||
@@ -194,23 +194,19 @@ export class VideosService {
|
|||||||
createData.duration = formattedDuration;
|
createData.duration = formattedDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof timestamp === 'number' && Number.isFinite(timestamp)) {
|
|
||||||
createData.datetime_download = new Date(timestamp * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.prisma.videos.create({
|
await this.prisma.videos.create({
|
||||||
data: createData,
|
data: createData,
|
||||||
});
|
});
|
||||||
|
|
||||||
// const params = {
|
const params = {
|
||||||
// url,
|
url,
|
||||||
// videoid,
|
videoid,
|
||||||
// qualidade: qualidade === 'automatic' ? 'medium' : qualidade,
|
qualidade: qualidade === 'automatic' ? 'medium' : qualidade,
|
||||||
// };
|
};
|
||||||
|
|
||||||
// await axios.get(`${N8N_REMOTE_SERVER}/webhook/download-video`, {
|
await axios.get(`${N8N_REMOTE_SERVER}/webhook/download-video`, {
|
||||||
// params,
|
params,
|
||||||
// });
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(id: number, data: Prisma.videosUpdateInput): Promise<videos> {
|
async update(id: number, data: Prisma.videosUpdateInput): Promise<videos> {
|
||||||
|
|||||||
Reference in New Issue
Block a user