Skip to content

Commit

Permalink
Merge pull request #149/#141 from NicolasOmar/feature/create-a-pet-event
Browse files Browse the repository at this point in the history
Create a Pet Event | Back End
  • Loading branch information
NicolasOmar authored Dec 5, 2023
2 parents 60fc436 + 471245a commit 7e5f1e2
Show file tree
Hide file tree
Showing 17 changed files with 749 additions and 453 deletions.
876 changes: 466 additions & 410 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "my-pets-api",
"version": "0.2.9",
"version": "0.2.10",
"description": "GraphQL server based on NodeJs to give back-end support a web client based on React",
"author": "Nicolás Omar González Passerino",
"license": "MIT",
"private": false,
"homepage": "https://github.com/NicolasOmar/my-pets-api#readme",
"homepage": "https://my-pets-api.up.railway.app",
"repository": {
"type": "git",
"url": "git+https://github.com/NicolasOmar/my-pets-api.git"
Expand Down Expand Up @@ -33,11 +33,11 @@
"update:doctor": "npm run test:clean:dev && npm run build"
},
"dependencies": {
"@babel/cli": "^7.23.0",
"@babel/core": "^7.23.3",
"@babel/cli": "^7.23.4",
"@babel/core": "^7.23.5",
"@babel/node": "^7.22.19",
"@babel/plugin-transform-runtime": "^7.23.3",
"@babel/preset-env": "^7.23.3",
"@babel/plugin-transform-runtime": "^7.23.4",
"@babel/preset-env": "^7.23.5",
"apollo-server-errors": "^3.3.1",
"apollo-server-express": "^3.13.0",
"babel-plugin-import-graphql": "^2.8.1",
Expand All @@ -47,21 +47,21 @@
"graphql": "^16.8.1",
"hbs": "^4.2.0",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.0.0",
"mongoose": "^8.0.2",
"validator": "^13.11.0"
},
"devDependencies": {
"@babel/eslint-parser": "^7.23.3",
"@babel/register": "^7.22.15",
"env-cmd": "^10.1.0",
"eslint": "^8.53.0",
"eslint": "^8.55.0",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-node": "^11.1.0",
"graphql-depth-limit": "^1.1.0",
"husky": "^8.0.3",
"jest": "^29.7.0",
"lint-staged": "^15.1.0",
"nodemon": "^3.0.1",
"lint-staged": "^15.2.0",
"nodemon": "^3.0.2",
"prettier": "^3.1.0"
},
"engines": {
Expand Down
8 changes: 7 additions & 1 deletion src/constants/allowedFields.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
"hasHeterochromia",
"eyeColors",
"passedAway"
],
"EVENT": [
"description",
"date",
"associatedPets"
]
},
"ALLOWED_UPDATE": {
Expand All @@ -33,7 +38,8 @@
"hairColors",
"hasHeterochromia",
"eyeColors",
"passedAway"
"passedAway",
"events"
]
}
}
25 changes: 25 additions & 0 deletions src/db/models/event.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Schema, model } from 'mongoose'
// FUNCTIONS
import { parseErrorMsg } from '../../functions/parsers'

const eventSchema = new Schema({
description: {
type: String,
required: [true, parseErrorMsg.missingValue('Description', 'Event')],
minlength: [2, parseErrorMsg.minMaxValue('Name', 3, true)],
maxlength: [200, parseErrorMsg.minMaxValue('Name', 200, false)]
},
date: {
type: String,
required: [true, parseErrorMsg.missingValue('Date', 'Event')]
},
associatedPets: {
type: [Schema.Types.ObjectId],
required: [true, parseErrorMsg.missingValue('Pet', 'Event')],
ref: 'Pet'
}
})

const Event = model('Event', eventSchema)

export default Event
4 changes: 4 additions & 0 deletions src/db/models/pet.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ const petSchema = new Schema({
type: Schema.Types.ObjectId,
required: true,
ref: 'User'
},
events: {
type: [Schema.Types.ObjectId],
ref: 'Event'
}
})

