-
-
Notifications
You must be signed in to change notification settings - Fork 884
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for user family members (#1810)
* added all the code * new commit * new commit * fix linting * fix linting * fix linting
- Loading branch information
1 parent
cc5872e
commit fa10711
Showing
32 changed files
with
1,839 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[ | ||
{ | ||
"_id": "60f18f31b7e5c4a2a4c3f905", | ||
"title": "Smith Family", | ||
"users": [ | ||
"64378abd85008f171cf2990d", | ||
"65378abd85008f171cf2990d", | ||
"66378abd85008f171cf2990d" | ||
] | ||
}, | ||
{ | ||
"_id": "60f18f31b7e5c4a2a4c3f906", | ||
"title": "Johnson Family", | ||
"users": [ | ||
"66378abd85008f171cf2990d", | ||
"65378abd85008f171cf2990d", | ||
"64378abd85008f171cf2990d" | ||
] | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import type { PopulatedDoc, Types, Document, Model } from "mongoose"; | ||
import { Schema, model, models } from "mongoose"; | ||
import type { InterfaceUser } from "./User"; | ||
/** | ||
* This is an interface that represents a database(MongoDB) document for Family. | ||
*/ | ||
|
||
export interface InterfaceUserFamily { | ||
_id: Types.ObjectId; | ||
title: string; | ||
users: PopulatedDoc<InterfaceUser & Document>[]; | ||
admins: PopulatedDoc<InterfaceUser & Document>[]; | ||
creator: PopulatedDoc<InterfaceUser & Document>[]; | ||
} | ||
|
||
/** | ||
* @param title - Name of the user Family (type: String) | ||
* Description: Name of the user Family. | ||
*/ | ||
|
||
/** | ||
* @param users - Members associated with the user Family (type: String) | ||
* Description: Members associated with the user Family. | ||
*/ | ||
const userFamilySchema = new Schema({ | ||
title: { | ||
type: String, | ||
required: true, | ||
}, | ||
users: [ | ||
{ | ||
type: Schema.Types.ObjectId, | ||
ref: "User", | ||
required: true, | ||
}, | ||
], | ||
admins: [ | ||
{ | ||
type: Schema.Types.ObjectId, | ||
ref: "User", | ||
required: true, | ||
}, | ||
], | ||
creator: { | ||
type: Schema.Types.ObjectId, | ||
ref: "User", | ||
required: true, | ||
}, | ||
}); | ||
|
||
const userFamilyModel = (): Model<InterfaceUserFamily> => | ||
model<InterfaceUserFamily>("UserFamily", userFamilySchema); | ||
|
||
// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. | ||
export const UserFamily = (models.UserFamily || | ||
userFamilyModel()) as ReturnType<typeof userFamilyModel>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import "dotenv/config"; | ||
import type { MutationResolvers } from "../../types/generatedGraphQLTypes"; | ||
import { errors, requestContext } from "../../libraries"; | ||
import { adminCheck } from "../../utilities/userFamilyAdminCheck"; | ||
import { User } from "../../models"; | ||
import { UserFamily } from "../../models/userFamily"; | ||
import { | ||
USER_FAMILY_NOT_FOUND_ERROR, | ||
USER_ALREADY_MEMBER_ERROR, | ||
USER_NOT_FOUND_ERROR, | ||
} from "../../constants"; | ||
/** | ||
* This function adds user to the family. | ||
* @param _parent - parent of current request | ||
* @param args - payload provided with the request | ||
* @param context - context of the entire application | ||
* @remarks The following checks are done: | ||
* 1. If the family exists | ||
* 2. If the user exists | ||
* 3. If the user is already member of the family | ||
* 4. If the user is admin of the user Family | ||
* @returns Updated family | ||
*/ | ||
export const addUserToUserFamily: MutationResolvers["addUserToUserFamily"] = | ||
async (_parent, args, context) => { | ||
const userFamily = await UserFamily.findOne({ | ||
_id: args.familyId, | ||
}).lean(); | ||
|
||
const currentUser = await User.findById({ | ||
_id: context.userId, | ||
}); | ||
|
||
// Checks whether user with _id === args.userId exists. | ||
if (currentUser === null) { | ||
throw new errors.NotFoundError( | ||
requestContext.translate(USER_NOT_FOUND_ERROR.MESSAGE), | ||
USER_NOT_FOUND_ERROR.CODE, | ||
USER_NOT_FOUND_ERROR.PARAM | ||
); | ||
} | ||
|
||
//check wheather family exists | ||
if (!userFamily) { | ||
throw new errors.NotFoundError( | ||
requestContext.translate(USER_FAMILY_NOT_FOUND_ERROR.MESSAGE), | ||
USER_FAMILY_NOT_FOUND_ERROR.CODE, | ||
USER_FAMILY_NOT_FOUND_ERROR.PARAM | ||
); | ||
} | ||
|
||
//check whether user is admin of the family | ||
await adminCheck(currentUser?._id, userFamily); | ||
|
||
const isUserMemberOfUserFamily = userFamily.users.some((user) => { | ||
user.equals(args.userId); | ||
}); | ||
|
||
// Checks whether user with _id === args.userId is already a member of Family. | ||
if (isUserMemberOfUserFamily) { | ||
throw new errors.ConflictError( | ||
requestContext.translate(USER_ALREADY_MEMBER_ERROR.MESSAGE), | ||
USER_ALREADY_MEMBER_ERROR.CODE, | ||
USER_ALREADY_MEMBER_ERROR.PARAM | ||
); | ||
} | ||
|
||
// Adds args.userId to users lists on family group and return the updated family. | ||
return await UserFamily.findOneAndUpdate( | ||
{ | ||
_id: args.familyId, | ||
}, | ||
{ | ||
$push: { | ||
users: args.userId, | ||
}, | ||
}, | ||
{ | ||
new: true, | ||
} | ||
).lean(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import type { MutationResolvers } from "../../types/generatedGraphQLTypes"; | ||
import { User } from "../../models"; | ||
import { errors, requestContext } from "../../libraries"; | ||
import { | ||
LENGTH_VALIDATION_ERROR, | ||
USER_FAMILY_MIN_MEMBERS_ERROR_CODE, | ||
USER_NOT_FOUND_ERROR, | ||
} from "../../constants"; | ||
import { isValidString } from "../../libraries/validators/validateString"; | ||
import { UserFamily } from "../../models/userFamily"; | ||
import { superAdminCheck } from "../../utilities"; | ||
/** | ||
* This Function enables to create a user Family | ||
* @param _parent - parent of current request | ||
* @param args - payload provided with the request | ||
* @param context - context of entire application | ||
* @remarks - The following checks are done: | ||
* 1. If the user exists | ||
* 2. If the user is super admin | ||
* 3. If there are atleast two members in the family. | ||
* @returns Created user Family | ||
*/ | ||
export const createUserFamily: MutationResolvers["createUserFamily"] = async ( | ||
_parent, | ||
args, | ||
context | ||
) => { | ||
const currentUser = await User.findById({ | ||
_id: context.userId, | ||
}); | ||
|
||
// Checks whether user with _id === args.userId exists. | ||
if (!currentUser) { | ||
throw new errors.NotFoundError( | ||
requestContext.translate(USER_NOT_FOUND_ERROR.MESSAGE), | ||
USER_NOT_FOUND_ERROR.CODE, | ||
USER_NOT_FOUND_ERROR.PARAM | ||
); | ||
} | ||
|
||
// Check whether the user is super admin. | ||
superAdminCheck(currentUser); | ||
|
||
let validationResultName = { | ||
isLessThanMaxLength: false, | ||
}; | ||
|
||
if (args && args.data && typeof args.data.title === "string") { | ||
validationResultName = isValidString(args.data.title, 256); | ||
} | ||
|
||
if (!validationResultName.isLessThanMaxLength) { | ||
throw new errors.InputValidationError( | ||
requestContext.translate( | ||
`${LENGTH_VALIDATION_ERROR.MESSAGE} 256 characters in name` | ||
), | ||
LENGTH_VALIDATION_ERROR.CODE | ||
); | ||
} | ||
|
||
// Check if there are at least 2 members | ||
if (args.data?.userIds.length < 2) { | ||
throw new errors.InputValidationError( | ||
requestContext.translate(USER_FAMILY_MIN_MEMBERS_ERROR_CODE.MESSAGE), | ||
USER_FAMILY_MIN_MEMBERS_ERROR_CODE.CODE, | ||
USER_FAMILY_MIN_MEMBERS_ERROR_CODE.PARAM | ||
); | ||
} | ||
|
||
const userfamilyTitle = args.data?.title; | ||
|
||
const createdUserFamily = await UserFamily.create({ | ||
...args.data, | ||
title: userfamilyTitle, | ||
users: [context.userId, ...args.data.userIds], | ||
admins: [context.userId], | ||
creator: context.userId, | ||
}); | ||
|
||
return createdUserFamily.toObject(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.