Production assessment detail
Scope: This document covers the production (
prod) version on themainbranch. It does not cover the study version.
This document describes the six assessments implemented by the C2Fit mobile app. It is based on the current frontend code, BFF journey rules, Assessment/Result Service scoring code, and tracked seed data. Timing and question-pool values below describe the checked-in configuration. A deployed database can differ if its seed data was changed after deployment.
Open business logic and dataflow → for the surrounding journey, submission, and service flow.
How to read the flows
An assessment contains an ordered list of tasks. A task can contain one or more phases. The BFF owns the current assessment, task, and phase indexes. The frontend renders the corresponding screen and submits the user's actions. The Result Service scores the submitted phase, and the next-state rules either advance normally or apply an assessment-specific branch.
INTROandRESULTare tasks without phases.TRAININGis practice. Training behavior differs by assessment, but training results never contribute to the final displayed score.TESTING_*phases are scored attempts.- A variant identifies the question/configuration assigned to one phase.
- Unless a section says otherwise, phase actions are submitted to
POST /result-service/api/v1/journey/submit. - A result becomes
SCOREDonly after every required scored task is complete. Tasks without phases andRESTART_MODALtasks are initialized as already scored.
The requirement tables describe behavior that a user, PM, or UX designer can observe. Engineering details that support those requirements are kept in separate technical notes.
Attention Hold/Release
What it is
The user presses and holds the green hold button until a configured light turns on, then taps the target light within its response window. The single task shows one light. The complex task shows three lights and requires the user to select the correct one.
Ordered flow
| Step | Task | Phase | What happens |
|---|---|---|---|
| 1 | INTRO | None | Shows the assessment introduction and starts the journey when the user continues. |
| 2 | AHR_SINGLE | TRAINING | Runs three local practice trials with hold durations of 500, 750, and 1,000 ms. The practice light is shown for 900 ms. The practice response window is 150 to 1,150 ms after light activation. |
| 3 | AHR_SINGLE | TESTING_1 to TESTING_27 | Runs 27 scored one-light trials. Before TESTING_1 starts, a brief transition overlay displays ชุดที่ 1/2 and ไฟ 1 ดวง. |
| 4 | AHR_COMPLEX | TESTING_1 to TESTING_27 | Runs 27 scored three-light trials. Before TESTING_1 starts, a brief transition overlay displays ชุดที่ 2/2 and ไฟ 3 ดวง. |
| 5 | RESULT | None | Polls for the assessment result, then shows the combined score and separate one-light and three-light statistics. |
Detailed requirements
Trial content and interaction
| ID | Requirement |
|---|---|
| AHR-01 | The assessment must contain 27 one-light trials followed by 27 three-light trials. Trial order must vary while keeping questions appropriate for the user's age group. |
| AHR-02 | Each trial must use its assigned hold duration, light duration, target light, and valid response window. Current questions use two age bands, younger than 50 and 50 or older, and a minimum response time of 150 ms. |
| AHR-03 | The user must press and hold the green button for the required duration. Releasing too early returns the screen to waiting for a new hold. |
| AHR-04 | Completing the hold turns on the target light. In the one-light task, one light is available. In the three-light task, the user must choose the light that turned on. |
| AHR-05 | The trial ends after the user taps a light, taps the background after a light has appeared, misses the response window, or starts another hold after the light has appeared. The next trial must not wait for a visible result screen. |
| AHR-06 | Training must demonstrate the interaction through three practice trials. It must give practice feedback and allow the user to repeat training or continue. Training does not affect the assessment score. |
Warnings and task skipping
The idle warning has a 10-second recovery timer and a cumulative warning count. The release warning has its own 30-second timer and does not affect that count.
| ID | Requirement |
|---|---|
| AHR-07 | At the start of a normal testing trial, the user has 10 seconds to complete the required hold. Starting a hold without completing it does not avoid the warning. |
| AHR-08 | If the hold is not completed within 10 seconds, the app must display กดปุ่มสีเขียวค้างไว้ เพื่อรอให้ดวงไฟติด and start a 10-second recovery window. |
| AHR-09 | During the first and second idle warnings, the user may recover by completing the hold before the recovery window ends. Releasing before the hold completes leaves the warning active. |
| AHR-10 | If the user does not complete the hold during the recovery window, the app must skip the current task. This can happen on the first or second idle warning. |
| AHR-11 | The third idle warning must skip the current task immediately, without another recovery window. The warning count carries across testing phases. |
| AHR-12 | If the hold button is already pressed when a trial starts, the app must display ปล่อยมือจากปุ่ม และกดค้างใหม่อีกครั้ง. Releasing starts the normal 10-second trial window. |
| AHR-13 | If the user does not release the button within 30 seconds of the release warning, the app must skip the current task. This warning does not increase the idle-warning count. |
| AHR-14 | Skipping must move the user to the next task. Unanswered trials in the skipped task remain part of the total and receive no points. |
| AHR-15 | A permanent timeout during training ends the practice interaction and moves to the training result step. It does not skip a scored task. |
| AHR-16 | If result loading takes longer than five seconds, the app must replace the loading indicator with the request-timeout warning. |
Technical notes
- Journey generation selects three age-matching members from each single-task group
1through9, and one from each complex-task group1through27, then shuffles the selected variants. - Trial events are stored as
START_PHASE,HOLD,RELEASE,LIGHT_ON,CLICK_LIGHT_BTN,CLICK_BACKGROUND, andTIMEOUTactions. - Normal trials use the generic phase-submission endpoint. The frontend submits in the background and prevents duplicate submission.
- A permanent testing failure clears the unsubmitted actions and calls
POST /api/v1/journey/skip-task. Skip scoring marks the current task as scored and treats unsubmitted phases as incorrect.
Scoring
A testing phase is correct only when all of these conditions are true:
- The configured target light turns on.
- The user taps that target light, not another light.
- The tap happens after the light turns on.
- The response time is between the trial's minimum and maximum limits, inclusive.
Each correct testing phase is worth 1 point. AHR_SINGLE and AHR_COMPLEX are scored independently as correct trials over total testing trials. The assessment screen displays:
score = single_score + complex_score
maximum = single_total_score + complex_total_scoreWith the full seeded path, the maximum is 54. Training is not included.
Digit Span Speak
What it is
The app plays a sequence of spoken digits. The user repeats the digits in the same order for the forward task and in reverse order for the backward task. Sequence length increases from 2 to 12 digits.
Ordered flow
| Step | Task | Phase | What happens |
|---|---|---|---|
| 1 | INTRO | None | Shows the assessment introduction. |
| 2 | DSS_FORWARD | TRAINING | Plays a two-digit forward practice sequence, records the spoken answer, submits it for feedback, and lets the user repeat or continue. |
| 3 | DSS_FORWARD | TESTING_1_1 to TESTING_11_2 | Runs up to 11 levels. Levels 1 to 11 contain sequences of 2 to 12 digits, with two possible trials per level. |
| 4 | DSS_BACKWARD | TRAINING | Plays a two-digit practice sequence and asks for the digits in reverse order. |
| 5 | DSS_BACKWARD | TESTING_1_1 to TESTING_11_2 | Runs the same 2-to-12-digit level structure, but the expected answer is reversed. |
| 6 | RESULT | None | Shows the forward score, backward score, and their combined total. |
Detailed requirements
| ID | Requirement |
|---|---|
| DSS-01 | The assessment must test forward recall first and backward recall second. Each task has 11 levels, with sequence length increasing from 2 digits at level 1 to 12 digits at level 11. |
| DSS-02 | The app must play the digits one at a time before recording begins. The current question configuration uses a 10 ms gap between digit audio files. |
| DSS-03 | For forward recall, the user must repeat the digits in the order played. For backward recall, the user must repeat them in reverse order. The answer is correct only when the number of digits and every digit position match. |
| DSS-04 | The user has 10 seconds to record an answer. Manual submission must remain unavailable during the first second, after which the user may submit early. The app submits automatically when time expires. |
| DSS-05 | If the app moves to the background while the user is answering, recording and the countdown must pause. Both must continue when the app returns to the foreground. |
| DSS-06 | A correct first attempt at a level must skip the second attempt and advance to the next level. An incorrect first attempt must open the second attempt at the same level. |
| DSS-07 | Any correct answer must clear the consecutive-error count. Two consecutive incorrect answers must end the current forward or backward task. |
| DSS-08 | Before the first scored trial of each task, the app must briefly introduce the new round. During testing, it must show the user's progress through the task. |
| DSS-09 | Forward and backward training must use a two-digit example, record the user's answer, and show feedback. The user may repeat training or continue. Training does not affect the score. |
| DSS-10 | After testing, the result screen must show the forward score, backward score, and combined score. Half points must remain visible in the separate task statistics. |
Technical notes
- Digit audio comes from the bundled
digit-span-speak-{digit}.wavfiles. - Audio submissions use multipart
POST /result-service/api/v1/journey/submit/digit-span-speak. - The Result Service sends the recording to
global-asr-servicewith localeth-THand the Google default speech-to-text model. Scoring keeps only transcribed characters that parse as digits. - The BFF waits for the current phase score before it chooses the next or second attempt.
Scoring
For each of the 11 levels in a task:
- Correct on
TESTING_n_1: 1 point; the second trial is skipped. - Incorrect on
TESTING_n_1, then correct onTESTING_n_2: 0.5 points. - Both trials incorrect: 0 points, and the two-error rule ends the task.
The backend stores a maximum of 11 points for forward and 11 for backward. It returns the two scores separately. The result statistics preserve half points, but the large combined score in the current frontend converts forward_score + backward_score to an integer with toInt(), which truncates a remaining fractional part.
Modified Visuospatial
What it is
The assessment uses 12 cards arranged around the edge of a 5-by-3 layout. Baseline asks the user to select a card that was shown. Forward and backward show a sequence of card positions followed by a symbol, then ask the user to reproduce the position order and choose the symbol.
Ordered flow
| Step | Task | Phase | What happens |
|---|---|---|---|
| 1 | INTRO | None | Shows the assessment introduction. |
| 2 | MV_BASELINE | TRAINING | Demonstrates selecting one opened card from the four active corner cards. |
| 3 | MV_BASELINE | TESTING_1_1 to TESTING_4_1 | Runs four one-card baseline trials. Each active corner position is used once in randomized order. |
| 4 | RESTART_MODAL | RESTART_MODAL | Appears only when all four baseline trials are incorrect. It offers restart or leave/continue-to-next options according to the journey start source. |
| 5 | MV_FORWARD | TRAINING | Demonstrates position-order recall followed by symbol selection. |
| 6 | MV_FORWARD | TESTING_1_1 to TESTING_8_2 | Runs up to eight levels with 2 to 9 positions. Each level has two possible trials. The user reproduces the shown order. |
| 7 | MV_BACKWARD | TRAINING | Demonstrates the same interaction, but positions must be selected in reverse order. |
| 8 | MV_BACKWARD | TESTING_1_1 to TESTING_8_2 | Runs up to eight 2-to-9-position levels with the reverse-order rule. |
| 9 | RESULT | None | Shows forward and backward results. Baseline controls eligibility to continue but is not shown in the final score. |
Detailed requirements
Layout and baseline
| ID | Requirement |
|---|---|
| MV-01 | The assessment must display 12 cards around the edge of a 5-by-3 layout. Baseline uses four designated corner cards. Forward and backward use all 12 cards. |
| MV-02 | Baseline training must identify the four selectable corner cards, show one example card opening and closing, then let the user select the card that opened. It must show correctness feedback and allow the user to repeat training or continue. |
| MV-03 | Before the first scored baseline trial, a brief transition overlay must display ชุดที่ 1/3 and เลือกไพ่ที่เปิด. |
| MV-04 | Each scored baseline trial must open exactly one of the four selectable corner cards. The card remains open for 1 second, then closes. The user cannot answer until the close animation finishes. |
| MV-05 | Each baseline trial accepts one answer. After the shown card closes, the user selects one of the four corner cards and that selection submits the current trial. The other eight cards remain disabled, and the user cannot change the answer after selecting it. |
| MV-06 | Baseline testing has no answer countdown or automatic timeout. It waits until the user selects a card. |
| MV-07 | The user must answer all four baseline trials before the assessment can continue. Trials 1 through 3 advance to the next baseline trial without showing correctness feedback. After trial 4, the app evaluates the four baseline answers. Each selectable corner must be the target once, in randomized order, and the first target must differ from the training example. |
| MV-08 | A baseline answer is correct only when the selected card is the card that opened. Baseline does not include position sequences or symbol selection. |
| MV-09 | After all four baseline trials, at least one correct answer must continue the assessment to forward training. If all four answers are incorrect, the app must show the restart decision. |
Forward and backward
| ID | Requirement |
|---|---|
| MV-10 | Forward and backward must contain eight levels. The sequence grows from 2 card positions at level 1 to 9 positions at level 8, and generated positions must not be adjacent. |
| MV-11 | The app must reveal the card positions one at a time. Each card remains open for 1 second, followed by its flip animation. After the position sequence, forward and backward testing must show the target symbol for 3 seconds. |
| MV-12 | The user has 10 seconds to reproduce the card sequence and 5 seconds to select the symbol. Position entry ends when the required number of cards has been selected or time expires. Symbol selection submits immediately; a symbol timeout submits the incomplete attempt. |
| MV-13 | During position entry, the user may select only active cards that are currently closed. After position entry, the app must display four symbol choices in the center of the layout. |
| MV-14 | Forward requires the user to select positions in the order shown. Backward requires the reverse order. Both tasks also require the correct symbol. |
| MV-15 | Each trial must use a different active symbol set within one assessment attempt so the same symbol set is not repeated. |
| MV-16 | For each level, a correct first attempt must skip the second attempt. An incorrect first attempt must open the second attempt. Two consecutive incorrect answers must end the current task. |
| MV-17 | Training must demonstrate position recall followed by symbol selection. Backward training must explain and demonstrate reverse-order selection. Training does not affect the final score. |
Restart and result
| ID | Requirement |
|---|---|
| MV-18 | Restart must create a new set of questions and return to the baseline tests without replaying the assessment introduction or baseline training. The alternative action depends on where the assessment was started and may continue to the next assessment or leave it for later. |
| MV-19 | The result screen must show forward and backward results. Baseline performance controls whether the user may continue, but it must not appear in the final assessment score. |
Technical notes
- Baseline uses indexes
0,2,6, and8; training uses index0. The scored order prevents index0from appearing first. - Baseline testing records one
CLICK_CARDaction and submits as soon as the first selection is accepted. It does not create aTIMEOUTaction. - Generated forward and backward questions use the phase variant as a deterministic seed. The same task, phase, and variant reproduce the same position order.
- Training uses positions
3and9with four symbol choices. Testing records selections asCLICK_CARDandCLICK_SYMBOL. - The backend reverses submitted card selections before comparing backward answers. It stores order correctness and symbol correctness separately.
- The BFF waits for a scored phase result before applying baseline and retry branches.
Scoring
Baseline receives 1 point for each correct baseline phase, but that value is used for the continuation rule and is omitted from the returned assessment score.
For each forward and backward task, the backend initializes the task score at 1 and the total at 9. Each level passed on either its first or second trial adds 1 point. Unlike Digit Span Speak, success on a second trial is not reduced to half a point. The final screen displays:
score = forward_score + backward_score
maximum = forward_total_score + backward_total_scoreThe full maximum is 18. This reflects the current scoring code, including its initial 1 point per forward/backward task.
Drawing Memory
What it is
The user reproduces line patterns on a 5-by-5 point grid. Matching keeps the reference visible while the user draws. Mirror requires the reflected pattern. Delayed tasks briefly show a pattern, hide it for a configured delay, and then ask the user to draw it from memory.
Ordered flow
| Step | Task | Phase | What happens |
|---|---|---|---|
| 1 | INTRO | None | Shows the assessment introduction. |
| 2 | DM_MATCHING_SIMPLE | TRAINING, TESTING_1 | Teaches direct pattern copying, then runs one simple scored copy. |
| 3 | DM_MATCHING_COMPLEX | TESTING_1 | Runs one more complex direct copy without another training phase. |
| 4 | DM_MIRROR_SIMPLE | TRAINING, TESTING_1 | Teaches reflected drawing, then runs one simple scored reflected drawing. |
| 5 | DM_MIRROR_COMPLEX | TESTING_1 | Runs one more complex reflected drawing. |
| 6 | RESTART_MODAL | RESTART_MODAL | Appears only when all four matching/mirror testing phases are incorrect. |
| 7 | DM_DELAY_1_SIMPLE | TRAINING, TESTING_1, TESTING_2 | Teaches delayed recall, then runs two simple patterns with a 6-second scored delay. The training delay is 4 seconds. |
| 8 | DM_DELAY_1_COMPLEX | TESTING_1, TESTING_2 | Runs two complex patterns with a 6-second delay. |
| 9 | DM_DELAY_2_SIMPLE | TESTING_1, TESTING_2 | Runs two simple patterns with a 12-second delay. |
| 10 | DM_DELAY_2_COMPLEX | TESTING_1, TESTING_2 | Runs two complex patterns with a 12-second delay. |
| 11 | DM_DELAY_3_COMPLEX | TESTING_1 | Runs one complex pattern with a 300-second delay and displays the waiting countdown. |
| 12 | RESULT | None | Shows total correctness and average response time across correct testing phases. |
Detailed requirements
| ID | Requirement |
|---|---|
| DM-01 | The assessment must select patterns for the user's age group, younger than 50 or 50 and older. Pattern choice must vary between assessment attempts. |
| DM-02 | Every drawing task must use a 5-by-5 point grid and allow 30 seconds for the user to complete the answer. |
| DM-03 | A drawn line must connect two neighboring points horizontally, vertically, or diagonally. The line must snap to a point only when the drag is close enough to that point. |
| DM-04 | Tapping ลบเส้น must remove only the most recently drawn line. The user cannot choose an older line to remove. Drawing may continue after removal. |
| DM-05 | Matching tasks must keep the reference pattern visible while the user copies it. The simple task includes training; the complex task begins directly with testing. |
| DM-06 | Mirror tasks must keep the reference visible while the user draws its reflection. The simple task includes training; the complex task begins directly with testing. |
| DM-07 | Delayed tasks must show the reference pattern, hide it, wait for the configured delay, then show an empty grid and start the 30-second answer timer. |
| DM-08 | For scored delayed trials, TESTING_1 shows the reference for 2.25 seconds to users younger than 50 and 3 seconds to users 50 or older. TESTING_2 uses 1.5 seconds and 2.25 seconds respectively. The five-minute delayed task uses the TESTING_1 display duration. |
| DM-09 | Delay 1 must wait 6 seconds, Delay 2 must wait 12 seconds, and Delay 3 must wait 300 seconds. Delayed training uses a 4-second wait. |
| DM-10 | The five-minute Delay 3 wait must display a countdown. Shorter delayed trials show a waiting screen without the numeric countdown. If more than 60 seconds remain, the app must schedule a reminder for the final minute and cancel it when the wait ends or the user leaves the screen. |
| DM-11 | The user may finish manually before the answer timer ends. If the timer expires first, the app must submit the drawing as it currently appears. |
| DM-12 | A drawing is correct only when it contains every required line and no extra line. Line direction does not matter. Mirror scoring must compare against the reflected form of the reference pattern. |
| DM-13 | After the four matching and mirror tests, at least one correct answer must continue to delayed training. If all four are incorrect, the app must show the restart decision. |
| DM-14 | Restart must create a new set of questions and return to the matching tests without replaying the assessment introduction, matching training, or mirror training. |
| DM-15 | The result screen must show the number of correct testing phases and the average drawing time for correct phases. Training does not affect either value. |
Technical notes
- Added and removed lines are stored as
SHOW_LINEandHIDE_LINEactions. Manual completion usesCLICK_NEXT; timer completion usesTIMEOUT. - Scoring converts the final line actions into an undirected adjacency matrix. Long straight lines are divided at each integer grid point, and out-of-bounds coordinates are rejected.
- Mirror scoring reverses grid rows while keeping columns fixed.
- Drawing duration is measured from
SHOW_GRIDuntilCLICK_NEXTorTIMEOUT.
Scoring
Each testing phase is worth 1 point for an exact path match. A task score is the number of correct testing phases over the number of testing phases in that task. The task also stores the average duration of its correct phases, or -1 when none are correct.
The assessment score sums all task scores and totals. It calculates a score-weighted average duration across correct phases. With the full seeded path, there are 13 scored phases. The frontend displays the average duration in seconds by dividing the backend nanosecond value by 1e9.
Verbal Memory
What it is
The user learns 15 spoken words, recalls the list immediately, recalls it again after five minutes, then chooses the previously learned word from 15 two-word recognition pairs.
Ordered flow
| Step | Task | Phase | What happens |
|---|---|---|---|
| 1 | INTRO | None | Shows the assessment introduction. |
| 2 | VM_ENCODE | TRAINING | Combines a word-repeat tutorial with recall practice. |
| 3 | VM_ENCODE | TESTING_1 to TESTING_15 | Plays one target word per phase and asks the user to repeat it. |
| 4 | VM_IMMEDIATE_RECALL | TESTING_1 | Gives 60 seconds to say any of the 15 learned words, in any order. |
| 5 | VM_DELAYED_RECALL | TESTING_1 | Waits 300 seconds, then gives 60 seconds to recall the same 15 words. |
| 6 | VM_DELAYED_RECOGNITION | TRAINING | Teaches choosing the previously presented word. |
| 7 | VM_DELAYED_RECOGNITION | TESTING_1 to TESTING_15 | Shows one learned word and one distractor per phase. The user selects one within 10 seconds. |
| 8 | VM_DELAYED_RECOGNITION | RESULT_TASK | Shows the recognition task score and per-phase choices. Continuing opens the assessment result. |
| 9 | RESULT | None | Shows immediate recall, delayed recall, recognition, and their combined score. |
Detailed requirements
| ID | Requirement |
|---|---|
| VM-01 | The assessment must use 15 target words. The same word list must be used for learning, immediate recall, delayed recall, and recognition. Each recognition question must pair one target word with one distractor. |
| VM-02 | During learning, the app must play one target word and ask the user to repeat it. The user has 10 seconds. A correctly recognized repetition ends the trial early; otherwise the trial ends when time expires. |
| VM-03 | Immediate recall must begin without a waiting period and give the user 60 seconds to say as many of the 15 learned words as possible, in any order. |
| VM-04 | Delayed recall must show a five-minute waiting screen before recording starts. The app must schedule a reminder when 60 seconds remain, then give the user 60 seconds to recall the words. |
| VM-05 | Recall must count each recognized target word once. Repeating the same target word must not increase the result. The recall task ends early if all 15 words are recognized. |
| VM-06 | After a recall task ends, the app must show the recognized-word result for up to 10 seconds. The user may continue immediately, or the app continues automatically when the result timer ends. |
| VM-07 | Recognition training must teach the user to select the word heard earlier. Each scored recognition trial must show two choices, keep their order stable during the assessment attempt, and allow 10 seconds for one selection. |
| VM-08 | Selecting a recognition word must submit the answer immediately. If time expires, the app must submit the unanswered trial and continue. |
| VM-09 | After the 15 recognition trials, the app must show the recognition task result and the choice made for each trial before opening the full assessment result. |
| VM-10 | The final result screen must show immediate recall, delayed recall, recognition, and their combined score. The learned-word repetition task must not be included in the displayed total. |
| VM-11 | Training must not contribute to the assessment score. |
Technical notes
- Learning and recall stream microphone audio through the speech WebSocket for live transcription. The app validates transcripts once per second and when it receives a final ASR result.
- Transcript and recognition values are stored as
TRANSCRIBE_WORDandCLICK_WORD. Completion is stored asALLOW_CORRECT_SKIPorTIMEOUT. - The app submits transcript actions for scoring and uploads recorded audio separately to
POST /result-service/api/v1/journey/result/phase-file. - Failure to upload the separate audio file is logged but does not block the user from continuing.
- Recognition option order is selected deterministically from the journey ID and word pair, so rebuilding the same trial does not swap the choices.
RESULT_TASKis a presentation phase. It is initialized as scored and does not create another test submission.
Scoring
Each task score is the sum of its testing-phase matched-word counts and totals. The backend assessment result includes encode, immediate recall, delayed recall, and delayed recognition as separate values.
The current frontend's displayed total omits encode and calculates:
score = immediate_recall_score + delayed_recall_score + delayed_recognition_score
maximum = immediate_recall_total + delayed_recall_total + delayed_recognition_totalWith the tracked 15-word configuration, the displayed maximum is 45. Encode can contribute up to 15 additional backend-stored points, but those points are not included in the large result score or its three statistic cards.
Trail Making Test
What it is
The user draws a continuous ordered trail through numbered and symbolic nodes. C2Fit exposes character and dice assessment variants. They share the same journey and scoring logic; only the symbolic node presentation differs.
Ordered flow
| Step | Task | Phase | What happens |
|---|---|---|---|
| 1 | INTRO | None | Shows the character or dice introduction. |
| 2 | TMT_NUMBER | TRAINING | Runs a frontend-only four-part tutorial covering number order, symbol order, number order with distractors, and alternating number/symbol order. |
| 3 | TMT_NUMBER | TESTING_1 | Connects 1-2-3...8. Current seeded questions allow 60 seconds and contain 8 scorable nodes. |
| 4 | TMT_SYMBOL | TESTING_1 | Connects Thai characters or dice quantities in order. Current seeded questions allow 90 seconds and contain 8 scorable nodes. |
| 5 | TMT_NUMBER_WITH_DISTRACTION | TESTING_1 | Connects numbers in order without entering distractor nodes. Current seeded questions allow 90 seconds and contain 8 scorable plus 2 distractor nodes. |
| 6 | TMT_NUMBER_AND_SYMBOL | TESTING_1 | Alternates number and character/dice nodes. Current seeded questions allow 180 seconds and contain 10 scorable nodes. |
| 7 | RESULT | None | Shows all four task scores and their combined total. |
Detailed requirements
| ID | Requirement |
|---|---|
| TMT-01 | The assessment must support character and dice versions. Both versions use the same tasks and rules. Symbol nodes must appear as Thai characters in the character version and dice quantities in the dice version. |
| TMT-02 | The node layout must scale to the available screen while preserving the configured positions and relative node sizes. |
| TMT-03 | Training must cover number order, symbol order, number order with distractors, and alternating number and symbol order. The four sections allow 10, 15, 15, and 30 seconds and finish after 3, 3, 3, and 4 required nodes respectively. |
| TMT-04 | Number testing must ask the user to connect 1-2-3...8 within 60 seconds. Symbol testing must ask the user to connect eight characters or dice quantities in order within 90 seconds. |
| TMT-05 | Number-with-distraction testing must include eight required number nodes and two distractors, with a 90-second limit. Number-and-symbol testing must include ten required alternating nodes, with a 180-second limit. |
| TMT-06 | A trail must begin inside the first required node and continue through the required nodes in their displayed order. Distractor nodes must never be part of the required order. |
| TMT-07 | Entering the next required node must mark it correct and advance the trail. Starting on or entering the wrong node must mark it incorrect and prevent further drawing until the user selects undo. |
| TMT-08 | The outer hint ring must preview whether the node under the trail is the next correct node. Moving away without entering the node must restore its previous state. |
| TMT-09 | Undo must remove only the latest stroke. If that stroke caused an error, undo must unlock drawing. If it reached a correct node, undo must also move progress back by one required node. |
| TMT-10 | Reaching every required node must submit the task automatically. If time expires first, drawing must stop and the app must submit the partial trail as it appears at timeout. |
| TMT-11 | Each required node must earn one point only when the user reaches it correctly and does not undo it. Distractors must not affect the score. A task is fully correct only when every required node is correct at submission. |
| TMT-12 | The result screen must show the four task scores and their combined total. Training must not contribute to the result. |
Technical notes
- Both versions start from the shared
TRAIL_MAKING_TESTpath. Journey generation selects an active question variant for each testing task and maps genericSYMBOLnodes toCHARorDICE. - Testing questions use a logical canvas of 340 by 645 before the frontend scales it to the viewport.
- Submission uses multipart
POST /result-service/api/v1/journey/submit/trail-making-testwith the normal action list and a JSON detail file containing node changes, sampled points, strokes, and undo events. - The scorer uses only each known node's final status. Only
GREEN_SOLIDearns a point. Point samples, stroke history, and undo history are retained for detail but do not change the score.
Scoring
Each task has one testing phase. Its score is the number of scorable nodes whose final status is GREEN_SOLID; its total is the number of configured number and character/dice nodes. The assessment total is the sum of all four task scores and totals.
With the tracked pool, the maximum is 8 + 8 + 8 + 10 = 34. Character and dice results are stored in separate MongoDB collections: result_trail_making_test_char and result_trail_making_test_dice.
Implementation source map
The main evidence used for this reference is listed below. Paths are relative to the three C2Fit source repositories named in the project documentation.
| Area | Primary source files |
|---|---|
| Shared task/phase contract | c2fit-app-frontend/lib/feature/journey/domain/enum/task.dart, c2fit-app-frontend/lib/feature/journey/domain/enum/phase.dart, c2fit-assessment-result/pkg/model/enum/assessment.go |
| Shared frontend submission | c2fit-app-frontend/lib/feature/journey/util/submit_phase.dart, c2fit-app-frontend/lib/feature/journey/data/network/journey_result_service.dart |
| BFF branching and restart/skip | c2fit-bff/internal/pkg/engine/journey_eng.go |
| Attention Hold/Release | c2fit-app-frontend/lib/feature/attention_hold_release/, c2fit-assessment-result/internal/pkg/engine/journey_path_attention_hold_release_eng.go, c2fit-assessment-result/internal/pkg/engine/score_attention_hold_release_eng.go, c2fit-assessment-result/seed/question_attention_hold_release.csv |
| Digit Span Speak | c2fit-app-frontend/lib/feature/digit_span_speak/, c2fit-assessment-result/seed/assessment_path_digit_span_speak.js, c2fit-assessment-result/seed/question_digit_span_speak.csv, c2fit-assessment-result/internal/pkg/engine/score_digit_span_speak_eng.go |
| Modified Visuospatial | c2fit-app-frontend/lib/feature/modified_visuospatial/, c2fit-assessment-result/seed/assessment_path_modified_visuospatial.js, c2fit-assessment-result/internal/pkg/engine/journey_path_modified_visuospatial_eng.go, c2fit-assessment-result/internal/pkg/repository/question_modified_visuospatial_repo.go, c2fit-assessment-result/internal/pkg/engine/score_modified_visuospatial_eng.go |
| Drawing Memory | c2fit-app-frontend/lib/feature/drawing_memory/, c2fit-assessment-result/seed/assessment_path_drawing_memory.js, c2fit-assessment-result/seed/drawing_memory/, c2fit-assessment-result/internal/pkg/engine/journey_path_drawing_memory_eng.go, c2fit-assessment-result/internal/pkg/engine/score_drawing_memory_eng.go |
| Verbal Memory | c2fit-app-frontend/lib/feature/verbal_memory/, c2fit-assessment-result/seed/assessment_path_verbal_memory.js, c2fit-assessment-result/seed/question_verbal_memory.csv, c2fit-assessment-result/internal/pkg/engine/score_verbal_memory_eng.go |
| Trail Making Test | c2fit-app-frontend/lib/feature/trail_making_test/, c2fit-app-frontend/lib/asset/trail_making_test_{char,dice}_training_question.json, c2fit-assessment-result/seed/assessment_path_trail_making_test.js, c2fit-assessment-result/seed/trail_making_test/, c2fit-assessment-result/internal/pkg/engine/journey_path_trail_making_test_eng.go, c2fit-assessment-result/internal/pkg/engine/score_trail_making_test_eng.go |