Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev to Main Sync #2349

Merged
merged 26 commits into from
Jan 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a256841
feat: Add api to create onboarding extension request from discord ser…
pankajjs Jan 4, 2025
444e34c
Add tests for create onboarding extension request api (#2306)
pankajjs Jan 6, 2025
07b8720
feat: Integrate userData into Progresses API to reduce redundant call…
AnujChhikara Jan 6, 2025
5c80de0
fix: Changed status code to 409 for sending Conflict response (#2339)
pankajjs Jan 9, 2025
5bc49c6
chore(#2342) - upgraded dependency packages
vikasosmium Jan 9, 2025
1ffa717
Revert "chore(#2342) - upgraded dependency packages" (#2343)
yesyash Jan 10, 2025
c4263c9
fix: Add support to fetch onboarding extension request (#2331)
pankajjs Jan 15, 2025
12a296f
Fix: skip users having approved onboarding extension when applying gr…
pankajjs Jan 15, 2025
22fd044
fix: negligent tagging instead of proposedStartDate, we are using cre…
Achintya-Chatterjee Jan 15, 2025
900ee7d
feat: Add feature to handle onboarding extension request approval or …
pankajjs Jan 16, 2025
a266acf
Feat: Update Node Version Latest LTS (#2350)
vikasosmium Jan 17, 2025
9d8bfd4
fix date query to fetch logs (#2348)
vinit717 Jan 18, 2025
6c5a1df
fix : change node version to `22.10.0` (#2354)
vikasosmium Jan 18, 2025
52822ad
fix : merge conflicts (#2356)
Achintya-Chatterjee Jan 18, 2025
e225baa
chore(#2342) - upgraded dependency packages
vikasosmium Jan 9, 2025
1e8194a
Revert "chore(#2342) - upgraded dependency packages" (#2343)
yesyash Jan 10, 2025
fd8d4c5
fix: Add support to fetch onboarding extension request (#2331)
pankajjs Jan 15, 2025
2f1339d
Fix: skip users having approved onboarding extension when applying gr…
pankajjs Jan 15, 2025
eed35b6
fix: negligent tagging instead of proposedStartDate, we are using cre…
Achintya-Chatterjee Jan 15, 2025
5170a23
feat: Add feature to handle onboarding extension request approval or …
pankajjs Jan 16, 2025
c79e3cc
Feat: Update Node Version Latest LTS (#2350)
vikasosmium Jan 17, 2025
3dc056d
fix date query to fetch logs (#2348)
vinit717 Jan 18, 2025
f2b27db
fix : change node version to `22.10.0` (#2354)
vikasosmium Jan 18, 2025
43e8466
fix : merge conflicts (#2356)
Achintya-Chatterjee Jan 18, 2025
ad841d7
Merge branch 'develop' into yash/merge-conflicts
Achintya-Chatterjee Jan 18, 2025
2aaed8f
Merge pull request #2357 from Real-Dev-Squad/yash/merge-conflicts
yesyash Jan 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

strategy:
matrix:
node-version: [20.11.x]
node-version: [22.10.0]

steps:
- uses: actions/checkout@v3
Expand Down
86 changes: 82 additions & 4 deletions controllers/onboardingExtension.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
import {
ERROR_WHILE_CREATING_REQUEST,
ERROR_WHILE_UPDATING_REQUEST,
LOG_ACTION,
ONBOARDING_REQUEST_CREATED_SUCCESSFULLY,
REQUEST_ALREADY_PENDING,
REQUEST_APPROVED_SUCCESSFULLY,
REQUEST_DOES_NOT_EXIST,
REQUEST_LOG_TYPE,
REQUEST_REJECTED_SUCCESSFULLY,
REQUEST_STATE,
REQUEST_TYPE,
UNAUTHORIZED_TO_CREATE_ONBOARDING_EXTENSION_REQUEST,
} from "../constants/requests";
import { userState } from "../constants/userStatus";
import { addLog } from "../services/logService";
import { createRequest, getRequestByKeyValues } from "../models/requests";
import { createRequest, getRequestByKeyValues, updateRequest } from "../models/requests";
import { fetchUser } from "../models/users";
import { getUserStatus } from "../models/userStatus";
import { User } from "../typeDefinitions/users";
import {
CreateOnboardingExtensionBody,
OnboardingExtension,
OnboardingExtensionCreateRequest,
OnboardingExtensionResponse
OnboardingExtensionResponse,
UpdateOnboardingExtensionStateRequest,
UpdateOnboardingExtensionStateRequestBody
} from "../types/onboardingExtension";
import { convertDateStringToMilliseconds, getNewDeadline } from "../utils/requests";
import { convertDaysToMilliseconds } from "../utils/time";
Expand All @@ -34,7 +40,11 @@ import { convertDaysToMilliseconds } from "../utils/time";
* @param {OnboardingExtensionResponse} res - The Express response object used to send back the response.
* @returns {Promise<OnboardingExtensionResponse>} Resolves to a response with the status and data or an error message.
*/
export const createOnboardingExtensionRequestController = async (req: OnboardingExtensionCreateRequest, res: OnboardingExtensionResponse): Promise<OnboardingExtensionResponse> => {
export const createOnboardingExtensionRequestController = async (
req: OnboardingExtensionCreateRequest,
res: OnboardingExtensionResponse )
: Promise<OnboardingExtensionResponse> => {

try {

const data = req.body as CreateOnboardingExtensionBody;
Expand Down Expand Up @@ -121,4 +131,72 @@ export const createOnboardingExtensionRequestController = async (req: Onboarding
logger.error(ERROR_WHILE_CREATING_REQUEST, err);
return res.boom.badImplementation(ERROR_WHILE_CREATING_REQUEST);
}
};
};

/**
* Updates the state of an onboarding extension request.
*
* @param {UpdateOnboardingExtensionStateRequest} req - The request object containing the update details.
* @param {OnboardingExtensionResponse} res - The response object to send the result of the update.
* @returns {Promise<OnboardingExtensionResponse>} Sends the response with the result of the update operation.
*/
export const updateOnboardingExtensionRequestState = async (
req: UpdateOnboardingExtensionStateRequest,
res: OnboardingExtensionResponse )
: Promise<OnboardingExtensionResponse> => {

const dev = req.query.dev === "true";

if(!dev) return res.boom.notImplemented("Feature not implemented");

const body = req.body as UpdateOnboardingExtensionStateRequestBody;
const lastModifiedBy = req?.userData?.id;
const extensionId = req.params.id;

let requestBody: UpdateOnboardingExtensionStateRequestBody = {
state: body.state,
type: body.type,
}

if(body.message){
requestBody = { ...requestBody, message: body.message };
}

try {
const response = await updateRequest(extensionId, requestBody, lastModifiedBy, REQUEST_TYPE.ONBOARDING);

if ("error" in response) {
if (response.error === REQUEST_DOES_NOT_EXIST) {
return res.boom.notFound(response.error);
}
return res.boom.badRequest(response.error);
}

const [logType, returnMessage] = response.state === REQUEST_STATE.APPROVED
? [REQUEST_LOG_TYPE.REQUEST_APPROVED, REQUEST_APPROVED_SUCCESSFULLY]
: [REQUEST_LOG_TYPE.REQUEST_REJECTED, REQUEST_REJECTED_SUCCESSFULLY];

const requestLog = {
type: logType,
meta: {
requestId: extensionId,
action: LOG_ACTION.UPDATE,
createdBy: lastModifiedBy,
},
body: response,
};

await addLog(requestLog.type, requestLog.meta, requestLog.body);

return res.status(200).json({
message: returnMessage,
data: {
id: response.id,
...response,
},
});
}catch(error){
logger.error(ERROR_WHILE_UPDATING_REQUEST, error);
return res.boom.badImplementation(ERROR_WHILE_UPDATING_REQUEST);
}
}
8 changes: 6 additions & 2 deletions controllers/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { createTaskExtensionRequest, updateTaskExtensionRequest } from "./extens
import { UpdateRequest } from "../types/requests";
import { TaskRequestRequest } from "../types/taskRequests";
import { createTaskRequestController } from "./taskRequestsv2";
import { OnboardingExtensionCreateRequest, OnboardingExtensionResponse } from "../types/onboardingExtension";
import { createOnboardingExtensionRequestController } from "./onboardingExtension";
import { OnboardingExtensionCreateRequest, OnboardingExtensionResponse, UpdateOnboardingExtensionStateRequest } from "../types/onboardingExtension";
import { createOnboardingExtensionRequestController, updateOnboardingExtensionRequestState } from "./onboardingExtension";

export const createRequestController = async (
req: OooRequestCreateRequest | ExtensionRequestRequest | TaskRequestRequest | OnboardingExtensionCreateRequest,
Expand All @@ -30,6 +30,8 @@ export const createRequestController = async (
return await createTaskRequestController(req as TaskRequestRequest, res as CustomResponse);
case REQUEST_TYPE.ONBOARDING:
return await createOnboardingExtensionRequestController(req as OnboardingExtensionCreateRequest, res as OnboardingExtensionResponse);
case REQUEST_TYPE.ONBOARDING:
return await createOnboardingExtensionRequestController(req as OnboardingExtensionCreateRequest, res as OnboardingExtensionResponse);
default:
return res.boom.badRequest("Invalid request type");
}
Expand All @@ -42,6 +44,8 @@ export const updateRequestController = async (req: UpdateRequest, res: CustomRes
return await updateOooRequestController(req as UpdateRequest, res as ExtensionRequestResponse);
case REQUEST_TYPE.EXTENSION:
return await updateTaskExtensionRequest(req as UpdateRequest, res as ExtensionRequestResponse);
case REQUEST_TYPE.ONBOARDING:
return await updateOnboardingExtensionRequestState(req as unknown as UpdateOnboardingExtensionStateRequest, res as OnboardingExtensionResponse);
default:
return res.boom.badRequest("Invalid request type");
}
Expand Down
5 changes: 3 additions & 2 deletions middlewares/validators/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ export const updateRequestsMiddleware = async (
.messages({
"any.only": "state must be APPROVED or REJECTED",
}),
type: joi.string().valid(REQUEST_TYPE.OOO, REQUEST_TYPE.EXTENSION).required(),
type: joi.string().valid(REQUEST_TYPE.OOO, REQUEST_TYPE.EXTENSION, REQUEST_TYPE.ONBOARDING).required(),
message: joi.string().optional()
});

try {
Expand All @@ -84,7 +85,7 @@ export const getRequestsMiddleware = async (req: OooRequestCreateRequest, res: O
id: joi.string().optional(),
type: joi
.string()
.valid(REQUEST_TYPE.OOO, REQUEST_TYPE.EXTENSION, REQUEST_TYPE.TASK, REQUEST_TYPE.ALL)
.valid(REQUEST_TYPE.OOO, REQUEST_TYPE.EXTENSION, REQUEST_TYPE.TASK, REQUEST_TYPE.ALL, REQUEST_TYPE.ONBOARDING)
.optional(),
requestedBy: joi.string().insensitive().optional(),
state: joi
Expand Down
52 changes: 51 additions & 1 deletion models/discordactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
const discordService = require("../services/discordService");
const { buildTasksQueryForMissedUpdates } = require("../utils/tasks");
const { buildProgressQueryForMissedUpdates } = require("../utils/progresses");
const { getRequestByKeyValues } = require("./requests");
const { REQUEST_TYPE, REQUEST_STATE } = require("../constants/requests");
const allMavens = [];

/**
Expand Down Expand Up @@ -550,7 +552,7 @@

for (let i = 0; i < nicknameUpdateBatches.length; i++) {
const promises = [];
const usersStatusDocsBatch = nicknameUpdateBatches[i];

Check warning on line 555 in models/discordactions.js

View workflow job for this annotation

GitHub Actions / build (22.10.0)

Variable Assigned to Object Injection Sink
usersStatusDocsBatch.forEach((document) => {
const doc = document.data();
const userId = doc.userId;
Expand Down Expand Up @@ -753,12 +755,59 @@
};
};

/**
* Filters out onboarding users who have an approved onboarding extension request that is still valid.
*
* This function iterates through the given list of onboarding users and checks if each user has a valid
* approved onboarding extension request. If a valid extension request exists with a `newEndsOn`
* date greater than the current date, the user is skipped. Otherwise, the user is added to the
* returned list.
*
* @async
* @function skipOnboardingUsersHavingApprovedExtensionRequest
* @param {Array<Object>} [users=[]] - An array of user objects to be filtered. Each user object
* must have an `id` property.
* @returns {Promise<Array<Object>>} A promise that resolves to an array of users who do not have
* a valid approved onboarding extension request.
*/
const skipOnboardingUsersHavingApprovedExtensionRequest = async (users = []) => {
const currentTime = Date.now();

const results = await Promise.all(
users.map(async (user) => {
try {
const latestApprovedExtension = await getRequestByKeyValues({
type: REQUEST_TYPE.ONBOARDING,
state: REQUEST_STATE.APPROVED,
userId: user.id,
});

if (latestApprovedExtension && latestApprovedExtension.newEndsOn > currentTime) {
return null;
}

return user;
} catch (error) {
logger.error(`Error while fetching latest approved extension for user ${user.id}:`, error);
return null;
}
})
);

return results.filter(Boolean);
};

const updateUsersWith31DaysPlusOnboarding = async () => {
try {
const allOnboardingUsers31DaysCompleted = await getUsersBasedOnFilter({
let allOnboardingUsers31DaysCompleted = await getUsersBasedOnFilter({
state: userState.ONBOARDING,
time: "31d",
});

allOnboardingUsers31DaysCompleted = await skipOnboardingUsersHavingApprovedExtensionRequest(
allOnboardingUsers31DaysCompleted
);

const discordMembers = await getDiscordMembers();
const groupOnboardingRole = await getGroupRole("group-onboarding-31d+");
const groupOnboardingRoleId = groupOnboardingRole.role.roleid;
Expand Down Expand Up @@ -1131,4 +1180,5 @@
addInviteToInviteModel,
groupUpdateLastJoinDate,
deleteGroupRole,
skipOnboardingUsersHavingApprovedExtensionRequest,
};
14 changes: 9 additions & 5 deletions models/logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,20 +193,24 @@ const fetchAllLogs = async (query) => {
throw error;
}

const buildTimestamp = (date) => ({
_seconds: Math.floor(date / 1000),
_nanoseconds: 0,
const buildTimestamp = (milliseconds) => ({
_seconds: Math.floor(milliseconds / 1000),
_nanoseconds: (milliseconds % 1000) * 1000000,
});

if (startDate) {
requestQuery = requestQuery.where("timestamp", ">=", buildTimestamp(startDate));
const startTimestamp = buildTimestamp(startDate);
requestQuery = requestQuery.where("timestamp._seconds", ">=", startTimestamp._seconds);
}

if (endDate) {
requestQuery = requestQuery.where("timestamp", "<=", buildTimestamp(endDate));
const endTimestamp = buildTimestamp(endDate);
requestQuery = requestQuery.where("timestamp._seconds", "<=", endTimestamp._seconds);
}
}

requestQuery = requestQuery.orderBy("timestamp", "desc");

let requestQueryDoc = requestQuery;

if (prev) {
Expand Down
10 changes: 8 additions & 2 deletions models/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ export const updateRequest = async (id: string, body: any, lastModifiedBy: strin

export const getRequests = async (query: any) => {
let { id, type, requestedBy, state, prev, next, page, size = SIZE } = query;
const dev = query.dev === "true";

size = parseInt(size);
page = parseInt(page);
try {
Expand All @@ -86,11 +88,15 @@ export const getRequests = async (query: any) => {
...requestDoc.data(),
};
}

if (requestedBy) {

if(requestedBy && dev){
requestQuery = requestQuery.where("requestedBy", "==", requestedBy);
}
else if (requestedBy) {
const requestedByUserId = await getUserId(requestedBy);
requestQuery = requestQuery.where("requestedBy", "==", requestedByUserId);
}

if (type) {
requestQuery = requestQuery.where("type", "==", type);
}
Expand Down
Loading
Loading