MSDTmt - Trail Making Test Application
What is the Trail Making Test (TMT)?
The Trail Making Test (TMT) is a standardized cognitive assessment used to evaluate visual attention, task-switching ability, and executive function. The test consists of two parts:
- TMT-A: Connecting numbers in sequence (1-2-3...)
- TMT-B: Alternating between numbers and letters (1-A-2-B...)
The test measures the completion time, errors, and other metrics that help assess cognitive function.
This project is a digital implementation of the Trail Making Test (TMT), providing randomly generated cognitive assessments for clinical evaluation. The application dynamically generates test circles, records user performance, and provides comprehensive performance metrics analysis, transforming the traditional paper-and-pencil TMT into a reliable and consistent digital experience.
Project Structure
This project follows Clean Architecture with a Feature-First structure. Code is organized by feature, each as a self-contained module.
It uses GetX for state management, dependency injection, routing, and utilities.
Project Directory Structure
The project follows a typical Feature-First directory organization with Clean Architecture layers:
lib/
+---app/
| +---config/ # Application-wide configuration
| | +---routes/ # Route definitions
| | +---themes/ # Theme configurations
| | +---translation/ # Internationalization
| +---constans/ # Constants used across the app
| +---features/ # Feature modules (Feature-First)
| | +---home/ # Home feature
| | | +---data/ # Data layer
| | | | +---datasources/ # Data sources (local/remote)
| | | | +---repositories/ # Repository implementations
| | | +---domain/ # Domain layer
| | | | +---entities/ # Business models
| | | | +---repository/ # Repository interfaces
| | | | +---usecases/ # Use cases (business logic)
| | | +---presentation/ # Presentation layer
| | | +---binding/ # Dependency injection
| | | +---components/ # UI components
| | | +---controllers/ # GetX controllers
| | | +---screens/ # Screen widgets
| | +---splash/ # Splash screen feature
| | +---tm_tst/ # Trail Making Test feature
| | | +---data/
| | | | +---datasources/
| | | | +---repositories/
| | | +---domain/
| | | | +---entities/
| | | | | +---metric/ # Test metrics entities
| | | | | +---result/ # Test result entities
| | | | | +---tmt_game/ # Game-specific entities
| | | | +---repository/
| | | | +---usecases/
| | | | +---tmt_result/# Result-related use cases
| | | +---presentation/
| | | +---bindings/
| | | +---components/
| | | +---controllers/
| | | +---screens/
| | +---user/ # User management feature
| | +---data/
| | | +---datasources/
| | +---domain/
| | | +---entities/
| | | +---repository/
| | | +---usecase/
| | +---presentation/
| | +---binding/
| | +---components/
| | +---contoller/
| | +---screen/
| +---shared_components/ # Shared UI components
| +---utils/ # Utilities
| +---helpers/ # Helper functions
| +---mixins/ # Shared behavior
| +---services/ # Services
| | +---net/ # Network services
| +---ui/ # UI utilities
This structure demonstrates how the application organizes code:
- Feature-First: Each feature (home, splash, tm_tst, user) has its own dedicated directory
- Clean Architecture: Each feature follows the clean architecture layers (data, domain, presentation)
- Shared Resources: Common components and utilities are separated from features
- Consistency: The same structure is repeated across all features for maintainability
Clean Architecture Overview

The implementation organizes the application into five main components:
1. Config
Contains configuration-related classes:
- Routing: Manages screen navigation and routes using GetX route management
- Themes: Defines light, dark, and custom themes
- Translation: Handles multilingual text resources with GetX internationalization
2. Constants
Maintains application-wide constants:
- API Path: Centralized API endpoint definitions
- Asset Path: Organized asset file references
3. Features
Core functionality organized by feature:
- Model: Data models representing screen information
- View: UI components and screen layouts
- Controller: State management using GetX controllers
4. Shared Components
Reusable elements across features:
- Widget: Custom UI elements (cards, buttons, etc.)
- Style: Common styling configurations
5. Utils
Helper utilities:
- Helper: Extension functions, type converters, etc.
- Mixin: Reusable behavior for navigation, validation, etc.
- Service: API clients, database connections, native functionality
- UI: Common dialog boxes, snackbars, etc.
Feature Architecture
Each feature follows a layered architecture that enforces separation of concerns:

