This commit is contained in:
2025-08-18 20:12:57 +03:00
parent cc0b793000
commit 9f6fca6dac
24 changed files with 11283 additions and 117 deletions

43
src/app.controller.ts Normal file
View File

@@ -0,0 +1,43 @@
import { BadRequestException, Body, Controller, Get, NotFoundException, Param, ParseIntPipe, Post, Put } from '@nestjs/common';
import { RegisterDto } from './dto/register.dto';
import { ApiTags } from '@nestjs/swagger';
import { PrismaService } from './services/prisma.service';
@ApiTags('App')
@Controller('app')
export class AppController {
constructor(private prisma: PrismaService) { }
@Get('candidates')
getCandidateList() {
return this.prisma.candidate.findMany({
select: {
id: true,
fullName: true,
image: true,
}
})
}
@Get('candidate/:id')
getCandidateDetails(@Param('id', ParseIntPipe) id: number) {
return this.prisma.candidate.findFirst({where: {id : id}});
}
@Post('register')
register(@Body() dto: RegisterDto) {
return this.prisma.candidate.create({ data: { ...dto, createdAt: new Date() } });
}
@Put('candidate/:id')
async update(@Param('id', ParseIntPipe) id: number, @Body() dto: RegisterDto) {
const candidate = await this.prisma.candidate.findFirst({ where: { id: id } });
if (!candidate) throw new NotFoundException(`candidate with id ${id} not found`);
const dayMilliseconds = 86400000;
const expirationDate = new Date(candidate.createdAt.valueOf() + 3 * dayMilliseconds);
if (expirationDate < new Date()) throw new BadRequestException(`can not edit candidate form after 3 days`);
await this.prisma.candidate.update({ where: { id: id }, data: { id, ...dto } });
return;
}
}

16
src/app.module.ts Normal file
View File

@@ -0,0 +1,16 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
import { PrismaService } from './services/prisma.service';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, 'client'),
}),
],
controllers: [AppController],
providers: [PrismaService],
})
export class AppModule { }

22
src/dto/register.dto.ts Normal file
View File

@@ -0,0 +1,22 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsInt } from 'class-validator';
export class RegisterDto {
@ApiProperty({ required: true })
fullName: string;
@ApiProperty({ required: true })
email: string;
@ApiProperty({ required: true })
phoneNumber: string;
@ApiProperty({ required: true })
@IsInt()
age: number;
@ApiProperty({ required: true })
cityOrRegion: string;
@ApiProperty({ required: false })
hobbies: string;
@ApiProperty({ required: false })
text: string;
@ApiProperty({ required: false })
image: string;
}

47
src/main.ts Normal file
View File

@@ -0,0 +1,47 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { INestApplication, ValidationPipe } from '@nestjs/common';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(
new ValidationPipe({
forbidNonWhitelisted: true,
transform: true,
transformOptions: { enableImplicitConversion: true },
}),
);
setupSwagger(app);
app.enableCors({
origin: true,
methods: [
'GET',
'HEAD',
'PUT',
'PATCH',
'POST',
'DELETE',
'OPTIONS',
],
allowedHeaders: ['*'],
optionsSuccessStatus: 204,
credentials: true,
preflightContinue: false
});
await app.listen(process.env.PORT ?? 3000);
}
function setupSwagger(app: INestApplication<any>) {
const config = new DocumentBuilder()
.setTitle('IISA Api')
.setDescription('API description')
.setVersion('1.0')
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
}
bootstrap();

View File

@@ -0,0 +1,9 @@
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from 'generated/prisma';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}