notification system implemented
need refinements
This commit is contained in:
1 parent
612259f020
commit
1143f8ca02
33 files changed
+2221
-222
No files matched your search
@@ -1,49 +1,87 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { getDatabase } from "@/lib/database";
|
||||
import log from "@/lib/logger";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
const { recommendationId, status, approvedBy } = await req.json();
|
||||
try {
|
||||
const body = await req.json();
|
||||
log.debug("Approve recommendation request body", { body });
|
||||
|
||||
if (!recommendationId || !status) {
|
||||
return NextResponse.json(
|
||||
{ error: "Recommendation ID and status are required" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
const { recommendationId, status, approvedBy } = body;
|
||||
|
||||
const db = await getDatabase();
|
||||
|
||||
// Update recommendation status
|
||||
const updates: any = {
|
||||
status,
|
||||
approvedAt: status === "approved" ? new Date() : undefined,
|
||||
approvedBy: status === "approved" ? approvedBy : undefined,
|
||||
};
|
||||
|
||||
// Remove undefined keys
|
||||
Object.keys(updates).forEach(key => updates[key] === undefined && delete updates[key]);
|
||||
|
||||
const updatedRecommendation = await db.updateRecommendation(recommendationId, updates);
|
||||
|
||||
if (!updatedRecommendation) {
|
||||
return NextResponse.json(
|
||||
{ error: "Recommendation not found" },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
// If approved, create a notification for the user
|
||||
// Note: IDatabase doesn't have createNotification yet, so we'll skip it for now
|
||||
// or we need to add it to IDatabase/SQLiteDatabase
|
||||
// For now, let's assume the notification is handled elsewhere or add it later
|
||||
|
||||
return NextResponse.json(updatedRecommendation);
|
||||
} catch (error) {
|
||||
console.error("Error approving recommendation:", error);
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
if (!recommendationId || !status) {
|
||||
log.error("Missing required fields", {
|
||||
recommendationId,
|
||||
status,
|
||||
receivedBody: body,
|
||||
});
|
||||
return NextResponse.json(
|
||||
{ error: "Recommendation ID and status are required" },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const db = await getDatabase();
|
||||
|
||||
// Update recommendation status
|
||||
const updates: any = {
|
||||
status,
|
||||
approvedAt: status === "approved" ? new Date() : undefined,
|
||||
approvedBy: status === "approved" ? approvedBy : undefined,
|
||||
};
|
||||
|
||||
// Remove undefined keys
|
||||
Object.keys(updates).forEach(
|
||||
(key) => updates[key] === undefined && delete updates[key],
|
||||
);
|
||||
|
||||
const updatedRecommendation = await db.updateRecommendation(
|
||||
recommendationId,
|
||||
updates,
|
||||
);
|
||||
|
||||
if (!updatedRecommendation) {
|
||||
return NextResponse.json(
|
||||
{ error: "Recommendation not found" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
// If approved, create a notification for the user
|
||||
if (status === "approved") {
|
||||
try {
|
||||
await db.createNotification({
|
||||
id: crypto.randomUUID(),
|
||||
userId: updatedRecommendation.userId,
|
||||
title: "Recommendation Approved! 🎉",
|
||||
message:
|
||||
"Your AI-powered fitness recommendation has been approved by your trainer. Check it out now!",
|
||||
type: "system",
|
||||
read: false,
|
||||
});
|
||||
|
||||
log.info("Notification created for approved recommendation", {
|
||||
recommendationId,
|
||||
userId: updatedRecommendation.userId,
|
||||
});
|
||||
} catch (notificationError) {
|
||||
// Log error but don't fail the approval
|
||||
log.error("Failed to create notification", notificationError);
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
data: updatedRecommendation,
|
||||
meta: {
|
||||
timestamp: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
log.error("Error approving recommendation", error);
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -15,18 +15,27 @@ export async function POST(req: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
log.debug("Generating recommendation for user", {
|
||||
userId,
|
||||
modelProvider,
|
||||
useExternalModel,
|
||||
});
|
||||
|
||||
const db = await getDatabase();
|
||||
|
||||
// Fetch fitness profile
|
||||
const profile = await db.getFitnessProfileByUserId(userId);
|
||||
|
||||
if (!profile) {
|
||||
log.error("Fitness profile not found", undefined, { userId });
|
||||
return NextResponse.json(
|
||||
{ error: "Fitness profile not found for this user" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
log.debug("Fitness profile found", { profileId: profile.id });
|
||||
|
||||
// Build AI context with goals and recommendations
|
||||
let prompt: string;
|
||||
try {
|
||||
@@ -270,21 +279,45 @@ export async function POST(req: Request) {
|
||||
}
|
||||
|
||||
// Save to database
|
||||
log.debug("Saving recommendation to database", {
|
||||
userId,
|
||||
profileId: profile.id,
|
||||
hasRecommendationText: !!parsedResponse.recommendationText,
|
||||
hasActivityPlan: !!parsedResponse.activityPlan,
|
||||
hasDietPlan: !!parsedResponse.dietPlan,
|
||||
});
|
||||
|
||||
const recommendation = await db.createRecommendation({
|
||||
id: crypto.randomUUID(),
|
||||
userId,
|
||||
fitnessProfileId: profile.id,
|
||||
recommendationText: parsedResponse.recommendationText,
|
||||
activityPlan: parsedResponse.activityPlan,
|
||||
dietPlan: parsedResponse.dietPlan,
|
||||
recommendationText: parsedResponse.recommendationText || "",
|
||||
activityPlan: parsedResponse.activityPlan || "",
|
||||
dietPlan: parsedResponse.dietPlan || "",
|
||||
status: "pending",
|
||||
generatedAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
});
|
||||
|
||||
return NextResponse.json(recommendation);
|
||||
log.info("Recommendation generated successfully", {
|
||||
recommendationId: recommendation.id,
|
||||
userId,
|
||||
});
|
||||
|
||||
// Return in standardized format
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
data: recommendation,
|
||||
meta: {
|
||||
timestamp: new Date().toISOString(),
|
||||
requestId: `req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
log.error("Failed to generate recommendation", error);
|
||||
log.error("Failed to generate recommendation", error, {
|
||||
errorMessage: error instanceof Error ? error.message : String(error),
|
||||
errorStack: error instanceof Error ? error.stack : undefined,
|
||||
});
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 },
|
||||
|
||||
Reference in new issue
Block a user