Skip to main content

Cognitive Assessment

Overview

This page summarizes the Cognitive Assessment (HK-MoCA) APIs used in GOFA Next.js, including:

  • Creating an assessment record (start test)
  • Saving/updating results during the flow
  • Fetching a single result or a list
  • Fetching player history
  • Correctly returning to the intended home page (not BaseURL /)

API Summary

MethodEndpointDescription
POST/api/cognitive-assessmentCreate a cognitive assessment record and return step URLs
GET/api/cognitive-assessment-resultsList cognitive assessment results (optional filters)
GET/api/cognitive-assessment-results/[cognitiveAssessmentResultId]Get a single cognitive assessment result
PATCH/api/cognitive-assessment-results/[cognitiveAssessmentResultId]Update progress or complete the assessment
GET/api/client/[clientId]/analytics/player/[uid]/cognitive-assessment-historyGet a player’s assessment history (admin)

Authentication & Access

  • All endpoints use authenticateRequest() validation. Common options:
    • Authorization: Bearer <firebase_id_token>
    • Or existing Session Cookie (for example, after Kiosk login)
  • If userId is omitted, the server creates/reuses an anonymous user and returns firebaseCustomToken for the assessment flow.
tip

In Kiosk flows, you usually obtain a Session first, then call the create API. If firebaseCustomToken is returned, the client should sign in with it so that later PATCH requests can persist partial results.

1) Create an Assessment (POST)

Endpoint: POST /api/cognitive-assessment

Request Body

FieldTypeRequiredDescription
userIdstringNoAssigns the assessment to a user; if omitted, an anonymous user is created and firebaseCustomToken is returned
emailstringNoOptional email validation
photoURLstringNoOptional photo URL validation
userInfoobjectNoUser snapshot (name/age/gender/height/weight)
returnUrlstringNoReturn path after completion (must start with / and not //)
resultModestringNoResult display mode: qr (default) or direct

Query Parameters (Optional)

FieldTypeDescription
resultModestringResult display mode: qr (default) or direct

Response

200 OK
{
"cognitiveAssessmentResultId": "string",
"basicInfoUrl": "/cognitive-assessment/{id}/basic-info?returnUrl=...",
"memoryRecallUrl": "/cognitive-assessment/{id}/memory-recall?returnUrl=...",
"verbalFluencyUrl": "/cognitive-assessment/{id}/verbal-fluency?returnUrl=...",
"orientationUrl": "/cognitive-assessment/{id}/orientation?returnUrl=...",
"delayedRecallUrl": "/cognitive-assessment/{id}/delayed-recall?returnUrl=...",
"resultsUrl": "/cognitive-assessment/{id}/results?returnUrl=...",
"createdAt": "2026-02-04T08:30:00.000Z",
"returnUrl": "/kiosk/test-selection",
"resultMode": "direct",
"firebaseCustomToken": "<optional>"
}

Example

create-cognitive-assessment.ts
const response = await fetch('/api/cognitive-assessment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({
returnUrl: '/kiosk/test-selection?locale=zh-Hant',
resultMode: 'direct',
userInfo: {
name: 'Alex Chan',
age: 70,
gender: 'male',
heightInCm: 168,
weightInKg: 60,
},
}),
});

const data = await response.json();
// data.cognitiveAssessmentResultId
// data.resultsUrl, etc.
note

If resultMode is provided, the API appends it to the returned step URLs so clients can open any step and still respect the display mode.

note

resultMode=qr (default) will show the QR code screen after results are generated. The QR links to /cognitive-assessment/{id}/share, which is the shareable report UI. resultMode=direct skips the QR and opens that same share report UI directly.

tip

resultMode can be passed either in the request body or as a query parameter on POST /api/cognitive-assessment. If both are present, the request body value takes precedence.

danger

returnUrl must be a relative path that starts with / and does not start with //. Invalid values are ignored and the result screen will fall back to / (BaseURL home).

2) Launch the Assessment Page

You can use the returned basicInfoUrl / resultsUrl to jump to a specific step, or enter the main entry route directly:

