Skip to content

Commit

Permalink
Adding Advertisement feature in API (PalisadoesFoundation#1395)
Browse files Browse the repository at this point in the history
* Add: Advert model

* Add: Advert model

* Add: graphql types

* Add: createAd, removeAd, getAllAds

* 2

* 2

* Ad: 3

* Added: Typedefs

* Test: removeadvertisement

* test: get advertisement

* fix

* fix: errors

* updated add types
  • Loading branch information
SiddheshKukade authored Oct 19, 2023
1 parent 07248d6 commit b24c407
Show file tree
Hide file tree
Showing 22 changed files with 715 additions and 119 deletions.
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,4 @@ LOG_LEVEL = info

REDIS_HOST=
REDIS_PORT=
REDIS_PASSWORD=
279 changes: 163 additions & 116 deletions INSTALLATION.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"user.alreadyMember": "User is already a member",
"user.profileImage.notFound": "User profile image not found",
"task.notFound": "Task not found",
"advertisement.notFound": "Advertisement not found",
"event.notFound": "Event not found",
"eventProject.notFound": "Event project not found",
"organization.notFound": "Organization not found",
Expand Down
1 change: 1 addition & 0 deletions locales/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"user.alreadyMember": "उपयोगकर्ता पहले से ही एक सदस्य है",
"user.profileImage.notFound": "उपयोगकर्ता प्रोफ़ाइल छवि नहीं मिली",
"task.notFound": "कार्य नहीं मिला",
"advertisement.notFound": "विज्ञापन नहीं मिला",
"event.notFound": "घटना नहीं मिली",
"eventProject.notFound": "इवेंट प्रोजेक्ट नहीं मिला",
"organization.notFound": "संगठन नहीं मिला",
Expand Down
13 changes: 13 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ directive @auth on FIELD_DEFINITION

directive @role(requires: UserType) on FIELD_DEFINITION

type Advertisement {
_id: ID
endDate: Date!
link: String!
name: String!
orgId: ID
startDate: Date!
type: String!
}

type AggregatePost {
count: Int!
}
Expand Down Expand Up @@ -422,6 +432,7 @@ type Mutation {
cancelMembershipRequest(membershipRequestId: ID!): MembershipRequest!
checkIn(data: CheckInInput!): CheckIn!
createAdmin(data: UserAndOrganizationInput!): User!
createAdvertisement(endDate: Date!, link: String!, name: String!, orgId: ID!, startDate: Date!, type: String!): Advertisement!
createComment(data: CommentInput!, postId: ID!): Comment
createDirectChat(data: createChatInput!): DirectChat!
createDonation(amount: Float!, nameOfOrg: String!, nameOfUser: String!, orgId: ID!, payPalId: ID!, userId: ID!): Donation!
Expand Down Expand Up @@ -450,6 +461,7 @@ type Mutation {
rejectAdmin(id: ID!): Boolean!
rejectMembershipRequest(membershipRequestId: ID!): MembershipRequest!
removeAdmin(data: UserAndOrganizationInput!): User!
removeAdvertisement(id: ID!): Advertisement
removeComment(id: ID!): Comment
removeDirectChat(chatId: ID!, organizationId: ID!): DirectChat!
removeEvent(id: ID!): Event!
Expand Down Expand Up @@ -722,6 +734,7 @@ type Query {
event(id: ID!): Event
eventsByOrganization(id: ID, orderBy: EventOrderByInput): [Event]
eventsByOrganizationConnection(first: Int, orderBy: EventOrderByInput, skip: Int, where: EventWhereInput): [Event!]!
getAdvertisements: [Advertisement]
getDonationById(id: ID!): Donation!
getDonationByOrgId(orgId: ID!): [Donation]
getDonationByOrgIdConnection(first: Int, orgId: ID!, skip: Int, where: DonationWhereInput): [Donation!]!
Expand Down
7 changes: 6 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,12 @@ export const TASK_NOT_FOUND_ERROR = {
MESSAGE: "task.notFound",
PARAM: "task",
};

export const ADVERTISEMENT_NOT_FOUND_ERROR = {
DESC: "Advertisement not found",
CODE: "advertisement.notFound",
MESSAGE: "advertisement.notFound",
PARAM: "advertisement",
};
export const STATUS_ACTIVE = "ACTIVE";

export const URL =
Expand Down
81 changes: 81 additions & 0 deletions src/models/Advertisement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { Types, Model } from "mongoose";
import { Schema, model, models } from "mongoose";
/**
* This is an interface that represents a database(MongoDB) document for Advertisement.
*/
type AdvertisementTypes = {
type: "POPUP" | "MENU" | "BANNER";
// Other properties specific to each type
};
export interface InterfaceAdvertisement {
_id: Types.ObjectId;
orgId: string;
name: string;
link: string;
type: AdvertisementTypes;
startDate: string;
endDate: string;
}

/**
* @param name - Name of the advertisement (type: String)
* Description: Name of the advertisement.
*/

/**
* @param orgId - Organization ID associated with the advertisement (type: Schema.Types.ObjectId)
* Description: Organization ID associated with the advertisement.
*/

/**
* @param link - Link associated with the advertisement (type: String)
* Description: Link associated with the advertisement.
*/

/**
* @param type - Type of advertisement (POPUP, MENU, BANNER) (type: String)
* Description: Type of advertisement (POPUP, MENU, BANNER).
*/

/**
* @param startDate - Start date of the advertisement (type: Date)
* Description: Start date of the advertisement.
*/

/**
* @param endDate - End date of the advertisement (type: Date)
* Description: End date of the advertisement.
*/
const advertisementSchema = new Schema({
name: {
type: String,
required: true,
},
orgId: {
type: String,
},
link: {
type: String,
required: true,
},
type: {
type: String,
enum: ["POPUP", "MENU", "BANNER"],
required: true,
},
startDate: {
type: String,
required: true,
},
endDate: {
type: String,
required: true,
},
});

const advertisementModel = (): Model<InterfaceAdvertisement> =>
model<InterfaceAdvertisement>("Advertisement", advertisementSchema);

// This syntax is needed to prevent Mongoose OverwriteModelError while running tests.
export const Advertisement = (models.Advertisement ||
advertisementModel()) as ReturnType<typeof advertisementModel>;
1 change: 1 addition & 0 deletions src/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./Advertisement";
export * from "./CheckIn";
export * from "./MessageChat";
export * from "./Comment";
Expand Down
18 changes: 18 additions & 0 deletions src/resolvers/Mutation/createAdvertisement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { MutationResolvers } from "../../types/generatedGraphQLTypes";
import { Advertisement } from "../../models";
//eslint-disable-next-line @typescript-eslint/naming-convention
const { ObjectId } = require("mongodb");
// @ts-ignore
export const createAdvertisement: MutationResolvers["createAdvertisement"] =
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async (_parent, args, _context) => {
// Creates new Ad.
args.orgId = ObjectId(args.orgId);
args.startDate = new Date(args.startDate);
args.endDate = new Date(args.endDate);
const createdAd = await Advertisement.create({
...args,
});
// Returns createdAd.
return createdAd.toObject();
};
4 changes: 4 additions & 0 deletions src/resolvers/Mutation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { createGroupChat } from "./createGroupChat";
import { createMessageChat } from "./createMessageChat";
import { createOrganization } from "./createOrganization";
import { createPlugin } from "./createPlugin";
import { createAdvertisement } from "./createAdvertisement";
import { createPost } from "./createPost";
import { createTask } from "./createTask";
import { createUserTag } from "./createUserTag";
Expand All @@ -49,6 +50,7 @@ import { removeEvent } from "./removeEvent";
import { removeEventAttendee } from "./removeEventAttendee";
import { removeEventProject } from "./removeEventProject";
import { removeGroupChat } from "./removeGroupChat";
import { removeAdvertisement } from "./removeAdvertisement";
import { removeMember } from "./removeMember";
import { removeOrganization } from "./removeOrganization";
import { removeOrganizationImage } from "./removeOrganizationImage";
Expand Down Expand Up @@ -101,6 +103,7 @@ export const Mutation: MutationResolvers = {
createMember,
createAdmin,
createComment,
createAdvertisement,
createDirectChat,
createDonation,
createEvent,
Expand Down Expand Up @@ -131,6 +134,7 @@ export const Mutation: MutationResolvers = {
removeDirectChat,
removeEvent,
removeEventAttendee,
removeAdvertisement,
removeEventProject,
removeGroupChat,
removeMember,
Expand Down
28 changes: 28 additions & 0 deletions src/resolvers/Mutation/removeAdvertisement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { MutationResolvers } from "../../types/generatedGraphQLTypes";
import { errors, requestContext } from "../../libraries";
import { Advertisement } from "../../models";
import { ADVERTISEMENT_NOT_FOUND_ERROR } from "../../constants";

// @ts-ignore
export const removeAdvertisement: MutationResolvers["removeAdvertisement"] =
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async (_parent, args, _context) => {
const currentAd = await Advertisement.findOne({
_id: args.id ? args.id : "",
}).lean();

if (!currentAd) {
throw new errors.NotFoundError(
requestContext.translate(ADVERTISEMENT_NOT_FOUND_ERROR.MESSAGE),
ADVERTISEMENT_NOT_FOUND_ERROR.CODE,
ADVERTISEMENT_NOT_FOUND_ERROR.PARAM
);
}

// Deletes the ad.
await Advertisement.deleteOne({
_id: args.id ? args.id : "",
});
// Returns deleted ad.
return currentAd;
};
11 changes: 11 additions & 0 deletions src/resolvers/Query/getAdvertisements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { QueryResolvers } from "../../types/generatedGraphQLTypes";
import { Advertisement } from "../../models";

/**
* This function returns list of Advertisement from the database.
* @returns An object that contains a list of Ads.
*/
export const getAdvertisements: QueryResolvers["getAdvertisements"] =
async () => {
return await Advertisement.find().lean();
};
2 changes: 2 additions & 0 deletions src/resolvers/Query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { registeredEventsByUser } from "./registeredEventsByUser";
import { user } from "./user";
import { userLanguage } from "./userLanguage";
import { users } from "./users";
import { getAdvertisements } from "./getAdvertisements";
import { usersConnection } from "./usersConnection";

export const Query: QueryResolvers = {
Expand All @@ -32,6 +33,7 @@ export const Query: QueryResolvers = {
eventsByOrganization,
eventsByOrganizationConnection,
getDonationById,
getAdvertisements,
getDonationByOrgId,
getDonationByOrgIdConnection,
getlanguage,
Expand Down
2 changes: 1 addition & 1 deletion src/services/CommentCache/findCommentsByPostIdInCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export async function findCommentsByPostIdInCache(

const commentsFoundInCache = await CommentCache.mget(commentIDs);

const comments = commentsFoundInCache.map((comment) => {
const comments = commentsFoundInCache.map((comment: string | null) => {
if (comment === null) {
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion src/services/OrganizationCache/findOrganizationsInCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export async function findOrganizationsInCache(

const organizationFoundInCache = await OrganizationCache.mget(keys);

const organizations = organizationFoundInCache.map((org) => {
const organizations = organizationFoundInCache.map((org: string | null) => {
if (org === null) {
return null;
}
Expand Down
11 changes: 11 additions & 0 deletions src/typeDefs/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ export const mutations = gql`
uninstalledOrgs: [ID!]
): Plugin!
createAdvertisement(
orgId: ID!
name: String!
link: String!
type: String!
startDate: Date!
endDate: Date!
): Advertisement!
createPost(data: PostInput!, file: String): Post @auth
createUserTag(input: CreateUserTagInput!): UserTag @auth
Expand Down Expand Up @@ -134,6 +143,8 @@ export const mutations = gql`
removePost(id: ID!): Post @auth
removeAdvertisement(id: ID!): Advertisement
removeUserTag(id: ID!): UserTag @auth
removeTask(id: ID!): Task @auth
Expand Down
1 change: 1 addition & 0 deletions src/typeDefs/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const queries = gql`
getlanguage(lang_code: String!): [Translation]
getPlugins: [Plugin]
getAdvertisements: [Advertisement]
hasSubmittedFeedback(userId: ID!, eventId: ID!): Boolean
Expand Down
9 changes: 9 additions & 0 deletions src/typeDefs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ export const types = gql`
nameOfOrg: String!
amount: Float!
}
type Advertisement {
_id: ID
name: String!
orgId: ID
link: String!
type: String!
startDate: Date!
endDate: Date!
}
type ExtendSession {
accessToken: String!
Expand Down
Loading

0 comments on commit b24c407

Please sign in to comment.