From 170861a77366fdd4848429215200d2c288a38ecc Mon Sep 17 00:00:00 2001 From: Agustin <agusr1999@gmail.com> Date: Fri, 17 Sep 2021 13:12:39 -0300 Subject: [PATCH] Swagger updated with calculator path, parameter path not done yet Calculator controller now also logs errors. --- src/Controllers/CalculatorController.ts | 2 + src/Controllers/SheetController.ts | 48 +++--- src/Logger/logger.ts | 64 +++---- src/Services/SheetService.ts | 216 ++++++++++++------------ src/index.ts | 78 ++++----- swagger.yaml | 27 +++ 6 files changed, 232 insertions(+), 203 deletions(-) diff --git a/src/Controllers/CalculatorController.ts b/src/Controllers/CalculatorController.ts index d178be2..51a0f43 100644 --- a/src/Controllers/CalculatorController.ts +++ b/src/Controllers/CalculatorController.ts @@ -4,6 +4,7 @@ import { import AgeGroupJSON from '../DTOs/AgeGroupJSON'; import CalculatorService from '../Services/CalculatorService'; import CalculatorResponse from '../DTOs/CalculatorResponseDTO'; +import logger from '../Logger/logger'; const router = Router(); @@ -14,6 +15,7 @@ const getREP: Handler = async (req: Request, res: Response) => { return res.status(200).send(EnergyReq); } catch (error) { const e = error as Error; + logger.info(e.message); return res.status(400).json({ error: e.message }); } }; diff --git a/src/Controllers/SheetController.ts b/src/Controllers/SheetController.ts index 8d784ec..8658d81 100644 --- a/src/Controllers/SheetController.ts +++ b/src/Controllers/SheetController.ts @@ -1,24 +1,24 @@ -import { - Handler, Request, Response, Router, -} from 'express'; -import { SheetParserResponse } from '../Models/SheetParserResponse'; -import SheetService from '../Services/SheetService'; -import logger from '../Logger/logger'; - -const router = Router(); - -const parseSheet: Handler = async (req: Request, res: Response) => { - const sheet: Buffer = req.body; - try { - const parsedSheet: SheetParserResponse = SheetService.parseSheetService(sheet); - return res.status(200).send(parsedSheet); - } catch (error) { - const e = error as Error; - logger.info(e.message); - return res.status(400).json({ error: e.message }); - } -}; - -router.post('/', parseSheet); - -export default router; +import { + Handler, Request, Response, Router, +} from 'express'; +import { SheetParserResponse } from '../Models/SheetParserResponse'; +import SheetService from '../Services/SheetService'; +import logger from '../Logger/logger'; + +const router = Router(); + +const parseSheet: Handler = async (req: Request, res: Response) => { + const sheet: Buffer = req.body; + try { + const parsedSheet: SheetParserResponse = SheetService.parseSheetService(sheet); + return res.status(200).send(parsedSheet); + } catch (error) { + const e = error as Error; + logger.info(e.message); + return res.status(400).json({ error: e.message }); + } +}; + +router.post('/', parseSheet); + +export default router; diff --git a/src/Logger/logger.ts b/src/Logger/logger.ts index 1771549..e14b731 100644 --- a/src/Logger/logger.ts +++ b/src/Logger/logger.ts @@ -1,32 +1,32 @@ -import { - createLogger, format, transports, Logger, -} from 'winston'; - -const { - combine, timestamp, -} = format; - -const logger: Logger = createLogger({ - level: 'info', - format: combine( - timestamp(), - format.errors({ stack: true }), - format.json(), - ), - transports: [ - new transports.File({ - level: 'error', - filename: 'logs/error-logs', - maxsize: 104857600, // 100Mb - maxFiles: 3, - }), - new transports.File({ - level: 'info', - filename: 'logs/info-logs', - maxsize: 104857600, // 100Mb - maxFiles: 3, - }), - ], -}); - -export default logger; +import { + createLogger, format, transports, Logger, +} from 'winston'; + +const { + combine, timestamp, +} = format; + +const logger: Logger = createLogger({ + level: 'info', + format: combine( + timestamp(), + format.errors({ stack: true }), + format.json(), + ), + transports: [ + new transports.File({ + level: 'error', + filename: 'logs/error-logs', + maxsize: 104857600, // 100Mb + maxFiles: 3, + }), + new transports.File({ + level: 'info', + filename: 'logs/info-logs', + maxsize: 104857600, // 100Mb + maxFiles: 3, + }), + ], +}); + +export default logger; diff --git a/src/Services/SheetService.ts b/src/Services/SheetService.ts index 947b1b0..e30e75a 100644 --- a/src/Services/SheetService.ts +++ b/src/Services/SheetService.ts @@ -1,108 +1,108 @@ -import * as XLSX from 'xlsx'; -import { SheetNames } from '../Config/Constants'; -import { - SheetParserResponse, Menores, Mayores, MenoresSheet, MayoresSheet, -} from '../Models/SheetParserResponse'; - -/* PRIVATE FUNCTIONS */ -// const ec = (r: number, c: number): string => XLSX.utils.encode_cell({ r, c }); -// const deleteRow = (ws: XLSX.WorkSheet, rowIndex: number): XLSX.WorkSheet => { -// const work = ws; -// if (work['!ref'] === undefined) throw new Error('An error has ocurred in deleteRow'); -// const variable = XLSX.utils.decode_range(work['!ref']); -// for (let R = rowIndex; R < variable.e.r; R += 1) { -// for (let C = variable.s.c; C <= variable.e.c; C += 1) { -// work[ec(R, C)] = work[ec(R + 1, C)]; -// } -// } -// variable.e.r -= 1; -// work['!ref'] = XLSX.utils.encode_range(variable.s, variable.e); -// return work; -// }; - -const parseAdults = (worksheet: XLSX.WorkSheet): Mayores[] => { - const res: Mayores[] = []; - const ref = worksheet['!ref']; - if (ref === undefined) throw new Error('An error ocurred'); - const range = XLSX.utils.decode_range(ref); - range.s.c = 0; - range.e.c = 2; - const newRange = XLSX.utils.encode_range(range); - - const aux = XLSX.utils.sheet_to_json(worksheet, { range: newRange }) as unknown as MayoresSheet[]; - - aux.forEach((element: MayoresSheet) => { - res.push( - { - edad: element['Edad (años)'], - peso: element['Peso (Kg)'], - talla: element['Talla (cm)'], - }, - ); - }); - return res; -}; - -const parseBabies = (worksheet: XLSX.WorkSheet): Menores[] => { - const res: Menores[] = []; - const aux = XLSX.utils.sheet_to_json(worksheet) as unknown as MenoresSheet[]; - aux.forEach((element: MenoresSheet) => { - res.push( - { - edad: element['Edad (meses)'], - peso: element['Peso (Kg)'], - }, - ); - }); - return res; -}; - -/* EXPORT FUNCTIONS */ - -const parseSheetService = (data: Buffer): SheetParserResponse => { - const workbook: XLSX.WorkBook = XLSX.read(data); - let parsed: SheetParserResponse = null; - let hombresMenores: Menores[] = []; - let hombres: Mayores[] = []; - let mujeresMenores: Menores[] = []; - let mujeres: Mayores[] = []; - - const sheetNames: string[] = workbook.SheetNames; - // Check there are 4 sheets, no more, no less - if (sheetNames.length !== 4) { - throw new Error('File does not respect scheme, there are more or less than 4 sheets'); - } - sheetNames.forEach((name) => { - const worksheet: XLSX.WorkSheet = workbook.Sheets[name]; - switch (name) { - case SheetNames.HOMBRES_MENORES: - hombresMenores = parseBabies(worksheet); - break; - case SheetNames.HOMBRES: - hombres = parseAdults(worksheet); - break; - case SheetNames.MUJERES_MENORES: - mujeresMenores = parseBabies(worksheet); - break; - case SheetNames.MUJERES: - mujeres = parseAdults(worksheet); - break; - - default: - throw new Error(`Sheet name ${name} is not part of the scheme `); - } - }); - parsed = { - hombresMenores, - hombres, - mujeresMenores, - mujeres, - }; - - return parsed; - // TODO: depends on sheet layout what to do -}; - -export default { - parseSheetService, -}; +import * as XLSX from 'xlsx'; +import { SheetNames } from '../Config/Constants'; +import { + SheetParserResponse, Menores, Mayores, MenoresSheet, MayoresSheet, +} from '../Models/SheetParserResponse'; + +/* PRIVATE FUNCTIONS */ +// const ec = (r: number, c: number): string => XLSX.utils.encode_cell({ r, c }); +// const deleteRow = (ws: XLSX.WorkSheet, rowIndex: number): XLSX.WorkSheet => { +// const work = ws; +// if (work['!ref'] === undefined) throw new Error('An error has ocurred in deleteRow'); +// const variable = XLSX.utils.decode_range(work['!ref']); +// for (let R = rowIndex; R < variable.e.r; R += 1) { +// for (let C = variable.s.c; C <= variable.e.c; C += 1) { +// work[ec(R, C)] = work[ec(R + 1, C)]; +// } +// } +// variable.e.r -= 1; +// work['!ref'] = XLSX.utils.encode_range(variable.s, variable.e); +// return work; +// }; + +const parseAdults = (worksheet: XLSX.WorkSheet): Mayores[] => { + const res: Mayores[] = []; + const ref = worksheet['!ref']; + if (ref === undefined) throw new Error('An error ocurred'); + const range = XLSX.utils.decode_range(ref); + range.s.c = 0; + range.e.c = 2; + const newRange = XLSX.utils.encode_range(range); + + const aux = XLSX.utils.sheet_to_json(worksheet, { range: newRange }) as unknown as MayoresSheet[]; + + aux.forEach((element: MayoresSheet) => { + res.push( + { + edad: element['Edad (años)'], + peso: element['Peso (Kg)'], + talla: element['Talla (cm)'], + }, + ); + }); + return res; +}; + +const parseBabies = (worksheet: XLSX.WorkSheet): Menores[] => { + const res: Menores[] = []; + const aux = XLSX.utils.sheet_to_json(worksheet) as unknown as MenoresSheet[]; + aux.forEach((element: MenoresSheet) => { + res.push( + { + edad: element['Edad (meses)'], + peso: element['Peso (Kg)'], + }, + ); + }); + return res; +}; + +/* EXPORT FUNCTIONS */ + +const parseSheetService = (data: Buffer): SheetParserResponse => { + const workbook: XLSX.WorkBook = XLSX.read(data); + let parsed: SheetParserResponse = null; + let hombresMenores: Menores[] = []; + let hombres: Mayores[] = []; + let mujeresMenores: Menores[] = []; + let mujeres: Mayores[] = []; + + const sheetNames: string[] = workbook.SheetNames; + // Check there are 4 sheets, no more, no less + if (sheetNames.length !== 4) { + throw new Error('File does not respect scheme, there are more or less than 4 sheets'); + } + sheetNames.forEach((name) => { + const worksheet: XLSX.WorkSheet = workbook.Sheets[name]; + switch (name) { + case SheetNames.HOMBRES_MENORES: + hombresMenores = parseBabies(worksheet); + break; + case SheetNames.HOMBRES: + hombres = parseAdults(worksheet); + break; + case SheetNames.MUJERES_MENORES: + mujeresMenores = parseBabies(worksheet); + break; + case SheetNames.MUJERES: + mujeres = parseAdults(worksheet); + break; + + default: + throw new Error(`Sheet name ${name} is not part of the scheme `); + } + }); + parsed = { + hombresMenores, + hombres, + mujeresMenores, + mujeres, + }; + + return parsed; + // TODO: depends on sheet layout what to do +}; + +export default { + parseSheetService, +}; diff --git a/src/index.ts b/src/index.ts index 30dad1b..6198782 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,39 +1,39 @@ -/* eslint-disable no-console */ -import express, { Application } from 'express'; -import 'dotenv/config'; -import cors from 'cors'; -import swaggerUi from 'swagger-ui-express'; -import helmet from 'helmet'; -import YAML from 'yamljs'; -import Routes from './routes'; -import logger from './Logger/logger'; - -const app: Application = express(); -const PORT = process.env.PORT || 8000; -app.use(helmet.hidePoweredBy()); -// swagger init -const swaggerDocument = YAML.load('./swagger.yaml'); -// middlewares -app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); - -app.use(express.json({ - limit: '50mb', -})); -app.use(express.urlencoded({ extended: false })); -app.use(cors({ - origin: '*', - methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', - preflightContinue: false, - optionsSuccessStatus: 204, -})); - -app.use(express.raw({ - limit: '50mb', -})); - -app.use(Routes); - -app.listen(PORT, (): void => { - console.log(`REPP Backend running here 👉 https://localhost:${PORT}`); - logger.info('Server initiated'); -}); +/* eslint-disable no-console */ +import express, { Application } from 'express'; +import 'dotenv/config'; +import cors from 'cors'; +import swaggerUi from 'swagger-ui-express'; +import helmet from 'helmet'; +import YAML from 'yamljs'; +import Routes from './routes'; +import logger from './Logger/logger'; + +const app: Application = express(); +const PORT = process.env.PORT || 8000; +app.use(helmet.hidePoweredBy()); +// swagger init +const swaggerDocument = YAML.load('./swagger.yaml'); +// middlewares +app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); + +app.use(express.json({ + limit: '50mb', +})); +app.use(express.urlencoded({ extended: false })); +app.use(cors({ + origin: '*', + methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', + preflightContinue: false, + optionsSuccessStatus: 204, +})); + +app.use(express.raw({ + limit: '50mb', +})); + +app.use(Routes); + +app.listen(PORT, (): void => { + console.log(`REPP Backend running here 👉 https://localhost:${PORT}`); + logger.info('Server initiated'); +}); diff --git a/swagger.yaml b/swagger.yaml index b424dc7..a531d9d 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -44,6 +44,23 @@ paths: description: Ok. security: - BearerAuth: [] + + /repCalculator: + post: + tags: + - Calculation + summary: Given population data calculates its energetic requirement + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AgeGroupJSON' + required: true + responses: + '200': + description: Ok. + security: + - BearerAuth: [] components: securitySchemes: BearerAuth: @@ -88,3 +105,13 @@ components: type: string pass: type: string + AgeGroupJSON: + properties: + edad: + type: string + sexo: + type: string + pesoMediano: + type: string + cantidad: + type: string \ No newline at end of file -- GitLab