Data Layer
- Remote Data Sources: Handles API interactions
- Local Data Sources: Manages database and device storage
- Models: Data transfer objects
- Repositories (Implementation): Implements the interfaces defined in the domain layer
Domain Layer
- Entities: Core business objects
- Repositories (Interface): Defines data access contracts
- Use Cases: Encapsulates business logic
Presentation Layer
- Presentation Logic Holders: State management using GetX controllers
- Widgets: UI components specific to the feature
Data Flow
- UI events trigger controller methods
- Controllers invoke use cases
- Use cases interact with repositories
- Repositories coordinate between data sources
- Results flow back up through the layers
- UI updates based on the new state and GetX reactive variables
This architecture ensures that:
- Business logic remains independent of UI and external frameworks
- Dependencies point inward (outer layers depend on inner layers)
- Components are highly testable through dependency injection
- The application is scalable and maintainable as features grow
References
- The Clean Architecture implementation is inspired by Flutter Template
- The feature architecture is inspired by Flutter GetX Clean Architecture
Documentation
Viewing Project Documentation
The project's detailed documentation is located in the doc/build/html/index.html file. This documentation provides comprehensive information about the project's architecture, features, and implementation details.
To access the documentation:
- Navigate to the
doc/build/htmldirectory - Open the
index.htmlfile in any web browser - Browse through the complete documentation to understand all aspects of the project
The documentation includes detailed descriptions of:
- Architecture and design patterns
- Feature implementations
- API interactions
- User interfaces
- Testing methodologies
For developers who want to understand or modify the documentation source, the RST files are available in the doc/source directory.
Running the Project
Prerequisites
Before running the project, users must create a .env file in the root directory with the following content:
API_BASE_URL=http://your_server_ip_address
Note: A backend server that supports the following API endpoints is required:
API Endpoints
-
/procesar- Validate reference codes- Method: POST
- Request Body:
{ "codeid": "reference_code_string" } - Response:
{ "exists": 2, "hands": [ "D", "I" ], "message": "OK", "status": "ok" } - Description: Validates if a reference code is valid and returns whether it exists and which hand(s) were used previously
-
/reportar- Submit TMT test results- Method: POST
- Request Body: Combined user profile and test metrics data with the following format:
codeid:123234-12 F_nacimiento:MM-DD-YYYY Sexo:M Nivel_Educ:D Mano:D NumCirc:26 Time_complete:156.6 Number_Errors:2 Average_Pause:2.5 Average_Lift:0.7 Average_Rate_Between_Circles:0.8 Average_Rate_Inside_Circles:0.24 Average_Time_Between_Circles:3.2 Average_Time_Inside_Circles:2.1 Average_Rate_Before_Letters:0.9 Average_Rate_Before_Numbers:0.75 Average_Time_Before_Letters:3.8 Average_Time_Before_Numbers:1.98 Number_Pauses:1 Number_Lifts:2 Average_Total_Pressure:12.5 Average_Total_Size:3.0 Date_Data:29-12-2025 Score:36 DiagInch:10.5 - Response:
{ "status": "OK", "message": "Result saved successfully" } - Description: Submits detailed test performance metrics and user information
-
/listar- Retrieve test results list- Method: POST
- Request Body:
{ "codeid": "reference_code_string", "date_data": "YYYY-MM-DD" } - Response:
{ "status": "OK", "data": [ { "date": "YYYY-MM-DD", "time_a": 45.3, "time_b": 75.2, "hand": "I/D", "": "// ...other result metrics" } ] } - Description: Returns a list of test results for a specific reference code and date
All responses include a status field that indicates success ("OK") or failure ("error"). In case of errors, a message field provides error details.
Running on Android
Debug Mode
flutter run --debug
Build for Release
flutter build apk --release
Running on iOS
Debug Mode
flutter run --debug
Build for Release
flutter build ipa
Build App Bundle for Play Store
Before building, add the following to android/local.properties:
storeFile=YOUR_PATH_TO_KEYSTORE
storePassword=YOUR_KEYSTORE_PASSWORD
keyAlias=YOUR_KEY_ALIAS
keyPassword=YOUR_KEY_PASSWORD
Then run:
flutter build appbundle --release
Output location:
- Windows:
.\build\app\outputs\bundle\release\ - macOS/Linux:
./build/app/outputs/bundle/release/
Generating Documentation with Sphinx
Prerequisites
Ensure that Python is installed on your computer. You can verify this by running:
python --version
Windows
- Install Sphinx dependencies:
pip install -r doc/requirements.txt
- Navigate to the doc directory:
cd doc
- Generate the documentation:
make.bat html
Linux/macOS
- Install Sphinx:
pip install sphinx sphinx_rtd_theme
- Navigate to the doc directory:
cd doc
- Generate the documentation:
make html
Other Development Commands
Create Splash Screen
dart run flutter_native_splash:create
Generate Launcher Icons
flutter pub run flutter_launcher_icons
Libraries
- app\config\routes\app_pages
- app\config\routes\app_route_observer
- app\config\themes\app_text_style_base
- app\config\themes\app_theme
- app\config\themes\AppColors
- app\config\themes\AppFontWeight
- app\config\themes\AppTextStyle
- app\config\themes\input_decoration
- app\config\themes\theme_controller
- app\config\translation\app_translations
- app\constans\app_constants
- app\constans\database_constants
- app\constans\send_tmt_result_date_formatter
- app\constans\tmt_result_model_constant
- app\features\home\data\repositories\reference_validation_repository_impl
- app\features\home\domain\entities\home_ui_constant_variable
- app\features\home\domain\entities\reference_validation_result_entity
- app\features\home\domain\repository\reference_validation_repository
- app\features\home\domain\usecases\validate_reference_code_use_case
- app\features\home\presentation\binding\home_screen_binding
- app\features\home\presentation\binding\reference_validation_biding
- app\features\home\presentation\binding\select_user_profile_binding
- app\features\home\presentation\components\home_page_header
- app\features\home\presentation\components\reference_code_input
- app\features\home\presentation\components\select_user_dropdown
- app\features\home\presentation\components\select_user_profile_dialog
- app\features\home\presentation\controllers\reference_code_controller
- app\features\home\presentation\controllers\select_user_profile_controller
- app\features\home\presentation\screens\home_page
- app\features\splash\splash_screen
- app\features\tm_tst\data\datasources\generate_circle_with_data
- app\features\tm_tst\data\datasources\random_grid_sampler
- app\features\tm_tst\data\datasources\reorder_circles
- app\features\tm_tst\data\datasources\simple_generate_random_circle
- app\features\tm_tst\data\model\pending_result_model
- app\features\tm_tst\data\model\tmt_result_metric_model
- app\features\tm_tst\data\model\tmt_reult_user_model
- app\features\tm_tst\data\repositories\pending_result_repository_impl
- app\features\tm_tst\data\repositories\tmt_game_config_repository_imp
- app\features\tm_tst\data\repositories\tmt_result_repository_impl
- app\features\tm_tst\domain\entities\metric\circles_metric
- app\features\tm_tst\domain\entities\metric\metric_static_values
- app\features\tm_tst\domain\entities\metric\tmt_b_metrics
- app\features\tm_tst\domain\entities\metric\tmt_circles_metrics
- app\features\tm_tst\domain\entities\metric\tmt_metrics_controller
- app\features\tm_tst\domain\entities\metric\tmt_pressure_size_metric
- app\features\tm_tst\domain\entities\metric\tmt_test_lift_metric
- app\features\tm_tst\domain\entities\metric\tmt_test_pause_metric
- app\features\tm_tst\domain\entities\metric\tmt_test_time_metric
- app\features\tm_tst\domain\entities\result\tmt_game_hand_used
- app\features\tm_tst\domain\entities\result\tmt_game_init_data
- app\features\tm_tst\domain\entities\result\tmt_game_result_data
- app\features\tm_tst\domain\entities\result\tmt_user_data
- app\features\tm_tst\domain\entities\tmt_game\tmt_game_circle
- app\features\tm_tst\domain\entities\tmt_game\tmt_game_variable
- app\features\tm_tst\domain\repository\pending_result_repository
- app\features\tm_tst\domain\repository\tmt_game_config_repository
- app\features\tm_tst\domain\repository\tmt_result_repository
- app\features\tm_tst\domain\usecases\select_mode_practice_or_test_responsive_calculate
- app\features\tm_tst\domain\usecases\tmt_game_calculate
- app\features\tm_tst\domain\usecases\tmt_game_config_use_case
- app\features\tm_tst\domain\usecases\tmt_result\pending_result_use_case
- app\features\tm_tst\domain\usecases\tmt_result\report_tmt_result_use_case
- app\features\tm_tst\domain\usecases\tmt_result\tmt_result_card_responsive_calculate
- app\features\tm_tst\domain\usecases\tmt_result\tmt_result_screen_responsive_calculator
- app\features\tm_tst\presentation\bindings\tmt_game_config_biding
- app\features\tm_tst\presentation\bindings\tmt_result_binding
- app\features\tm_tst\presentation\bindings\tmt_test_binding
- app\features\tm_tst\presentation\bindings\tmt_test_practice_binding
- app\features\tm_tst\presentation\components\tmt_count_down_component
- app\features\tm_tst\presentation\components\tmt_game_board_controller
- app\features\tm_tst\presentation\components\tmt_painter
- app\features\tm_tst\presentation\components\tmt_result_card
- app\features\tm_tst\presentation\components\tmt_select_hand_dialog
- app\features\tm_tst\presentation\components\tmt_test_app_bar
- app\features\tm_tst\presentation\controllers\base_tmt_test_flow_contoller
- app\features\tm_tst\presentation\controllers\tmt_practice_flow_state_contoller
- app\features\tm_tst\presentation\controllers\tmt_result_report_controller
- app\features\tm_tst\presentation\controllers\tmt_test_flow_state_controller
- app\features\tm_tst\presentation\screens\tmt_select_mode_practice_or_test
- app\features\tm_tst\presentation\screens\tmt_test_help
- app\features\tm_tst\presentation\screens\tmt_test_practice_screen
- app\features\tm_tst\presentation\screens\tmt_test_result_screen
- app\features\tm_tst\presentation\screens\tmt_test_screen
- app\features\user\data\datasources\test_result_data_soruce
- app\features\user\data\datasources\user_profle_data_soruce
- app\features\user\data\model\user_profile_model
- app\features\user\data\model\user_test_result_local_data_model
- app\features\user\domain\entities\user_profile
- app\features\user\domain\entities\user_test_local_data_result
- app\features\user\domain\repository\test_result_local_data_repository
- app\features\user\domain\repository\user_profile_repository
- app\features\user\domain\usecase\register_user_screen_responsive_calculator
- app\features\user\presentation\binding\test_result_local_data_binding
- app\features\user\presentation\binding\user_history_binding
- app\features\user\presentation\binding\user_profile_binding
- app\features\user\presentation\contoller\test_result_controller
- app\features\user\presentation\contoller\user_profile_controller
- app\features\user\presentation\screen\current_user_data_screen
- app\features\user\presentation\screen\register_user_screen
- app\features\user\presentation\screen\user_result_history_screen
- app\features\user\presentation\screen\user_screen_base
- app\shared_components\custom_app_bar
- app\shared_components\custom_dialog
- app\shared_components\header_text
- app\utils\helpers\app_helpers
- app\utils\helpers\widget_max_width_calculator
- app\utils\mixins\app_mixins
- app\utils\services\app_logger
- app\utils\services\local_storage_services
- app\utils\services\native_api_services
- app\utils\services\net\api_error
- app\utils\services\net\api_interceptor
- app\utils\services\net\rest_api_services
- app\utils\services\net\result_data
- app\utils\services\request_state
- app\utils\services\user_data_base_helper
- app\utils\services\user_data_base_migration
- app\utils\services\work_manager_handler
- app\utils\ui\ui_utils
- main