From ca02162737735bb851f03b17a7e53d79e3d91a19 Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 18 Apr 2025 22:04:30 +0200 Subject: [PATCH 01/10] refactor: action type --- prisma/schema.prisma | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 0535f55..c28b5ea 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -575,6 +575,16 @@ enum ActionType { SPRINT_COMPLETED TASK_MOVED LOGGED_TIME + VERIFIED + LOGO_UPDATED + SETTINGS_CHANGED + SUBSCRIPTION_CHANGED + TEAM_CREATED + TEAM_DELETED + DEPARTMENT_CREATED + DEPARTMENT_DELETED + OWNER_ADDED + OWNER_REMOVED } enum TaskPriority { From 5ec52386bcfcf4994851ba8031bef84d535d0ae0 Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 18 Apr 2025 22:05:26 +0200 Subject: [PATCH 02/10] feat: add activity logs for `createOrganization` --- src/controllers/organization.controller.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index 4783ae5..3d66a11 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -11,6 +11,10 @@ import { updateOrganizationValidation, verifyOrganizationValidation, } from '../validations/organization.validation.js'; +import { + createActivityLog, + generateActivityDetails, +} from '../utils/activityLogs.utils.js'; /** * @desc Create a new organization with the current user as owner @@ -116,6 +120,19 @@ export const createOrganization = async (req, res, next) => { // } // } + // Log organization creation + await createActivityLog({ + entityType: 'ORGANIZATION', + action: 'CREATED', + userId: req.user.id, + organizationId: result.org.id, + details: generateActivityDetails('CREATED', null, { + organizationName: result.org.name, + organizationId: result.org.id, + createdAt: result.org.createdAt, + }), + }); + return res.status(201).json({ success: true, message: `Organization created successfully.`, From 5bb0a3c2553d022fed4cac844e4b5da76280e525 Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 18 Apr 2025 22:07:24 +0200 Subject: [PATCH 03/10] feat: add activity logs for `resendOTP` function --- src/controllers/organization.controller.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index 3d66a11..d15d464 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -209,6 +209,18 @@ export const resendOTP = async (req, res, next) => { }); } + // Log OTP resend + await createActivityLog({ + entityType: 'ORGANIZATION', + action: 'UPDATED', + userId: req.user.id, + organizationId: orgId, + details: { + action: 'OTP_RESENT', + timestamp: new Date(), + }, + }); + res.status(200).json({ success: true, message: 'Code send successfully. Please check your email', From e27b095aa2cf86db27cb4d042eaea88760f61205 Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 18 Apr 2025 22:09:18 +0200 Subject: [PATCH 04/10] feat: add activity logs for `verifyOrganization` function --- src/controllers/organization.controller.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index d15d464..11a9301 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -279,6 +279,18 @@ export const verifyOrganization = async (req, res, next) => { }, }); + // Log organization verification + await createActivityLog({ + entityType: 'ORGANIZATION', + action: 'UPDATED', + userId: req.user.id, + organizationId: org.id, + details: { + action: 'VERIFIED', + verifiedAt: org.isVerified, + }, + }); + return res .status(200) .json({ message: 'Organization verified successfully' }); From 70e3da57317c546f6f5ff4f53415a97b48e56a9a Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 18 Apr 2025 22:12:25 +0200 Subject: [PATCH 05/10] feat: add activity logs for `updateOrganization` function --- src/controllers/organization.controller.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index 11a9301..397f027 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -718,6 +718,23 @@ export const updateOrganization = async (req, res, next) => { } } + const updatedOrganization = await prisma.organization.update({ + where: { id: organizationId }, + }); + + // Log organization update + await createActivityLog({ + entityType: 'ORGANIZATION', + action: 'UPDATED', + userId: req.user.id, + organizationId: organizationId, + details: generateActivityDetails( + 'UPDATED', + existingOrg, + updatedOrganization, + ), + }); + return res.status(200).json({ success: true, message: 'Organization updated successfully', From 2dd7ba2d5435dca91687763f8d37cf6218f2ab86 Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 18 Apr 2025 22:13:58 +0200 Subject: [PATCH 06/10] feat: add activity logs for `deleteOrganization` function --- src/controllers/organization.controller.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index 397f027..931882f 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -822,6 +822,18 @@ export const deleteOrganization = async (req, res, next) => { data: { deletedAt: new Date(), status: 'DELETED' }, }); + // Log organization deletion + await createActivityLog({ + entityType: 'ORGANIZATION', + action: 'DELETED', + userId: req.user.id, + organizationId: organizationId, + details: generateActivityDetails('DELETED', existingOrg, { + deletedAt: new Date(), + organizationName: existingOrg.name, + }), + }); + return res.status(200).json({ success: true, message: 'Organization deleted successfully', From 821bc235eb3dafacf139974b04bbf1153dd6425d Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 18 Apr 2025 22:20:22 +0200 Subject: [PATCH 07/10] feat: add activity logs for `addOwners` function --- src/controllers/organization.controller.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index 931882f..d91b30d 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -976,6 +976,18 @@ export const addOwners = async (req, res, next) => { }); // Send email notifications to new owners + // Log addition of owners + await createActivityLog({ + entityType: 'ORGANIZATION', + action: 'MEMBER_ADDED', + userId: req.user.id, + organizationId: organizationId, + details: { + newOwnerRecords, + addedAt: new Date(), + }, + }); + return res.status(200).json({ success: true, message: `Successfully added ${newOwnerRecords.count} owner(s) to the organization`, From 503dff65672dcd2cbc4168dc742b85d0ef339aba Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 18 Apr 2025 22:21:44 +0200 Subject: [PATCH 08/10] feat: add activity logs for `uploadOrganizationLogo` function --- src/controllers/organization.controller.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index d91b30d..9b9f8af 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -1060,6 +1060,21 @@ export const uploadOrganizationLogo = async (req, res, next) => { data: { logoUrl }, }); + // Log logo upload + await createActivityLog({ + entityType: 'ORGANIZATION', + action: 'UPDATED', + userId: req.user.id, + organizationId: organizationId, + details: { + action: 'LOGO_UPLOADED', + logoUrl: updatedOrganization.logoUrl, + fileSize: req.file.size, + fileName: req.file.originalname, + uploadedAt: updatedOrganization.updatedAt, + }, + }); + res.status(200).json({ message: 'Organization logo uploaded successfully', logoUrl, From 1b5fbd1bcd86622d8772c4448c5f5c7131220959 Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 18 Apr 2025 22:22:50 +0200 Subject: [PATCH 09/10] feat: add activity logs for `deleteOrganizationLogo` function --- src/controllers/organization.controller.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index 9b9f8af..1855ca6 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -1118,6 +1118,19 @@ export const deleteOrganizationLogo = async (req, res, next) => { data: { logoUrl: null }, }); + // Log logo deletion + await createActivityLog({ + entityType: 'ORGANIZATION', + action: 'UPDATED', + userId: req.user.id, + organizationId: organizationId, + details: { + action: 'LOGO_DELETED', + previousLogoUrl: organization.logoUrl, + deletedAt: updatedOrganization.updatedAt, + }, + }); + res.status(200).json({ message: 'Organization logo deleted successfully', organization: updatedOrganization, From a6f8e408b4f9bf2c420c0db0ee7a8ba5973a8cbb Mon Sep 17 00:00:00 2001 From: Mohamed Dawoud Date: Fri, 18 Apr 2025 22:22:50 +0200 Subject: [PATCH 10/10] feat: add activity logs for `deleteOrganizationLogo` function --- src/controllers/organization.controller.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index 9b9f8af..33dfb52 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -287,7 +287,7 @@ export const verifyOrganization = async (req, res, next) => { organizationId: org.id, details: { action: 'VERIFIED', - verifiedAt: org.isVerified, + verifiedAt: new Date(), }, }); @@ -1118,6 +1118,19 @@ export const deleteOrganizationLogo = async (req, res, next) => { data: { logoUrl: null }, }); + // Log logo deletion + await createActivityLog({ + entityType: 'ORGANIZATION', + action: 'UPDATED', + userId: req.user.id, + organizationId: organizationId, + details: { + action: 'LOGO_DELETED', + previousLogoUrl: organization.logoUrl, + deletedAt: updatedOrganization.updatedAt, + }, + }); + res.status(200).json({ message: 'Organization logo deleted successfully', organization: updatedOrganization,