import { ORPCError } from "@orpc/server"; import type { CoachRhythmDeps } from "@rakazo/adapters"; import { syncCoachTimeZone } from "@rakazo/adapters"; import type { Actor, ForgetUserFacts, UpdateUserProfile, UserProfileState, } from "@rakazo/contracts"; import type { PrismaClient } from "@rakazo/db"; import { forgetUserFacts, getUserProfileState, InvalidUserFactError, UserFactNotFoundError, updateUserProfile, } from "@rakazo/db"; function toRpcError(error: unknown): unknown { if (error instanceof UserFactNotFoundError) { return new ORPCError("NOT_FOUND", { message: error.message }); } if (error instanceof InvalidUserFactError) { return new ORPCError("BAD_REQUEST", { message: error.message }); } return error; } export function getProfile(prisma: PrismaClient, actor: Actor): Promise { return getUserProfileState(prisma, actor.userId); } export async function updateProfile( deps: CoachRhythmDeps, actor: Actor, input: UpdateUserProfile, ): Promise { try { await updateUserProfile(deps.prisma, actor.userId, input); } catch (error) { throw toRpcError(error); } if (input.timeZone !== undefined) await syncCoachTimeZone(deps, actor.userId); return getUserProfileState(deps.prisma, actor.userId); } /** Unknown ids are ignored, so a caller cannot probe another user's facts. */ export async function forgetProfile( deps: CoachRhythmDeps, actor: Actor, input: ForgetUserFacts, ): Promise { const target = input.factIds ? { factIds: input.factIds } : input.category ? { category: input.category } : { all: true as const }; await forgetUserFacts(deps.prisma, actor.userId, target); // Forgetting everything clears the time zone too. if ("all" in target) await syncCoachTimeZone(deps, actor.userId); return getUserProfileState(deps.prisma, actor.userId); }