Merged in feat/LOY-232-DTMC-API-INTEGRATION (pull request #2454)

feat(LOY-232): DTMC API Integration

* feat(LOY-232): DTMC API Integration

* feat(LOY-232): use employment data in team member card

* refactor(LOY-232): remove static data, return employment details in parsed response & fix tests

* refactor(LOY-232): improve DTMC API Linking error control flow + make res type safe

* fix(LOY-232): remove unused utils

* fix(LOY-232): error vars


Approved-by: Christian Andolf
Approved-by: Erik Tiekstra
This commit is contained in:
Chuma Mcphoy (We Ahead)
2025-07-01 07:03:59 +00:00
parent d272cd03ce
commit 7eb8deb208
8 changed files with 155 additions and 26 deletions

View File

@@ -1,6 +1,7 @@
import { type NextRequest, NextResponse } from "next/server"
import { overview } from "@scandic-hotels/common/constants/routes/myPages"
import * as api from "@scandic-hotels/trpc/api"
import { isValidSession } from "@scandic-hotels/trpc/utils/session"
import { DTMC_SUCCESS_BANNER_KEY } from "@/constants/dtmc"
@@ -12,15 +13,94 @@ import { auth } from "@/auth"
import { auth as dtmcAuth } from "@/auth.dtmc"
import { getLang } from "@/i18n/serverContext"
async function linkEmployeeToUser(employeeId: string) {
interface LinkEmployeeSuccessResult {
success: true
}
interface LinkEmployeeErrorResult {
success: false
statusCode: number
queryParam?: string | null
}
type LinkEmployeeResult = LinkEmployeeSuccessResult | LinkEmployeeErrorResult
/**
* Links an employee to a user account via API call.
*/
async function linkEmployeeToUser(
employeeId: string,
accessToken: string
): Promise<LinkEmployeeResult> {
console.log(`[dtmc] Linking employee ID ${employeeId}`)
let response: Response
try {
console.log(`[dtmc] Linking employee ID ${employeeId}`)
// TODO: Use the actual API once available. For now, return a mock success response.
return { success: true }
} catch (error) {
console.error("[dtmc] Error linking employee to user:", error)
throw error
response = await api.post(
api.endpoints.v2.Profile.teamMemberCard(employeeId),
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
}
)
} catch (networkError) {
console.error("[dtmc] Network error during API request:", networkError)
return {
success: false,
statusCode: 0,
}
}
if (!response.ok) {
console.error(`[dtmc] API returned error status ${response.status}`)
try {
const errorResponse = await response.json()
console.error(`[dtmc] API error response:`, errorResponse)
} catch (parseError) {
console.warn(`[dtmc] Could not parse API error response:`, parseError)
try {
const errorText = await response.text()
console.error(`[dtmc] Raw error response:`, errorText)
} catch {
console.error(`[dtmc] Could not read error response body`)
}
}
let queryParam: string | null = null
switch (response.status) {
case 400:
case 404:
queryParam = "unable_to_verify_employee_id"
break
case 401:
queryParam = "unauthorized"
break
case 403:
queryParam = "forbidden"
break
}
return {
success: false,
statusCode: response.status,
queryParam,
}
}
console.log(`[dtmc] API call successful - Status: ${response.status}`)
console.log(
`[dtmc] Response headers:`,
Object.fromEntries(response.headers.entries())
)
try {
const responseBody = await response.json()
console.log(`[dtmc] Response body:`, responseBody)
} catch (parseError) {
console.warn(`[dtmc] Could not parse success response body:`, parseError)
}
console.log(`[dtmc] Successfully linked employee ID ${employeeId}`)
return { success: true }
}
/**
@@ -72,7 +152,16 @@ export async function GET(request: NextRequest) {
"[dtmc] DTMC Callback handler - Calling linkEmployeeToUser with ID:",
employeeId
)
const result = await linkEmployeeToUser(employeeId)
const accessToken = session.token.access_token
if (!accessToken) {
console.error("[dtmc] DTMC Callback handler - No access token in session")
const errorUrl = new URL(linkEmploymentError[lang], baseUrl)
errorUrl.searchParams.set("error", "missing_access_token")
return NextResponse.redirect(errorUrl)
}
const result = await linkEmployeeToUser(employeeId, accessToken)
console.log(
"[dtmc] DTMC Callback handler - linkEmployeeToUser result:",
result
@@ -80,10 +169,16 @@ export async function GET(request: NextRequest) {
if (!result.success) {
console.error(
"[dtmc] DTMC Callback handler - Failed to verify employment"
"[dtmc] DTMC Callback handler - Failed to verify employment:",
`Status: ${result.statusCode}, Error: ${result.queryParam}`
)
const errorUrl = new URL(linkEmploymentError[lang], baseUrl)
errorUrl.searchParams.set("error", "unable_to_verify_employee_id")
if (result.queryParam) {
errorUrl.searchParams.set("error", result.queryParam)
}
// For 500 errors and network errors, no query param = default error message.
return NextResponse.redirect(errorUrl)
}