From 1d7ab2af6967e7b9d0104b213fa5a6c6c65d672f Mon Sep 17 00:00:00 2001 From: x032205 Date: Mon, 8 Dec 2025 00:25:51 -0500 Subject: [PATCH] request & grant cleanup job --- backend/src/server/routes/index.ts | 9 +++-- .../approval-policy/approval-policy-dal.ts | 40 +++++++++++++++++-- .../resource-cleanup-queue.ts | 9 ++++- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index 792a310e0..382ff30d7 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -1927,6 +1927,9 @@ export const registerRoutes = async ( identityDAL }); + const approvalRequestDAL = approvalRequestDALFactory(db); + const approvalRequestGrantsDAL = approvalRequestGrantsDALFactory(db); + // DAILY const dailyResourceCleanUp = dailyResourceCleanUpQueueServiceFactory({ scimService, @@ -1942,7 +1945,9 @@ export const registerRoutes = async ( serviceTokenService, orgService, userNotificationDAL, - keyValueStoreDAL + keyValueStoreDAL, + approvalRequestDAL, + approvalRequestGrantsDAL }); const healthAlert = healthAlertServiceFactory({ @@ -2423,7 +2428,6 @@ export const registerRoutes = async ( gatewayV2Service }); - const approvalRequestGrantsDAL = approvalRequestGrantsDALFactory(db); const approvalPolicyDAL = approvalPolicyDALFactory(db); const pamAccountService = pamAccountServiceFactory({ @@ -2469,7 +2473,6 @@ export const registerRoutes = async ( const approvalPolicyStepsDAL = approvalPolicyStepsDALFactory(db); const approvalPolicyStepApproversDAL = approvalPolicyStepApproversDALFactory(db); - const approvalRequestDAL = approvalRequestDALFactory(db); const approvalRequestStepsDAL = approvalRequestStepsDALFactory(db); const approvalRequestStepEligibleApproversDAL = approvalRequestStepEligibleApproversDALFactory(db); const approvalRequestApprovalsDAL = approvalRequestApprovalsDALFactory(db); diff --git a/backend/src/services/approval-policy/approval-policy-dal.ts b/backend/src/services/approval-policy/approval-policy-dal.ts index bf4a12791..3d7bffebd 100644 --- a/backend/src/services/approval-policy/approval-policy-dal.ts +++ b/backend/src/services/approval-policy/approval-policy-dal.ts @@ -3,7 +3,12 @@ import { TableName, TApprovalRequestApprovals } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; import { ormify } from "@app/lib/knex"; -import { ApprovalPolicyType, ApproverType } from "./approval-policy-enums"; +import { + ApprovalPolicyType, + ApprovalRequestGrantStatus, + ApprovalRequestStatus, + ApproverType +} from "./approval-policy-enums"; import { ApprovalPolicyStep } from "./approval-policy-types"; // Approval Policy @@ -274,7 +279,21 @@ export const approvalRequestDALFactory = (db: TDbClient) => { } }; - return { ...orm, findStepsByRequestId, findByProjectId }; + const markExpiredRequests = async () => { + try { + const result = await db(TableName.ApprovalRequests) + .where("status", ApprovalRequestStatus.Pending) + .whereNotNull("expiresAt") + .where("expiresAt", "<", new Date()) + .update({ status: ApprovalRequestStatus.Expired }); + + return result; + } catch (error) { + throw new DatabaseError({ error, name: "Mark expired approval requests" }); + } + }; + + return { ...orm, findStepsByRequestId, findByProjectId, markExpiredRequests }; }; // Approval Request Steps @@ -297,7 +316,22 @@ export const approvalRequestStepEligibleApproversDALFactory = (db: TDbClient) => export type TApprovalRequestGrantsDALFactory = ReturnType; export const approvalRequestGrantsDALFactory = (db: TDbClient) => { const orm = ormify(db, TableName.ApprovalRequestGrants); - return orm; + + const markExpiredGrants = async () => { + try { + const result = await db(TableName.ApprovalRequestGrants) + .where("status", ApprovalRequestGrantStatus.Active) + .whereNotNull("expiresAt") + .where("expiresAt", "<", new Date()) + .update({ status: ApprovalRequestGrantStatus.Expired }); + + return result; + } catch (error) { + throw new DatabaseError({ error, name: "Mark expired approval grants" }); + } + }; + + return { ...orm, markExpiredGrants }; }; // Approval Request Approvals diff --git a/backend/src/services/resource-cleanup/resource-cleanup-queue.ts b/backend/src/services/resource-cleanup/resource-cleanup-queue.ts index 60310765b..f0b9e5e20 100644 --- a/backend/src/services/resource-cleanup/resource-cleanup-queue.ts +++ b/backend/src/services/resource-cleanup/resource-cleanup-queue.ts @@ -7,6 +7,7 @@ import { logger } from "@app/lib/logger"; import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue"; import { TUserNotificationDALFactory } from "@app/services/notification/user-notification-dal"; +import { TApprovalRequestDALFactory, TApprovalRequestGrantsDALFactory } from "../approval-policy/approval-policy-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityUaClientSecretDALFactory } from "../identity-ua/identity-ua-client-secret-dal"; import { TOrgServiceFactory } from "../org/org-service"; @@ -31,6 +32,8 @@ type TDailyResourceCleanUpQueueServiceFactoryDep = { userNotificationDAL: Pick; keyValueStoreDAL: Pick; scimService: Pick; + approvalRequestDAL: Pick; + approvalRequestGrantsDAL: Pick; }; export type TDailyResourceCleanUpQueueServiceFactory = ReturnType; @@ -49,7 +52,9 @@ export const dailyResourceCleanUpQueueServiceFactory = ({ scimService, orgService, userNotificationDAL, - keyValueStoreDAL + keyValueStoreDAL, + approvalRequestDAL, + approvalRequestGrantsDAL }: TDailyResourceCleanUpQueueServiceFactoryDep) => { const appCfg = getConfig(); @@ -94,6 +99,8 @@ export const dailyResourceCleanUpQueueServiceFactory = ({ await auditLogDAL.pruneAuditLog(); await userNotificationDAL.pruneNotifications(); await keyValueStoreDAL.pruneExpiredKeys(); + await approvalRequestDAL.markExpiredRequests(); + await approvalRequestGrantsDAL.markExpiredGrants(); logger.info(`${QueueName.DailyResourceCleanUp}: queue task completed`); } catch (error) { logger.error(error, `${QueueName.DailyResourceCleanUp}: resource cleanup failed`);