Overview
The Nudj platform provides a flexible question and variable system that enables dynamic data collection across your community. This dual-system architecture separates structured gamification questions (actions) from flexible form-based data collection (variables), providing maximum customization capabilities.
System Architecture Actions - Structured challenge questions with scoring and validationVariables - Flexible form fields for data collectionQuestion Bank - Reusable question templatesValidation Engine - Multi-layer validation with external API supportType Safety - TypeScript and Zod schema enforcement
Accessing Questions Configuration
Navigate to questions and variables settings:
Go to Admin → Settings → Organisation
Click the Questions tab
Configure variables and question templates
The Questions tab primarily manages Variables - flexible form fields used across the platform. Challenge-specific questions are configured within individual challenges as Actions.
Variables System
What Are Variables?
Variables are configurable form fields that collect user data across different contexts:
Profile Information : Custom profile fields beyond standard data
Onboarding Forms : Collect information during user registration
Challenge Submissions : Additional data for challenge completion
Survey Responses : Gather feedback and insights
Event Registration : Capture attendee information
Variable Types
Text Variables
Selection Variables
Numeric Variables
Date Variables
Boolean Variables
Single-line and Multi-line Text :{
type : "text" | "textarea" ,
name : "company_name" ,
label : "Company Name" ,
placeholder : "Enter your company name" ,
required : true ,
maxLength : 100 ,
validation : {
pattern : "^[A-Za-z0-9 \\ s]+$" ,
message : "Only letters, numbers, and spaces allowed"
}
}
Variable Configuration
Creating Variables
Define Variable
Set the variable type, name, and label
Configure Validation
Add validation rules and error messages
Set Display Options
Configure placeholder text, help text, and visibility
Enable in Question Bank
Make available for reuse across contexts
Test Variable
Preview in form context before publishing
Variable Properties
// Base properties shared by all variable types
interface BaseVariable {
id : string ;
name : string ; // Unique identifier
label : string ; // Display label
placeholder ?: string ; // Placeholder text
helpText ?: string ; // Helper description
icon ?: string ; // Icon identifier
order ?: number ; // Display order
required ?: boolean ; // Is field required
disabled ?: boolean ; // Read-only field
hidden ?: boolean ; // Hidden field
conditional ?: ConditionalRule ; // Show/hide logic
availableInQuestionBank ?: boolean ; // Reusable
category ?: string ; // Categorization
tags ?: string []; // Search tags
}
// Type-specific variable interfaces
interface TextVariable extends BaseVariable {
type : 'text' | 'textarea' | 'email' | 'url' ;
defaultValue ?: string ;
maxLength ?: number ;
minLength ?: number ;
pattern ?: string ; // Regex pattern
validation ?: TextValidationRule [];
}
interface NumberVariable extends BaseVariable {
type : 'number' | 'range' ;
defaultValue ?: number ;
min ?: number ;
max ?: number ;
step ?: number ;
unit ?: string ; // Display unit (e.g., "$", "%")
validation ?: NumberValidationRule [];
}
interface SelectVariable extends BaseVariable {
type : 'select' | 'radio' | 'checkbox' ;
defaultValue ?: string | string [];
options : Array <{
value : string ;
label : string ;
icon ?: string ;
}>;
multiple ?: boolean ; // For multi-select
maxSelections ?: number ; // Max number of selections
validation ?: SelectValidationRule [];
}
interface DateVariable extends BaseVariable {
type : 'date' | 'datetime' | 'time' ;
defaultValue ?: string ; // ISO 8601 format
minDate ?: string ;
maxDate ?: string ;
format ?: string ; // Display format
validation ?: DateValidationRule [];
}
interface BooleanVariable extends BaseVariable {
type : 'boolean' ;
defaultValue ?: boolean ;
trueLabel ?: string ;
falseLabel ?: string ;
}
// Discriminated union type
type Variable = TextVariable | NumberVariable | SelectVariable | DateVariable | BooleanVariable ;
Advanced Validation
Validation Rules
{
validation : {
type : "pattern" ,
pattern : "^[A-Z]{2}[0-9]{6}$" ,
message : "Format: 2 letters followed by 6 digits"
}
}
{
validation : {
type : "custom" ,
validate : ( value ) => {
// Custom validation logic
return value . length >= 10 ;
},
message : "Value must be at least 10 characters"
}
}
{
validation : {
type : "api" ,
endpoint : "/api/validate/email" ,
method : "POST" ,
debounce : 500 ,
message : "Email already exists"
}
}
Security Considerations for External API Validation:
Data Privacy : Avoid sending raw PII to external validators. Hash or tokenize sensitive data when possible.
Authentication : Require proper authentication and authorization on validation endpoints.
Input Sanitization : Validate and sanitize inputs before sending; minimize data in responses.
Performance : Implement caching, rate-limiting, and debouncing (min 300ms) to reduce server load.
Resilience : Set reasonable timeouts (3-5s max) and handle failures gracefully without blocking the UI.
{
validation : {
type : "dependent" ,
dependsOn : [ "start_date" ],
validate : ( value , formData ) => {
return new Date ( value ) > new Date ( formData . start_date );
},
message : "End date must be after start date"
}
}
Conditional Logic
Show/hide fields based on conditions:
{
conditional : {
show : {
when : "user_type" ,
equals : "business"
},
// OR more complex conditions
rules : [
{
field: "country" ,
operator: "in" ,
value: [ "US" , "CA" , "UK" ]
},
{
field: "age" ,
operator: ">=" ,
value: 18
}
],
logic : "AND" // AND/OR
}
}
Challenge Questions (Actions)
Action Types
Challenge questions are implemented as Actions within the gamification system:
Quiz Action Multiple choice questions with scoring
Prediction Action Forecast outcomes with accuracy scoring
Video Interaction Watch content with engagement tracking
Quick Time Action Time-based challenges with speed bonuses
Estimation Action Numeric guessing with proximity scoring
Drawing Action Creative submissions with peer voting
Action Configuration
interface ActionContent {
// Core Properties
type : ActionType ;
question : string ;
description ?: string ;
media ?: MediaContent ;
// Scoring
points : number ;
timeLimit ?: number ;
bonusPoints ?: BonusConfig ;
// Quiz-specific
options ?: QuizOption [];
correctAnswer ?: string | string [];
// Validation
validation ?: ValidationConfig ;
required ?: boolean ;
}
Question Bank
Reusable Templates
The Question Bank allows you to create templates for commonly used questions:
Profile Questions
Feedback Questions
Event Questions
{
category : "profile" ,
questions : [
{
name: "job_title" ,
label: "What is your job title?" ,
type: "text" ,
tags: [ "professional" , "onboarding" ]
},
{
name: "department" ,
label: "Which department do you work in?" ,
type: "select" ,
options: departmentList ,
tags: [ "organization" , "onboarding" ]
}
]
}
Template Management
Create Template
Build reusable question sets
Categorize
Organize by use case or department
Tag for Search
Add tags for easy discovery
Version Control
Track template changes over time
Share Across Teams
Make available organization-wide
Implementation Examples
// User onboarding with progressive disclosure
const onboardingFlow = {
steps: [
{
title: "Basic Information" ,
variables: [ "first_name" , "last_name" , "email" ]
},
{
title: "Professional Details" ,
variables: [ "job_title" , "department" , "years_experience" ],
conditional: {
show: { when: "user_type" , equals: "employee" }
}
},
{
title: "Preferences" ,
variables: [ "interests" , "notification_preferences" , "language" ]
}
],
validation: "progressive" , // Validate each step
saveProgress: true // Auto-save between steps
};
Challenge Submission
// Challenge with custom data collection
const challengeSubmission = {
action: {
type: "quiz" ,
question: "What is the capital of France?" ,
options: [ "London" , "Berlin" , "Paris" , "Madrid" ],
correctAnswer: "Paris" ,
points: 100
},
additionalData: {
variables: [
{
name: "confidence_level" ,
label: "How confident are you?" ,
type: "range" ,
min: 0 ,
max: 100
},
{
name: "learning_source" ,
label: "Where did you learn this?" ,
type: "text" ,
required: false
}
]
}
};
Data Management
Storage and Retrieval
Variables data is stored with strong typing and validation:
{
"userId" : "507f1f77bcf86cd799439011" ,
"organisationId" : "507f191e810c19729de860ea" ,
"variables" : {
"company_name" : "Acme Corp" ,
"years_experience" : 5 ,
"interests" : [ "tech" , "sales" ],
"newsletter_consent" : true
},
"metadata" : {
"submittedAt" : "2024-01-15T14:30:00.000Z" ,
"source" : "onboarding" ,
"version" : "1.0.0"
}
}
Data Export
Export collected data for analysis:
Export All Variables
Export Specific Variable
curl -X GET https://your-subdomain.nudj.cx/api/v2/admin/variables/export \
-H "x-api-token: YOUR_API_TOKEN" \
-o variables-export.csv
Analytics and Reporting
Variable Analytics
Track form completion and field performance:
Metric Description Use Case Completion Rate % of users completing field Identify friction points Error Rate % of validation failures Improve validation messages Time to Complete Average time per field Optimize form length Drop-off Points Where users abandon Simplify complex fields
For challenge questions, track:
Correct answer rate
Average time to answer
Skip rate
Difficulty scoring
Engagement metrics
Best Practices
Keep Forms Short Only ask for essential information
Progressive Disclosure Show fields based on previous answers
Clear Labels Use descriptive, jargon-free labels
Helpful Validation Provide specific, actionable error messages
Mobile Optimization Test all forms on mobile devices
Accessibility Ensure WCAG compliance for all fields
Troubleshooting
Check visibility settings and conditional logic
Verify variable is enabled in current context
Clear cache and refresh page
Test validation pattern in regex tester
Check for conflicting validation rules
Verify API endpoint for external validation
Ensure required fields are completed
Check browser console for errors
Verify user has permission to submit
Question Bank templates missing
Confirm availableInQuestionBank is enabled
Check category and tag filters
Verify permissions for template access
API Reference
Get Variables Configuration
Create Variable
Update Variable
curl -X GET https://your-subdomain.nudj.cx/api/v2/admin/variables \
-H "x-api-token: YOUR_API_TOKEN"