import { cookies } from "next/headers" import { z } from "zod" import * as api from "@/lib/api" import { getVerifiedUser } from "@/server/routers/user/query" import { protectedProcedure } from "@/server/trpc" import { timeout } from "@/utils/timeout" const matchedSchema = z.object({ tierMatchState: z.enum(["matched"]), toLevel: z.enum(["L1", "L2", "L3", "L4", "L5", "L6", "L7"]), }) const notMatchedSchema = z.object({ tierMatchState: z.enum(["alreadyMatched", "notLinked", "error", "cached"]), }) const outputSchema = z.union([matchedSchema, notMatchedSchema]) export const performLevelUpgrade = protectedProcedure .output(outputSchema) .mutation(async function ({ ctx }) { console.log("[SAS] tier match") const cookieStore = cookies() const sasTierMatch = cookieStore.get("sasTierMatch") if (sasTierMatch) { return { tierMatchState: "cached" } } const userBeforeTierMatch = await getVerifiedUser({ session: ctx.session, }) if (!userBeforeTierMatch || userBeforeTierMatch?.error) { return { tierMatchState: "error" } } const apiResponse = await api.post(api.endpoints.v1.Profile.matchTier, { headers: { Authorization: `Bearer ${ctx.session.token.access_token}`, }, body: { partner: "sas_eb", partnerSpecific: {}, }, }) cookieStore.set("sasTierMatch", "true", { maxAge: 60 * 60 * 24, httpOnly: true, }) if (apiResponse.status === 202) { console.log("[SAS] tier match started") // Since the tier match is async we need to wait for it to complete before checking the result await timeout(1000) const userAfterTierMatch = await getVerifiedUser({ session: ctx.session, }) if (!userAfterTierMatch || userAfterTierMatch?.error) { return { tierMatchState: "error" } } const beforeLevel = userBeforeTierMatch.data.membership?.membershipLevel const afterLevel = userAfterTierMatch.data.membership?.membershipLevel if (!beforeLevel || !afterLevel) { console.log("[SAS] tier match error, user tier not found") return { tierMatchState: "error" } } if (beforeLevel !== afterLevel) { console.log( `[SAS] tier match success, user tier changed from ${beforeLevel} to ${afterLevel}` ) return { tierMatchState: "matched", toLevel: afterLevel } } return { tierMatchState: "alreadyMatched" } } if (apiResponse.status === 204) { console.log("[SAS] tier already matched") return { tierMatchState: "alreadyMatched" } } if (apiResponse.status === 404) { return { tierMatchState: "notLinked" } } console.log( `[SAS] tier match error with status code ${apiResponse.status} and response ${await apiResponse.text()}` ) return { tierMatchState: "error" } })