Skip to main content

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 validation
  • Variables - Flexible form fields for data collection
  • Question Bank - Reusable question templates
  • Validation Engine - Multi-layer validation with external API support
  • Type Safety - TypeScript and Zod schema enforcement

Accessing Questions Configuration

Navigate to questions and variables settings:
  1. Go to AdminSettingsOrganisation
  2. Click the Questions tab
  3. 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

1

Define Variable

Set the variable type, name, and label
2

Configure Validation

Add validation rules and error messages
3

Set Display Options

Configure placeholder text, help text, and visibility
4

Enable in Question Bank

Make available for reuse across contexts
5

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

1

Create Template

Build reusable question sets
2

Categorize

Organize by use case or department
3

Tag for Search

Add tags for easy discovery
4

Version Control

Track template changes over time
5

Share Across Teams

Make available organization-wide

Implementation Examples

Onboarding Form

// 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:
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:
MetricDescriptionUse Case
Completion Rate% of users completing fieldIdentify friction points
Error Rate% of validation failuresImprove validation messages
Time to CompleteAverage time per fieldOptimize form length
Drop-off PointsWhere users abandonSimplify complex fields

Question Performance

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
  • Confirm availableInQuestionBank is enabled
  • Check category and tag filters
  • Verify permissions for template access

API Reference

curl -X GET https://your-subdomain.nudj.cx/api/v2/admin/variables \
  -H "x-api-token: YOUR_API_TOKEN"
I