Skip to content

Commit

Permalink
Feature/swagger (#50)
Browse files Browse the repository at this point in the history
* Primeros cambios

* Commit salvaje pero todos los servicios relevados

* Update src/project/project.controller.ts

Co-authored-by: Juani Schuhmann <76596375+jschuhmann47@users.noreply.github.com>

* Mas fixes

* rm package

* restore package files

* rm redundant prop

---------

Co-authored-by: Juani Schuhmann <76596375+jschuhmann47@users.noreply.github.com>
Co-authored-by: jschuhmann47 <jschuhmann@frba.utn.edu.ar>
  • Loading branch information
3 people authored Nov 24, 2024
1 parent 291dbc1 commit d405415
Show file tree
Hide file tree
Showing 26 changed files with 1,378 additions and 297 deletions.
20 changes: 20 additions & 0 deletions src/app.controller.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
import { Controller, Get } from '@nestjs/common'
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger'
import { Tool } from './herramientas/tools'

@ApiTags('Tools')
@Controller()
export class AppController {
@Get('tools')
@ApiOperation({ summary: 'Retrieve available tools' })
@ApiResponse({
status: 200,
description: 'Returns a list of available tools with their identifiers',
schema: {
type: 'object',
properties: {
tool: {
type: 'array',
items: {
enum: Object.values(Tool),
},
description:
'List of tool identifiers available in the system',
},
},
},
})
getTools() {
return {
tool: Object.values(Tool),
Expand Down
30 changes: 29 additions & 1 deletion src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CreateUserDto } from 'src/user/user.dto'
import { UserService } from 'src/user/user.service'
import { AuthService } from './auth.service'
import { LoginDTO } from './login.dto'
import { ApiTags } from '@nestjs/swagger'
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger'
import { User } from 'src/user/user.schema'

@Controller('auth')
Expand All @@ -17,11 +17,23 @@ export class AuthController {

@Get('/onlyauth')
@UseGuards(AuthGuard('jwt'))
@ApiOperation({ summary: 'Access protected information' })
@ApiResponse({
status: 200,
description: 'Returns hidden information for authenticated users only.',
})
@ApiResponse({ status: 401, description: 'Unauthorized' })
async hiddenInformation() {
return 'hidden information'
}

@Post('/register')
@ApiOperation({ summary: 'Register a new user' })
@ApiResponse({
status: 201,
description: 'User successfully registered along with a JWT token.',
})
@ApiResponse({ status: 400, description: 'Invalid input data' })
async register(@Body() userDTO: CreateUserDto) {
const user = await this.userService.create(userDTO)
const payload = {
Expand All @@ -33,6 +45,15 @@ export class AuthController {
}

@Post('login')
@ApiOperation({ summary: 'Login a user and return a JWT token' })
@ApiResponse({
status: 200,
description: 'User successfully authenticated with a JWT token.',
})
@ApiResponse({
status: 401,
description: 'Unauthorized: Invalid login credentials',
})
async login(@Body() loginDTO: LoginDTO) {
const user = await this.userService.findByLogin(loginDTO)
const payload = {
Expand All @@ -44,6 +65,13 @@ export class AuthController {

@UseGuards(AuthGuard('jwt'))
@Get('/profile')
@ApiOperation({ summary: 'Get the profile of the authenticated user' })
@ApiResponse({
status: 200,
description:
'Returns the profile of the authenticated user along with a JWT token.',
})
@ApiResponse({ status: 401, description: 'Unauthorized' })
async getProfile(@Req() req: { user: User }) {
const { email } = req.user
const payload = {
Expand Down
40 changes: 39 additions & 1 deletion src/herramientas/ansoff/ansoff.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { AnsoffService } from './ansoff.service'
import { Ansoff } from './ansoff.schema'
import { AnsoffDto, AnsoffProductDto } from './ansoff.dto'
import { AuthGuard } from '@nestjs/passport'
import { ApiTags } from '@nestjs/swagger'
import { ApiTags, ApiOperation, ApiResponse, ApiParam } from '@nestjs/swagger'

@UseGuards(AuthGuard('jwt'))
@Controller('ansoff')
Expand All @@ -21,22 +21,46 @@ export class AnsoffController {
constructor(private ansoffService: AnsoffService) {}

@Post('')
@ApiOperation({ summary: 'Create a new Ansoff project' })
@ApiResponse({
status: 201,
description: 'Project successfully created',
type: Ansoff,
})
@ApiResponse({ status: 400, description: 'Invalid input data' })
async insert(@Body() ansoffDto: AnsoffDto): Promise<Ansoff> {
const ansoff = await this.ansoffService.create(ansoffDto)
return ansoff
}

@Get('options')
@ApiOperation({ summary: 'Get options for Ansoff analysis' })
@ApiResponse({
status: 200,
description: 'Returns available options for Ansoff analysis',
})
getOptions() {
return this.ansoffService.getOptions()
}

@Get(':id')
@ApiOperation({ summary: 'Find an Ansoff project by ID' })
@ApiParam({ name: 'id', description: 'ID of the Ansoff project' })
@ApiResponse({
status: 200,
description: 'Returns the project details',
type: Ansoff,
})
@ApiResponse({ status: 404, description: 'Project not found' })
async find(@Param('id') id: string) {
return await this.ansoffService.findById(id)
}

@Post(':id/products')
@ApiOperation({ summary: 'Add a product to an Ansoff project' })
@ApiParam({ name: 'id', description: 'ID of the Ansoff project' })
@ApiResponse({ status: 201, description: 'Product successfully added' })
@ApiResponse({ status: 400, description: 'Invalid input data' })
async addProduct(
@Param('id') id: string,
@Body() productRequest: AnsoffProductDto
Expand All @@ -45,6 +69,11 @@ export class AnsoffController {
}

@Put(':id/products/:productId')
@ApiOperation({ summary: 'Edit a product in an Ansoff project' })
@ApiParam({ name: 'id', description: 'ID of the Ansoff project' })
@ApiParam({ name: 'productId', description: 'ID of the product to edit' })
@ApiResponse({ status: 200, description: 'Product successfully updated' })
@ApiResponse({ status: 404, description: 'Product or project not found' })
async editProduct(
@Param('id') id: string,
@Param('productId') productId: string,
Expand All @@ -58,6 +87,11 @@ export class AnsoffController {
}

@Delete(':projectId/products/:productId')
@ApiOperation({ summary: 'Delete a product from an Ansoff project' })
@ApiParam({ name: 'projectId', description: 'ID of the Ansoff project' })
@ApiParam({ name: 'productId', description: 'ID of the product to delete' })
@ApiResponse({ status: 200, description: 'Product successfully deleted' })
@ApiResponse({ status: 404, description: 'Product or project not found' })
async deleteProduct(
@Param('projectId') projectId: string,
@Param('productId') productId: string
Expand All @@ -66,6 +100,10 @@ export class AnsoffController {
}

@Delete(':id')
@ApiOperation({ summary: 'Delete an Ansoff project' })
@ApiParam({ name: 'id', description: 'ID of the Ansoff project to delete' })
@ApiResponse({ status: 200, description: 'Project successfully deleted' })
@ApiResponse({ status: 404, description: 'Project not found' })
async delete(@Param('id') id: string) {
const documentId = await this.ansoffService.delete(id)
return {
Expand Down
56 changes: 46 additions & 10 deletions src/herramientas/ansoff/ansoff.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,71 @@ import { Estrategia } from './estrategia'
import { ApiProperty } from '@nestjs/swagger'

export class AnsoffDto {
@ApiProperty()
@ApiProperty({
example: '123456',
description: 'Unique identifier for the project',
})
projectId: string

@ApiProperty()
@ApiProperty({
example: 'Project Title',
description: 'Title of the project',
})
titulo: string

@ApiProperty()
@ApiProperty({
example: '2024-11-11T00:00:00Z',
description: 'Creation date in ISO format',
})
createdAt: string

@ApiProperty()
@ApiProperty({
type: () => AnsoffProductDto,
isArray: true,
description: 'List of products associated with the project',
})
productos: AnsoffProductDto[]
}

export class AnsoffProductDto {
@ApiProperty()
@ApiProperty({
example: '654321',
description: 'Unique identifier for the product',
})
_id: string

@ApiProperty()
@ApiProperty({
example: 'Product Name',
description: 'Name of the product',
})
nombre: string

@ApiProperty({ enum: SituacionDelMercado })
@ApiProperty({
enum: SituacionDelMercado,
example: SituacionDelMercado.MERCADO_EXISTENTE,
description: 'Market situation of the product',
})
situacionDelMercado: SituacionDelMercado

@ApiProperty({ enum: SituacionDelProducto })
@ApiProperty({
enum: SituacionDelProducto,
example: SituacionDelProducto.PRODUCTO_EXISTENTE,
description: 'Product situation in the market',
})
situacionDelProducto: SituacionDelProducto

@ApiProperty({ enum: Exito })
@ApiProperty({
enum: Exito,
example: Exito.MUY_EXITOSO,
description: 'Success level of the product',
})
exito: Exito

@ApiProperty({ enum: Estrategia })
@ApiProperty({
enum: Estrategia,
example: Estrategia.PENETRACION,
description:
'Strategy associated with the product based on market and product situation',
})
estrategia: Estrategia
}
34 changes: 28 additions & 6 deletions src/herramientas/ansoff/estrategia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,52 @@ import { Producto } from './ansoff.schema'
import { SituacionDelMercado } from './situacionDelMercado'
import { SituacionDelProducto } from './situacionDelProducto'

/**
* Enum representing the possible strategies based on market and product situation.
*/
export enum Estrategia {
PENETRACION = 'Penetracion',
DIVERSIFICAICON = 'Diversificacion',
DESARROLLO_DE_PRODUCTO = 'Desarrollo de Producto',
DESARROLLO_DE_MERCADO = 'Desarrollo de Mercado',
}

/**
* Determines the strategy based on the market and product situation.
* @param situacionDelMercado - Current market situation
* @param situacionDelProducto - Current product situation
* @returns The appropriate strategy as per the Ansoff Matrix
*/
export function calculate(
situacionDelMercado: SituacionDelMercado,
situacionDelProducto: SituacionDelProducto
) {
): Estrategia {
switch (situacionDelMercado) {
case SituacionDelMercado.MERCADO_EXISTENTE:
if (situacionDelProducto == SituacionDelProducto.PRODUCTO_EXISTENTE)
if (
situacionDelProducto === SituacionDelProducto.PRODUCTO_EXISTENTE
) {
return Estrategia.PENETRACION
else return Estrategia.DESARROLLO_DE_PRODUCTO
} else {
return Estrategia.DESARROLLO_DE_PRODUCTO
}
case SituacionDelMercado.NUEVO:
if (situacionDelProducto == SituacionDelProducto.PRODUCTO_EXISTENTE)
if (
situacionDelProducto === SituacionDelProducto.PRODUCTO_EXISTENTE
) {
return Estrategia.DESARROLLO_DE_MERCADO
else return Estrategia.DIVERSIFICAICON
} else {
return Estrategia.DIVERSIFICAICON
}
}
}

export function calcularEstrategia(product: Producto) {
/**
* Calculates the strategy for a given product.
* @param product - The product for which the strategy needs to be calculated
* @returns The calculated strategy based on the product's market and product situation
*/
export function calcularEstrategia(product: Producto): Estrategia {
return calculate(
product.situacionDelMercado as SituacionDelMercado,
product.situacionDelProducto as SituacionDelProducto
Expand Down
Loading

0 comments on commit d405415

Please sign in to comment.