/cognitive-assessment/{cognitiveAssessmentResultId}?returnUrl=...&resultMode=direct

Recommended Kiosk flow:

  1. Call POST /api/cognitive-assessment to get the id
  2. Navigate to /cognitive-assessment/{id}?returnUrl=...

This ensures every step and the result screen can return to Kiosk properly.

3) Update / Complete Results (PATCH)

Endpoint: PATCH /api/cognitive-assessment-results/[cognitiveAssessmentResultId]

  • Only schema-defined fields are allowed; unknown fields return 400.
  • id / clientId / createdAt cannot be changed.
  • When status is set to completed, completedAt is automatically added.
PATCH Example (Partial)
{
"status": "completed",
"testVersion": "HK-MoCA-5min",
"userAge": 70,
"educationYears": 9,
"scores": {
"memory": 5,
"fluency": 7,
"orientation": 6,
"delayedMemory": 8,
"rawTotal": 26,
"adjustedTotal": 27
},
"educationBonus": 1,
"rawScore": 26,
"totalScore": 27,
"interpretation": "Mild",
"riskLevel": "INTERMEDIATE",
"percentile": 35
}

4) Get a Single Result (GET)

Endpoint: GET /api/cognitive-assessment-results/[cognitiveAssessmentResultId]

200 OK
{
"data": {
"id": "string",
"clientId": "string",
"createdAt": "2026-02-04T08:30:00.000Z",
"assessmentType": "HK-MoCA",
"rawScore": 26,
"totalScore": 27,
"interpretation": "Mild",
"riskLevel": "INTERMEDIATE"
},
"resultsUrl": "/cognitive-assessment/{id}/results"
}

5) Get Result List (GET)

Endpoint: GET /api/cognitive-assessment-results

Query Parameters

ParameterTypeRequiredDescription
clientIdstringNoFilter by client ID
userIdstringNoFilter by user ID

6) Get Player History (GET)

Endpoint: GET /api/client/[clientId]/analytics/player/[uid]/cognitive-assessment-history

  • Admin access (accessRole: 'admin')
  • Used by B2B Player Report / admin dashboards

7) Correct Return Handling (Critical)

Why it Matters

If you omit returnUrl, the result page falls back to / (BaseURL home). In Kiosk scenarios, this breaks the kiosk flow.

  1. Pass returnUrl when creating the assessment (prefer returning to Kiosk home or test selection)
  2. Keep returnUrl in the assessment entry URL (or use the API-provided URLs)
  3. The “Finish Test” action uses returnUrl to navigate back
tip

When returning to Kiosk test selection, use /kiosk/test-selection?locale=... and ensure cognitiveResultId is included so the kiosk can mark the test as completed (this is auto-handled by the UI).

Kiosk Example

kiosk-cognitive-return.ts
const { cognitiveAssessmentResultId } = await createCognitiveAssessment({
returnUrl: '/kiosk/test-selection?locale=zh-Hant',
});

router.push(
`/cognitive-assessment/${cognitiveAssessmentResultId}?returnUrl=${encodeURIComponent('/kiosk/test-selection?locale=zh-Hant')}&resultMode=direct`
);

Exit to Cognitive Assessment Home (Non-Kiosk)

If the caller wants the Exit/Finish action to go back to the Cognitive Assessment home (instead of gofa.app), set returnUrl to the app’s cognitive assessment entry page. In GOFA Next.js, this is /cognitive-assessment/new.

Do not pass a full URL like https://gofa.app, because it will be rejected by the safety validator.

return-to-cognitive-home.ts
const returnUrl = '/cognitive-assessment/new';
const { cognitiveAssessmentResultId } = await createCognitiveAssessment({ returnUrl });

router.push(
`/cognitive-assessment/${cognitiveAssessmentResultId}?returnUrl=${encodeURIComponent(returnUrl)}`
);

Return URL Safety Rules

RuleDescription
Must start with /Prevents external redirects
Must not start with //Prevents protocol-relative redirects
Invalid values are clearedResult screen falls back to /

For extended fields or integration details, also see the existing Cognitive Assessment API.