Ajout endpoint trajets en train
This commit is contained in:
parent
4349a1b61a
commit
e052b06c83
@ -6,9 +6,10 @@ import { AuthModule } from './auth/auth.module'
|
|||||||
import { GeolocationsModule } from './geolocations/geolocations.module'
|
import { GeolocationsModule } from './geolocations/geolocations.module'
|
||||||
import { ChallengesModule } from './challenges/challenges.module'
|
import { ChallengesModule } from './challenges/challenges.module'
|
||||||
import { ChallengeActionsModule } from './challenge-actions/challenge-actions.module'
|
import { ChallengeActionsModule } from './challenge-actions/challenge-actions.module'
|
||||||
|
import { TrainsModule } from './trains/trains.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [PrismaModule, UsersModule, AuthModule, GeolocationsModule, ChallengesModule, ChallengeActionsModule],
|
imports: [PrismaModule, UsersModule, AuthModule, GeolocationsModule, ChallengesModule, ChallengeActionsModule, TrainsModule],
|
||||||
providers: [PrismaService],
|
providers: [PrismaService],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
46
server/src/trains/dto/create-train.dto.ts
Normal file
46
server/src/trains/dto/create-train.dto.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger"
|
||||||
|
import { JsonValue } from "@prisma/client/runtime/library"
|
||||||
|
import { Type } from "class-transformer"
|
||||||
|
import { IsDate, IsInt, IsJSON, IsNumber, IsString } from "class-validator"
|
||||||
|
|
||||||
|
export class CreateTrainDto {
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty({ description: "Identifiant du train, donné par l'identifiant de partage Interrail" })
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@IsInt()
|
||||||
|
@Type(() => Number)
|
||||||
|
@ApiProperty({ description: "Identifiant de l'utilisateur⋅rice effectuant le trajet" })
|
||||||
|
userId: number
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@Type(() => Number)
|
||||||
|
@ApiProperty({ description: "Distance en mètres du trajet, calculé sur https://signal.eu.org/osm/" })
|
||||||
|
distance: number
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty({ description: "Nom de la gare de départ" })
|
||||||
|
from: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty({ description: "Nom de la gare d'arrivée" })
|
||||||
|
to: string
|
||||||
|
|
||||||
|
@IsDate()
|
||||||
|
@Type(() => Date)
|
||||||
|
@ApiProperty({ description: "Date et heure de départ du train" })
|
||||||
|
departureTime: Date
|
||||||
|
|
||||||
|
@IsDate()
|
||||||
|
@Type(() => Date)
|
||||||
|
@ApiProperty({ description: "Date et heure d'arrivée du train" })
|
||||||
|
arrivalTime: Date
|
||||||
|
|
||||||
|
@IsJSON()
|
||||||
|
@ApiProperty({ description: "Informations JSON supplémentaires transmises par Interrail" })
|
||||||
|
infoJson: JsonValue
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty({ description: "Géométrie de la course, obtenue par https://signal.eu.org/osm/" })
|
||||||
|
geometry: string
|
||||||
|
}
|
4
server/src/trains/dto/update-train.dto.ts
Normal file
4
server/src/trains/dto/update-train.dto.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { PartialType } from '@nestjs/swagger';
|
||||||
|
import { CreateTrainDto } from './create-train.dto';
|
||||||
|
|
||||||
|
export class UpdateTrainDto extends PartialType(CreateTrainDto) {}
|
36
server/src/trains/entities/train.entity.ts
Normal file
36
server/src/trains/entities/train.entity.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger"
|
||||||
|
import { TrainTrip } from "@prisma/client"
|
||||||
|
import { JsonValue } from "@prisma/client/runtime/library"
|
||||||
|
|
||||||
|
export class TrainEntity implements TrainTrip {
|
||||||
|
constructor (partial: Partial<TrainEntity>) {
|
||||||
|
Object.assign(this, partial)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Identifiant du train, donné par l'identifiant de partage Interrail" })
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Identifiant de l'utilisateur⋅rice effectuant le trajet" })
|
||||||
|
userId: number
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Distance en mètres du trajet, calculé sur https://signal.eu.org/osm/" })
|
||||||
|
distance: number
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Nom de la gare de départ" })
|
||||||
|
from: string
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Nom de la gare d'arrivée" })
|
||||||
|
to: string
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Date et heure de départ du train" })
|
||||||
|
departureTime: Date
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Date et heure d'arrivée du train" })
|
||||||
|
arrivalTime: Date
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Informations JSON supplémentaires transmises par Interrail" })
|
||||||
|
infoJson: JsonValue
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Géométrie de la course, obtenue par https://signal.eu.org/osm/" })
|
||||||
|
geometry: string
|
||||||
|
}
|
20
server/src/trains/trains.controller.spec.ts
Normal file
20
server/src/trains/trains.controller.spec.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'
|
||||||
|
import { TrainsController } from './trains.controller'
|
||||||
|
import { TrainsService } from './trains.service'
|
||||||
|
|
||||||
|
describe('TrainsController', () => {
|
||||||
|
let controller: TrainsController
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
controllers: [TrainsController],
|
||||||
|
providers: [TrainsService],
|
||||||
|
}).compile()
|
||||||
|
|
||||||
|
controller = module.get<TrainsController>(TrainsController)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(controller).toBeDefined()
|
||||||
|
})
|
||||||
|
})
|
75
server/src/trains/trains.controller.ts
Normal file
75
server/src/trains/trains.controller.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { Controller, Get, Post, Body, Patch, Param, Delete, HttpCode, UseGuards, Query, ParseIntPipe, NotFoundException } from '@nestjs/common'
|
||||||
|
import { TrainsService } from './trains.service'
|
||||||
|
import { CreateTrainDto } from './dto/create-train.dto'
|
||||||
|
import { UpdateTrainDto } from './dto/update-train.dto'
|
||||||
|
import { TrainEntity } from './entities/train.entity'
|
||||||
|
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard'
|
||||||
|
import { ApiBearerAuth, ApiCreatedResponse, ApiForbiddenResponse, ApiNotFoundResponse, ApiOkResponse, ApiUnauthorizedResponse } from '@nestjs/swagger'
|
||||||
|
import { ApiOkResponsePaginated, paginateOutput } from 'src/common/utils/pagination.utils'
|
||||||
|
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||||
|
import { PaginateOutputDto } from 'src/common/dto/pagination-output.dto'
|
||||||
|
|
||||||
|
@Controller('trains')
|
||||||
|
export class TrainsController {
|
||||||
|
constructor(private readonly trainsService: TrainsService) {}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
@HttpCode(201)
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiCreatedResponse({ type: TrainEntity, description: "Objet créé avec succès" })
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
|
async create(@Body() createTrainDto: CreateTrainDto): Promise<TrainEntity> {
|
||||||
|
const train = await this.trainsService.create(createTrainDto)
|
||||||
|
return new TrainEntity(train)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiOkResponsePaginated(TrainEntity)
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
|
async findAll(@Query() queryPagination?: QueryPaginationDto): Promise<PaginateOutputDto<TrainEntity>> {
|
||||||
|
const [trains, total] = await this.trainsService.findAll(queryPagination)
|
||||||
|
return paginateOutput<TrainEntity>(trains.map(train => new TrainEntity(train)), total, queryPagination)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiOkResponse({ type: TrainEntity })
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
|
@ApiNotFoundResponse({ description: "Objet non trouvé" })
|
||||||
|
async findOne(@Param('id') id: string): Promise<TrainEntity> {
|
||||||
|
const train = await this.trainsService.findOne(id)
|
||||||
|
if (!train)
|
||||||
|
throw new NotFoundException(`Trajet en train inexistant avec l'identifiant ${id}`)
|
||||||
|
return new TrainEntity(train)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch(':id')
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiOkResponse({ type: TrainEntity })
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
|
@ApiNotFoundResponse({ description: "Objet non trouvé" })
|
||||||
|
async update(@Param('id') id: string, @Body() updateChallengeDto: UpdateTrainDto) {
|
||||||
|
return await this.trainsService.update(id, updateChallengeDto)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
@HttpCode(204)
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiOkResponse({ type: TrainEntity })
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
|
@ApiNotFoundResponse({ description: "Objet non trouvé" })
|
||||||
|
async remove(@Param('id') id: string) {
|
||||||
|
await this.trainsService.remove(id)
|
||||||
|
}
|
||||||
|
}
|
11
server/src/trains/trains.module.ts
Normal file
11
server/src/trains/trains.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Module } from '@nestjs/common'
|
||||||
|
import { TrainsService } from './trains.service'
|
||||||
|
import { TrainsController } from './trains.controller'
|
||||||
|
import { PrismaModule } from 'src/prisma/prisma.module'
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [TrainsController],
|
||||||
|
providers: [TrainsService],
|
||||||
|
imports: [PrismaModule],
|
||||||
|
})
|
||||||
|
export class TrainsModule {}
|
18
server/src/trains/trains.service.spec.ts
Normal file
18
server/src/trains/trains.service.spec.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'
|
||||||
|
import { TrainsService } from './trains.service'
|
||||||
|
|
||||||
|
describe('TrainsService', () => {
|
||||||
|
let service: TrainsService
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [TrainsService],
|
||||||
|
}).compile()
|
||||||
|
|
||||||
|
service = module.get<TrainsService>(TrainsService)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined()
|
||||||
|
})
|
||||||
|
})
|
44
server/src/trains/trains.service.ts
Normal file
44
server/src/trains/trains.service.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { CreateTrainDto } from './dto/create-train.dto'
|
||||||
|
import { UpdateTrainDto } from './dto/update-train.dto'
|
||||||
|
import { PrismaService } from 'src/prisma/prisma.service'
|
||||||
|
import { TrainTrip } from '@prisma/client'
|
||||||
|
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||||
|
import { paginate } from 'src/common/utils/pagination.utils'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TrainsService {
|
||||||
|
constructor(private prisma: PrismaService) { }
|
||||||
|
|
||||||
|
async create(createTrainDto: CreateTrainDto): Promise<TrainTrip> {
|
||||||
|
return await this.prisma.trainTrip.create({ data: createTrainDto })
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll(queryPagination?: QueryPaginationDto): Promise<[TrainTrip[], number]> {
|
||||||
|
return [
|
||||||
|
await this.prisma.trainTrip.findMany({
|
||||||
|
...paginate(queryPagination),
|
||||||
|
}),
|
||||||
|
await this.prisma.challenge.count(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
async findOne(id: string): Promise<TrainTrip> {
|
||||||
|
return await this.prisma.trainTrip.findUnique({
|
||||||
|
where: { id },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(id: string, updateTrainDto: UpdateTrainDto): Promise<TrainTrip> {
|
||||||
|
return await this.prisma.trainTrip.update({
|
||||||
|
where: { id },
|
||||||
|
data: updateTrainDto,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async remove(id: string): Promise<TrainTrip> {
|
||||||
|
return await this.prisma.trainTrip.delete({
|
||||||
|
where: { id },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user