Skip to content

Commit

Permalink
Post , Comment and Event Cache (PalisadoesFoundation#1388)
Browse files Browse the repository at this point in the history
* ioredis

* init

* org cache init

* org 2

* updating cache-1

* added types

* added few more improvements

* 2

* 3

* 3

* 4

* 4+5

* linting

* linting again

* added installation and setup guide

* added redis service in CI/CD

* redis port

* redis version

* installing redis to run tests

* PR workflow

* PR workflow

* added redis service to push workflow as well

* added hyperlinks to installation guide

* Improved INSTALLATION.md

* Updated INSTALLATION.md

* removed time logs

* format

* added null check

* rewrote tests

* fix linting warnings

* null check in tests

* Update INSTALLATION.md

* postCache init

* event and comment cache init

* hash comments based on their postIds

* comment post id hash done

* Post comments done

* like/remove comment tests done

* unlike comment and tests

* comment cache done

* comment cache done

* increase codecov

* added tests

* linting

* added additional cache points

* Event caching init

* Event caching implemented

* format

* removed the null check , removed console.log

* removed the any[] type def

* linting

* remove redundant check

* covered all files

* removed lint warnings

* rerun pre commit hooks

* log fix
  • Loading branch information
kb-0311 authored Sep 23, 2023
1 parent 853d0df commit 7a489b9
Show file tree
Hide file tree
Showing 44 changed files with 936 additions and 124 deletions.
29 changes: 23 additions & 6 deletions src/resolvers/Mutation/addEventAttendee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import {
} from "../../constants";
import type { MutationResolvers } from "../../types/generatedGraphQLTypes";
import { errors, requestContext } from "../../libraries";
import type { InterfaceEvent } from "../../models";
import { User, Event, EventAttendee } from "../../models";
import { findEventsInCache } from "../../services/EventCache/findEventInCache";
import { cacheEvents } from "../../services/EventCache/cacheEvents";
import { Types } from "mongoose";

export const addEventAttendee: MutationResolvers["addEventAttendee"] = async (
_parent,
Expand All @@ -25,20 +29,33 @@ export const addEventAttendee: MutationResolvers["addEventAttendee"] = async (
);
}

const currentEvent = await Event.findOne({
_id: args.data.eventId,
}).lean();
let event: InterfaceEvent | null;

const eventFoundInCache = await findEventsInCache([args.data.eventId]);

event = eventFoundInCache[0];

if (eventFoundInCache[0] === null) {
event = await Event.findOne({
_id: args.data.eventId,
}).lean();

if (event !== null) {
await cacheEvents([event]);
}
}

if (currentEvent === null) {
if (event === null) {
throw new errors.NotFoundError(
requestContext.translate(EVENT_NOT_FOUND_ERROR.MESSAGE),
EVENT_NOT_FOUND_ERROR.CODE,
EVENT_NOT_FOUND_ERROR.PARAM
);
}

const isUserEventAdmin = currentEvent.admins.some(
(admin) => admin.toString() === context.userId.toString()
const isUserEventAdmin = event.admins.some(
(admin) =>
admin === context.userID || Types.ObjectId(admin).equals(context.userId)
);

if (!isUserEventAdmin && currentUser.userType !== "SUPERADMIN") {
Expand Down
23 changes: 20 additions & 3 deletions src/resolvers/Mutation/adminRemoveEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import {
} from "../../constants";
import { findOrganizationsInCache } from "../../services/OrganizationCache/findOrganizationsInCache";
import { cacheOrganizations } from "../../services/OrganizationCache/cacheOrganizations";
import { findEventsInCache } from "../../services/EventCache/findEventInCache";
import { cacheEvents } from "../../services/EventCache/cacheEvents";
import { deleteEventFromCache } from "../../services/EventCache/deleteEventFromCache";
/**
* This function enables an admin to remove a event
* @param _parent - parent of current request
Expand All @@ -26,9 +29,21 @@ export const adminRemoveEvent: MutationResolvers["adminRemoveEvent"] = async (
args,
context
) => {
const event = await Event.findOne({
_id: args.eventId,
}).lean();
let event;

const eventFoundInCache = await findEventsInCache([args.eventId]);

event = eventFoundInCache[0];

if (event === null) {
event = await Event.findOne({
_id: args.eventId,
}).lean();

if (event !== null) {
await cacheEvents([event]);
}
}

// Checks whether event exists.
if (!event) {
Expand Down Expand Up @@ -101,6 +116,8 @@ export const adminRemoveEvent: MutationResolvers["adminRemoveEvent"] = async (
_id: event._id,
});

await deleteEventFromCache(event._id);

// Returns the deleted event.
return event;
};
25 changes: 21 additions & 4 deletions src/resolvers/Mutation/checkIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import {
} from "../../constants";
import type { MutationResolvers } from "../../types/generatedGraphQLTypes";
import { errors, requestContext } from "../../libraries";
import type { InterfaceEvent } from "../../models";
import { User, Event, EventAttendee, CheckIn } from "../../models";
import { findEventsInCache } from "../../services/EventCache/findEventInCache";
import { cacheEvents } from "../../services/EventCache/cacheEvents";
import { Types } from "mongoose";

export const checkIn: MutationResolvers["checkIn"] = async (
_parent,
Expand All @@ -26,9 +30,21 @@ export const checkIn: MutationResolvers["checkIn"] = async (
);
}

const currentEvent = await Event.findOne({
_id: args.data.eventId,
}).lean();
let currentEvent: InterfaceEvent | null;

const eventFoundInCache = await findEventsInCache([args.data.eventId]);

currentEvent = eventFoundInCache[0];

if (eventFoundInCache[0] === null) {
currentEvent = await Event.findOne({
_id: args.data.eventId,
}).lean();

if (currentEvent !== null) {
await cacheEvents([currentEvent]);
}
}

if (currentEvent === null) {
throw new errors.NotFoundError(
Expand All @@ -39,7 +55,8 @@ export const checkIn: MutationResolvers["checkIn"] = async (
}

const isUserEventAdmin = currentEvent.admins.some(
(admin) => admin.toString() === context.userId.toString()
(admin) =>
admin === context.userID || Types.ObjectId(admin).equals(context.userId)
);

if (!isUserEventAdmin && currentUser.userType !== "SUPERADMIN") {
Expand Down
13 changes: 12 additions & 1 deletion src/resolvers/Mutation/createComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { MutationResolvers } from "../../types/generatedGraphQLTypes";
import { User, Post, Comment } from "../../models";
import { errors, requestContext } from "../../libraries";
import { POST_NOT_FOUND_ERROR, USER_NOT_FOUND_ERROR } from "../../constants";
import { cacheComments } from "../../services/CommentCache/cacheComments";
import { cachePosts } from "../../services/PostCache/cachePosts";

/**
* This function enables to create comment.
Expand Down Expand Up @@ -50,18 +52,27 @@ export const createComment: MutationResolvers["createComment"] = async (
postId: args.postId,
});

await cacheComments([createdComment]);

// Increase commentCount by 1 on post's document with _id === args.postId.
await Post.updateOne(
const updatedPost = await Post.findOneAndUpdate(
{
_id: args.postId,
},
{
$inc: {
commentCount: 1,
},
},
{
new: true,
}
);

if (updatedPost !== null) {
await cachePosts([updatedPost]);
}

// Returns the createdComment.
return createdComment.toObject();
};
5 changes: 5 additions & 0 deletions src/resolvers/Mutation/createEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { getApps } from "firebase-admin/app";
import { isValidString } from "../../libraries/validators/validateString";
import { compareDates } from "../../libraries/validators/compareDates";
import { EventAttendee } from "../../models/EventAttendee";
import { cacheEvents } from "../../services/EventCache/cacheEvents";

const applicationDefault = credential.applicationDefault;

Expand Down Expand Up @@ -133,6 +134,10 @@ export const createEvent: MutationResolvers["createEvent"] = async (
organization: organization._id,
});

if (createdEvent !== null) {
await cacheEvents([createdEvent]);
}

await EventAttendee.create({
userId: currentUser._id.toString(),
eventId: createdEvent._id,
Expand Down
28 changes: 22 additions & 6 deletions src/resolvers/Mutation/createEventProject.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { MutationResolvers } from "../../types/generatedGraphQLTypes";
import type { InterfaceEventProject } from "../../models";
import type { InterfaceEvent, InterfaceEventProject } from "../../models";
import { User, EventProject, Event } from "../../models";
import { errors, requestContext } from "../../libraries";
import {
USER_NOT_FOUND_ERROR,
USER_NOT_AUTHORIZED_ERROR,
EVENT_NOT_FOUND_ERROR,
} from "../../constants";
import { findEventsInCache } from "../../services/EventCache/findEventInCache";
import { cacheEvents } from "../../services/EventCache/cacheEvents";
import { Types } from "mongoose";

/**
* This function enables to create an event project.
Expand Down Expand Up @@ -35,9 +38,21 @@ export const createEventProject: MutationResolvers["createEventProject"] =
);
}

const event = await Event.findOne({
_id: args.data.eventId,
}).lean();
let event: InterfaceEvent | null;

const eventFoundInCache = await findEventsInCache([args.data.eventId]);

event = eventFoundInCache[0];

if (eventFoundInCache[0] === null) {
event = await Event.findOne({
_id: args.data.eventId,
}).lean();

if (event !== null) {
await cacheEvents([event]);
}
}

// Checks whether event exists.
if (!event) {
Expand All @@ -48,8 +63,9 @@ export const createEventProject: MutationResolvers["createEventProject"] =
);
}

const currentUserIsEventAdmin = event.admins.some((admin) =>
admin.equals(context.userId)
const currentUserIsEventAdmin = event.admins.some(
(admin) =>
admin === context.userID || Types.ObjectId(admin).equals(context.userId)
);

// Checks whether currentUser with _id === context.userId is an admin of event.
Expand Down
6 changes: 5 additions & 1 deletion src/resolvers/Mutation/createPost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { uploadEncodedImage } from "../../utilities/encodedImageStorage/uploadEn
import { uploadEncodedVideo } from "../../utilities/encodedVideoStorage/uploadEncodedVideo";
import { findOrganizationsInCache } from "../../services/OrganizationCache/findOrganizationsInCache";
import { cacheOrganizations } from "../../services/OrganizationCache/cacheOrganizations";

import { cachePosts } from "../../services/PostCache/cachePosts";
/**
* This function enables to create a post.
* @param _parent - parent of current request
Expand Down Expand Up @@ -132,6 +132,10 @@ export const createPost: MutationResolvers["createPost"] = async (
videoUrl: uploadVideoFileName,
});

if (createdPost !== null) {
await cachePosts([createdPost]);
}

if (args.data.pinned) {
// Add the post to pinnedPosts of the organization
const updatedOrganizaiton = await Organization.findOneAndUpdate(
Expand Down
9 changes: 3 additions & 6 deletions src/resolvers/Mutation/leaveOrganization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,9 @@ export const leaveOrganization: MutationResolvers["leaveOrganization"] = async (
);
}

const currentUserIsOrganizationMember =
organization.members.length !== 0
? organization.members.some((member) =>
Types.ObjectId(member).equals(currentUser?._id)
)
: false;
const currentUserIsOrganizationMember = organization.members.some((member) =>
Types.ObjectId(member).equals(currentUser?._id)
);

// Checks whether currentUser is not a member of organzation.
if (!currentUserIsOrganizationMember) {
Expand Down
28 changes: 24 additions & 4 deletions src/resolvers/Mutation/likeComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { MutationResolvers } from "../../types/generatedGraphQLTypes";
import { User, Comment } from "../../models";
import { errors, requestContext } from "../../libraries";
import { COMMENT_NOT_FOUND_ERROR, USER_NOT_FOUND_ERROR } from "../../constants";
import { findCommentsInCache } from "../../services/CommentCache/findCommentsInCache";
import { cacheComments } from "../../services/CommentCache/cacheComments";
/**
* This function enables to like a post.
* @param _parent - parent of current request
Expand Down Expand Up @@ -31,9 +33,21 @@ export const likeComment: MutationResolvers["likeComment"] = async (
);
}

const comment = await Comment.findOne({
_id: args.id,
}).lean();
let comment;

const commentsFoundInCache = await findCommentsInCache([args.id]);

comment = commentsFoundInCache[0];

if (commentsFoundInCache.includes(null)) {
comment = await Comment.findOne({
_id: args.id,
}).lean();

if (comment !== null) {
await cacheComments([comment]);
}
}

// Checks whether comment exists.
if (!comment) {
Expand All @@ -54,7 +68,7 @@ export const likeComment: MutationResolvers["likeComment"] = async (
Adds context.userId to likedBy list and increases likeCount field by 1
of comment's document and returns the updated comment.
*/
return await Comment.findOneAndUpdate(
const updatedComment = await Comment.findOneAndUpdate(
{
_id: comment._id,
},
Expand All @@ -70,6 +84,12 @@ export const likeComment: MutationResolvers["likeComment"] = async (
new: true,
}
).lean();

if (updatedComment !== null) {
await cacheComments([updatedComment]);
}

return updatedComment;
}

// Returns the comment without liking.
Expand Down
Loading

0 comments on commit 7a489b9

Please sign in to comment.