Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
110 changes: 110 additions & 0 deletions src/controllers/organization.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.`,
Expand Down Expand Up @@ -192,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',
Expand Down Expand Up @@ -250,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: new Date(),
},
});

return res
.status(200)
.json({ message: 'Organization verified successfully' });
Expand Down Expand Up @@ -677,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',
Expand Down Expand Up @@ -764,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',
Expand Down Expand Up @@ -906,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`,
Expand Down Expand Up @@ -978,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,
Expand Down Expand Up @@ -1021,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,
Expand Down