import { HttpError } from "@batch-cooking/error-tools"; import { ErrorCode, type SafeUserProfile } from "@batch-cooking/shared"; import { prisma } from "../../db/prisma.js"; import { toSafeProfile } from "../../lib/safe-profile.js"; /** * Sets (or clears, if `dietId` is `null`) a profile's dietary regime — the * regime step of the profile journey is skippable, so `null` is a normal, * valid value, not an omission to reject. * * @throws {HttpError} `404 DIET_NOT_FOUND` if `dietId` doesn't match a reference `Diet` row. */ export async function updateDiet( userProfileId: number, dietId: number | null, ): Promise { if (dietId !== null) { const diet = await prisma.diet.findUnique({ where: { id: dietId } }); if (!diet) { throw new HttpError(404, ErrorCode.DIET_NOT_FOUND, `No diet with id ${dietId}`); } } const profile = await prisma.userProfile.update({ where: { id: userProfileId }, data: { dietId }, }); return toSafeProfile(profile); } /** Current allergen ids for a profile — an empty array is normal (no allergies declared, or the step was skipped). */ export async function getAllergyIds(userProfileId: number): Promise { const rows = await prisma.userProfileAllergy.findMany({ where: { userProfileId }, select: { allergyId: true }, }); return rows.map((row) => row.allergyId); } /** * Replaces a profile's full allergen set (not a merge — the caller sends * the complete list every time, same shape the multi-select UI already * holds). Validates every id up front so a partially-invalid request never * leaves the set half-updated. * * @throws {HttpError} `404 ALLERGY_NOT_FOUND` if any `allergyId` doesn't match a reference `Allergy` row. */ export async function updateAllergies( userProfileId: number, allergyIds: number[], ): Promise { if (allergyIds.length > 0) { const found = await prisma.allergy.findMany({ where: { id: { in: allergyIds } }, select: { id: true }, }); const foundIds = new Set(found.map((allergy) => allergy.id)); const missing = allergyIds.filter((id) => !foundIds.has(id)); if (missing.length > 0) { throw new HttpError( 404, ErrorCode.ALLERGY_NOT_FOUND, `Unknown allergy id(s): ${missing.join(", ")}`, ); } } await prisma.$transaction([ prisma.userProfileAllergy.deleteMany({ where: { userProfileId } }), prisma.userProfileAllergy.createMany({ data: allergyIds.map((allergyId) => ({ userProfileId, allergyId })), }), ]); return allergyIds; }