added incomplete recipe point, controller and mapper implementation

This commit is contained in:
Anika Raemer 2025-09-27 21:00:21 +02:00
parent d94251dea4
commit 3a887d8dbb
5 changed files with 134 additions and 2 deletions

View file

@ -0,0 +1,76 @@
import { Entity } from "typeorm";
import { RecipeDto } from "../dtos/RecipeDto.js";
import { RecipeDtoEntityMapper } from "../mappers/RecipeDtoEntityMapper.js";
import { RecipeRepository } from "../repositories/RecipeRepository.js";
import { RecipeEntity } from "../entities/RecipeEntity.js";
import { ValidationError } from "../errors/httpErrors.js";
import { RecipeInstructionStepDto } from "../dtos/RecipeInstructionStepDto.js";
/**
* Controls all user specific actions
*/
export class RecipeController {
constructor(
private repository: RecipeRepository,
private mapper: RecipeDtoEntityMapper
) {}
/**
* Load list of all recipes
* @returns List of all recipes
*/
async getAllRecipes(){
const recipeEntities = await this.repository.findAll();
let recipeDtos : RecipeDto[] = [];
recipeEntities.forEach(recipeEntity => {
recipeDtos.push(this.mapper.toDto(recipeEntity));
});
return recipeDtos;
}
/**
* Create a new recipe
* @param dto RecipeDto containing the new recipe
*/
async createRecipe(dto : RecipeDto){
if(!this.isRecipeDtoValid(dto)){
throw new ValidationError("recipe data is not valid!")
}
const recipeEntity = this.mapper.toEntity(dto)
const entity = await this.repository.create(recipeEntity);
return this.mapper.toDto(entity);
}
protected isRecipeDtoValid(dto :RecipeDto) : boolean {
let isValid = true;
if(dto.title == undefined
|| dto.title.length == 0
|| dto.amount == undefined
|| dto.amountDescription == undefined
|| dto.amountDescription.length == 0
|| !this.isInstructionsValid(dto.instructions)
){
isValid = false;
}
// @todo ingredient groups
return isValid;
}
protected isInstructionsValid(instructions: RecipeInstructionStepDto[]|undefined) : boolean {
if(instructions == undefined || instructions.length == 0){
return false;
}
let isValid = true;
instructions.forEach(step =>{
if(step.text == undefined
|| step.text.length == 0
|| step.sortOrder == undefined
){
isValid = false;
}
});
return isValid;
}
}

View file

@ -7,7 +7,7 @@ import { RecipeInstructionStepDto } from "./RecipeInstructionStepDto.js";
*/
export class RecipeDto extends AbstractDto {
title?: string;
title!: string;
amount?: number
amountDescription?: string;
instructions?: RecipeInstructionStepDto[];

View file

@ -0,0 +1,26 @@
import { Router } from "express";
import { RecipeRepository } from "../repositories/RecipeRepository.js";
import { RecipeDtoEntityMapper } from "../mappers/RecipeDtoEntityMapper.js";
import { RecipeController } from "../controllers/RecipeController.js";
import { asyncHandler } from "../utils/asyncHandler.js";
/**
* Handles all user related routes
*/
const router = Router();
// Inject repo + mapper here
const recipeRepository = new RecipeRepository();
const recipeDtoEntityMapper = new RecipeDtoEntityMapper();
const recipeController = new RecipeController(recipeRepository, recipeDtoEntityMapper);
/**
* Create a new user
*/
router.get(
"/",
asyncHandler(async (req, res) => {
const response = await recipeController.getAllRecipes();
res.status(201).json(response);
})
);

View file

@ -0,0 +1,31 @@
import { RecipeDto } from "../dtos/RecipeDto.js";
import { RecipeEntity } from "../entities/RecipeEntity.js";
import { ValidationError } from "../errors/httpErrors.js";
import { AbstractDtoEntityMapper } from "./AbstractDtoEntityMapper.js";
export class RecipeDtoEntityMapper extends AbstractDtoEntityMapper<RecipeEntity,RecipeDto>{
toDto(entity: RecipeEntity): RecipeDto {
const dto = new RecipeDto();
this.mapBaseEntityToDto(entity, dto);
dto.title = entity.title;
dto.amount = entity.amount
dto.amountDescription = dto.amountDescription;
return dto;
}
toEntity(dto: RecipeDto): RecipeEntity {
const entity = new RecipeEntity();
this.mapBaseDtoToEntity(dto, entity);
entity.title = dto.title;
entity.amount = dto.amount
entity.amountDescription = dto.amountDescription;
return entity;
}
}

View file

@ -1,7 +1,6 @@
import { AbstractDtoEntityMapper } from "./AbstractDtoEntityMapper.js";
import { UserEntity } from "../entities/UserEntity.js";
import { UserDto } from "../dtos/UserDto.js";
import { ValidationError } from "../errors/httpErrors.js";
export class UserDtoEntityMapper extends AbstractDtoEntityMapper<UserEntity, UserDto> {
toDto(entity: UserEntity): UserDto {