csa-backend-test/app/controllers/activity.controller.js

213 lines
6.7 KiB
JavaScript

// ENVIRONMENT
require('dotenv').config();
// DATABASE
const { PrismaClient: CMSClient, ActivityType } = require("../../prisma/clients/cms");
const prisma = new CMSClient();
// RESPONSES
const { badRequestResponse } = require("../res/responses.js");
const { successResponse } = require("../res/responses.js");
// SERVICES
const { localTime } = require("../services/time.services.js");
const logger = require("../services/logger.services.js");
const {
manualTriggerNotification,
processActivitiesAndSendNotifications,
analyzeUserActivitiesForNotification,
updateDailyAnalytics,
getAINotificationAnalytics
} = require("../services/notification.services.js");
// CONTROLLER
exports.create = async (req, res) => {
try {
const { userID, activityType, params } = req.body;
if (!userID || !activityType || !params) {
throw new Error("Invalid user ID, activity type, or params!");
}
if (!Object.values(ActivityType).includes(activityType)) {
throw new Error(`Invalid activity type value, allowed values: ${Object.values(ActivityType).join(", ")}`);
}
const userToken = await prisma.usersToken.findUnique({
where: { UserID_UT: userID }
});
if (!userToken) {
throw new Error(`User token not found for userID: ${userID}. Please register user token first.`);
}
let parsedParams = params;
if (typeof params === 'string' && params.startsWith('{')) {
try {
parsedParams = params;
} catch (e) {
parsedParams = params;
}
}
const activity = await prisma.usersActivity.create({
data: {
UUID_UT: userToken.UUID_UT,
ActivityType_UA: activityType,
Params_UA: parsedParams,
NotifyAt_UA: localTime(new Date(Date.now() + 1000 * 60 * 5)),
CreatedAt_UA: localTime(new Date()),
UpdatedAt_UA: localTime(new Date())
}
});
return successResponse(res, "User activity created successfully!", {
activityID: activity.UUID_UA,
userID: userID,
activityType: activity.ActivityType_UA,
createdAt: activity.CreatedAt_UA,
willTriggerAIAnalysis: true
});
} catch (err) {
return badRequestResponse(res, "Error creating user activity", err);
}
}
exports.triggerNotificationForUser = async (req, res) => {
try {
const { userID, timeRangeMinutes = 60 } = req.body;
if (!userID) {
throw new Error("userID is required");
}
const result = await manualTriggerNotification(userID, timeRangeMinutes);
if (result.success) {
return successResponse(res, "Notification sent successfully!", result);
} else {
return badRequestResponse(res, `Failed to send notification: ${result.reason || result.error}`, result);
}
} catch (err) {
logger.error("Error triggering notification", { error: err.message, stack: err.stack });
return badRequestResponse(res, "Error triggering notification", err);
}
}
exports.analyzeUserActivities = async (req, res) => {
try {
const { userID, timeRangeMinutes = 60 } = req.body;
if (!userID) {
throw new Error("userID is required");
}
const analysis = await analyzeUserActivitiesForNotification(userID, timeRangeMinutes);
return successResponse(res, "Activity analysis completed", analysis);
} catch (err) {
return badRequestResponse(res, "Error analyzing activities", err);
}
}
exports.processAllActivitiesAndNotifications = async (req, res) => {
try {
const { timeRangeMinutes = 30, minActivityCount = 1 } = req.body;
const result = await processActivitiesAndSendNotifications({
timeRangeMinutes,
minActivityCount
});
if (result.notificationsSent > 0) {
try {
await updateDailyAnalytics();
result.analyticsUpdated = true;
} catch (analyticsErr) {
result.analyticsUpdated = false;
}
}
return successResponse(res, "Activity processing completed", {
...result,
message: `Processed ${result.totalUsersProcessed} users, sent ${result.notificationsSent} AI notifications`
});
} catch (err) {
return badRequestResponse(res, "Error processing activities", err);
}
}
exports.getAIInsights = async (req, res) => {
try {
const { userID, timeRange = 30 } = req.query;
// Get AI notification analytics
const analytics = await getAINotificationAnalytics({
startDate: new Date(Date.now() - timeRange * 24 * 60 * 60 * 1000),
endDate: new Date(),
limit: 50
});
let userSpecificData = null;
if (userID) {
// Get user-specific AI notifications
userSpecificData = await prisma.aINotification.findMany({
where: {
UserID_AIN: userID,
CreatedAt_AIN: {
gte: new Date(Date.now() - timeRange * 24 * 60 * 60 * 1000)
}
},
orderBy: {
CreatedAt_AIN: 'desc'
},
take: 10
});
// Get user's recent activities
const userToken = await prisma.usersToken.findFirst({
where: { UserID_UT: userID }
});
if (userToken) {
userSpecificData = {
notifications: userSpecificData,
recentActivities: await prisma.usersActivity.findMany({
where: {
UUID_UT: userToken.UUID_UT,
CreatedAt_UA: {
gte: new Date(Date.now() - 24 * 60 * 60 * 1000) // Last 24 hours
}
},
orderBy: {
CreatedAt_UA: 'desc'
},
take: 20
})
};
}
}
return successResponse(res, "AI insights retrieved successfully!", {
analytics: analytics.summary,
userSpecificData,
integrationStatus: {
aiNotificationsEnabled: true,
analyticsTracking: true,
activityMonitoring: true
}
});
} catch (err) {
return badRequestResponse(res, "Error retrieving AI insights", err);
}
}