enhancment complete with phase 10

This commit is contained in:
dimitar committed 2026-03-10 05:37:22 +01:00
1 parent 2c4927478a
commit 6adb541967
44 files changed
+7820 -845

No files matched your search

+42 -45
View File
@@ -3,15 +3,23 @@ import { auth } from "@clerk/nextjs/server";
import { getDatabase } from "@/lib/database";
import { randomBytes } from "crypto";
import log from "@/lib/logger";
// Helper to add CORS headers
function corsHeaders() {
return {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
};
}
import {
fitnessGoalSchema,
paginationSchema,
statusFilterSchema,
} from "@/lib/validation/schemas";
import {
validateRequestBody,
validateQueryParams,
validationErrorResponse,
} from "@/lib/validation/helpers";
import {
successResponse,
createdResponse,
unauthorizedResponse,
internalErrorResponse,
addCorsHeaders,
} from "@/lib/api/responses";
// Helper to get user ID from auth (works with both web sessions and mobile tokens)
async function getAuthenticatedUserId(
@@ -25,7 +33,7 @@ async function getAuthenticatedUserId(
// OPTIONS - Handle preflight requests
export async function OPTIONS() {
return NextResponse.json({}, { headers: corsHeaders() });
return NextResponse.json({}, { headers: addCorsHeaders() });
}
// GET - List user's fitness goals
@@ -37,10 +45,7 @@ export async function GET(req: NextRequest) {
log.error("Fitness goals GET - authentication failed", undefined, {
headers: Object.fromEntries(req.headers.entries()),
});
return NextResponse.json(
{ error: "Unauthorized" },
{ status: 401, headers: corsHeaders() },
);
return unauthorizedResponse(undefined, addCorsHeaders());
}
log.debug("Fitness goals GET - authenticated user", { userId });
@@ -61,13 +66,10 @@ export async function GET(req: NextRequest) {
count: goals.length,
userId: targetUserId,
});
return NextResponse.json(goals, { headers: corsHeaders() });
return successResponse(goals, { headers: addCorsHeaders() });
} catch (error) {
log.error("Failed to get fitness goals", error);
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500, headers: corsHeaders() },
);
return internalErrorResponse(undefined, addCorsHeaders());
}
}
@@ -78,13 +80,19 @@ export async function POST(req: NextRequest) {
if (!userId) {
log.error("Fitness goals POST - authentication failed");
return NextResponse.json(
{ error: "Unauthorized" },
{ status: 401, headers: corsHeaders() },
);
return unauthorizedResponse(undefined, addCorsHeaders());
}
// Validate request body
const validation = await validateRequestBody(req, fitnessGoalSchema);
if (!validation.success) {
log.warn("Fitness goal creation validation failed", {
errors: validation.errors,
});
return validationErrorResponse(validation.errors);
}
const body = await req.json();
const {
goalType,
title,
@@ -94,17 +102,9 @@ export async function POST(req: NextRequest) {
unit,
targetDate,
priority,
status,
notes,
fitnessProfileId,
} = body;
// Validation
if (!goalType || !title) {
return NextResponse.json(
{ error: "goalType and title are required" },
{ status: 400, headers: corsHeaders() },
);
}
} = validation.data;
const db = await getDatabase();
@@ -112,28 +112,25 @@ export async function POST(req: NextRequest) {
const goal = await db.createFitnessGoal({
id: randomBytes(16).toString("hex"),
userId,
fitnessProfileId: fitnessProfileId || undefined,
fitnessProfileId: undefined,
goalType,
title,
description: description || undefined,
targetValue: targetValue || undefined,
description,
targetValue,
currentValue: currentValue || 0,
unit: unit || undefined,
unit,
startDate: new Date(),
targetDate: targetDate ? new Date(targetDate) : undefined,
status: "active",
status: status || "active",
progress: 0,
priority: priority || "medium",
notes: notes || undefined,
notes,
});
log.info("Fitness goal created", { goalId: goal.id, userId });
return NextResponse.json(goal, { status: 201, headers: corsHeaders() });
return createdResponse(goal, { headers: addCorsHeaders() });
} catch (error) {
log.error("Failed to create fitness goal", error);
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500, headers: corsHeaders() },
);
return internalErrorResponse(undefined, addCorsHeaders());
}
}