Expand Down
5 changes: 4 additions & 1 deletion src/functions/mocks/dbOps.mocks.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
"passedAway": false
},
"petType": ["Cat", "Dog"],
"color": ["White", "Black", "Brown", "Beige", "Grey"]
"color": ["White", "Black", "Brown", "Beige", "Grey"],
"event": {
"description": "Created event for test pet"
}
},
"prodEnv": {
"petType": ["Cat", "Dog"],
Expand Down
23 changes: 16 additions & 7 deletions src/functions/parsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,24 @@ export const parseErrorMsg = {
noIdeaCode: code => `No idea dude, the code ${code} has not been mapped so far`
}

export const parsedAuxiliaryData = ({ _id: id, name }) => ({ id, name })
export const findByIds = async ({
model,
ids,
findOne = false,
parser = '_id name',
parseId = false
}) => {
const findedData = findOne
? await model.findOne({ _id: ids }, parser)
: await model.find().where('_id').in(ids).select(parser)

export const findIds = async (model, ids, findOne = false) => {
if (findOne) {
const modelFinded = await model.findOne({ _id: ids })
return parsedAuxiliaryData(modelFinded)
if (parseId) {
return findOne
? { id: findedData._id, name: findedData.name }
: findedData.map(({ _id, name }) => ({ id: _id, name }))
} else {
return findedData
}

return (await model.find().where('_id').in(ids)).map(data => parsedAuxiliaryData(data))
}

export const parseUniqueArray = (list, callback) =>
Expand Down
34 changes: 24 additions & 10 deletions src/graphql/resolvers/Mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ApolloError } from 'apollo-server-errors'
// DB MODELS
import User from '../../db/models/user.model'
import Pet from '../../db/models/pet.model'
import Event from '../../db/models/event.model'
// FUNCTIONS
import { checkAllowedUpdates, parseError, parseErrorMsg } from '../../functions/parsers'
import { decryptPass } from '../../functions/encrypt'
Expand Down Expand Up @@ -148,17 +149,30 @@ const Mutations = {
} catch (error) {
throw new ApolloError(parseError(error, 'Pet'), HTTP_CODES.INTERNAL_ERROR_SERVER)
}
},
createEvent: async (_, { eventInfo }, { loggedUser }) => {
if (!loggedUser) {
throw new ApolloError(ERROR_MSGS.MISSING_USER_DATA, HTTP_CODES.UNAUTHORIZED)
}

if (!checkAllowedUpdates(eventInfo, ALLOWED_CREATE.EVENT)) {
throw new ApolloError(ERROR_MSGS.UPDATES, HTTP_CODES.UNPROCESSABLE_ENTITY)
}

try {
const parsedNewEvent = new Event(eventInfo)
await parsedNewEvent.save()
const { events } = await Pet.findById(eventInfo.associatedPets[0])
await Pet.findOneAndUpdate(
{ _id: eventInfo.associatedPets[0] },
{ events: [...events, parsedNewEvent._id] }
)

return parsedNewEvent.toJSON()
} catch (error) {
throw new ApolloError(parseError(error, 'Event'), HTTP_CODES.INTERNAL_ERROR_SERVER)
}
}
// logoutAll: async(_, __, { loggedUser }) => {
// try {
// loggedUser.tokens = []
// await loggedUser.save()
// return true
// } catch (error) {
// // response.status(500).send(error)
// return error
// }
// }
}

export default Mutations
16 changes: 11 additions & 5 deletions src/graphql/resolvers/Queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Pet from '../../db/models/pet.model'
import User from '../../db/models/user.model'
import { ApolloError } from 'apollo-server-errors'
import { ERROR_MSGS, HTTP_CODES } from '../../constants/errors.json'
import { findIds, parseUniqueArray } from '../../functions/parsers'
import { findByIds, parseUniqueArray } from '../../functions/parsers'

const Queries = {
getUser: async (_, __, { loggedUser, token }) => ({
Expand All @@ -22,9 +22,10 @@ const Queries = {
}

const { _id } = await User.findOne({ userName: loggedUser.userName })
const petFindQuery = query?.search
? { user: _id, name: new RegExp(query?.search) }
: { user: _id }
const petFindQuery =
query?.search && query?.search !== ''
? { user: _id, name: new RegExp(query?.search) }
: { user: _id }

return await Pet.find(petFindQuery)
},
Expand Down Expand Up @@ -54,7 +55,12 @@ const Queries = {
}

const petTypeInfo = Promise.allSettled(
petPopulation.map(pet => new Promise(resolve => resolve(findIds(PetType, pet.petType))))
petPopulation.map(
pet =>
new Promise(resolve =>
resolve(findByIds({ model: PetType, ids: pet.petType, parseId: true }))
)
)
)
const petTypeList = (await petTypeInfo).map(data => data.value[0].name)
const parsedPetTypeList = parseUniqueArray(petTypeList, info => ({
Expand Down
41 changes: 37 additions & 4 deletions src/graphql/resolvers/Relationships.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import Pet from '../../db/models/pet.model'
import User from '../../db/models/user.model'
import PetType from '../../db/models/petType.model'
import Color from '../../db/models/color.model'
import Event from '../../db/models/event.model'
// CONSTANTS
import { ALLOWED_CREATE } from '../../constants/allowedFields.json'
// FUNCTIONS
import { findIds } from '../../functions/parsers'
import { findByIds } from '../../functions/parsers'

const Relationships = {
User: {
Expand All @@ -15,9 +18,39 @@ const Relationships = {
},
Pet: {
user: async ({ user }) => await User.findById(user),
petType: async ({ petType }) => await findIds(PetType, petType, true),
hairColors: async ({ hairColors }) => await findIds(Color, hairColors),
eyeColors: async ({ eyeColors }) => await findIds(Color, eyeColors)
petType: async ({ petType }) =>
await findByIds({
model: PetType,
ids: petType,
findOne: true,
parseId: true
}),
hairColors: async ({ hairColors }) =>
await findByIds({
model: Color,
ids: hairColors,
parseId: true
}),
eyeColors: async ({ eyeColors }) =>
await findByIds({
model: Color,
ids: eyeColors,
parseId: true
}),
events: async ({ events }) =>
await findByIds({
model: Event,
ids: events,
parser: `_id ${ALLOWED_CREATE.EVENT.join(' ')}`
})
},
Event: {
associatedPets: async ({ associatedPets }) =>
await findByIds({
model: Pet,
ids: associatedPets,
parser: `_id ${ALLOWED_CREATE.PET.join(' ')}`
})
}
}

Expand Down
9 changes: 8 additions & 1 deletion src/graphql/resolvers/mocks/Mutations.mocks.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@
{ "field": "weight", "value": 150 },
{ "field": "gender", "value": "masculine" },
{ "field": "hasHeterochromia", "value": true },
{ "field": "passedAway", "value": false }
{ "field": "passedAway", "value": false },
{ "field": "events", "value": [] }
]
},
"createEvent": {
"events": [
{ "description": "First description" },
{ "description": "Second description" }
]
}
}
Loading

0 comments on commit 7e5f1e2

Please sign in to comment.