# Form Builder Engine

# Form Builder Engine

## Overview

A comprehensive platform for creating dynamic forms with multi-page support, automatic data collection, response management, and analytics. The platform serves multiple services (Calls for Applications, Fund Applications, Innovation Programs, etc.) using a unified form builder engine.

---

## Core Concepts

### 1. Platform Hierarchy

```
Platform
  └── Services (Fund Applications, Calls, Innovation Programs)
      └── Forms (Application Forms, Surveys, Feedback)
          └── Responses (User Submissions)

```

### 2. Key Components

- **Services**: Programs, calls, or events that require data collection
- **Forms**: Customizable multi-page forms attached to services
- **Responses**: User submissions with answers to form fields
- **Analytics**: Insights and reports from collected responses

### 3. Null Handling Principle

Throughout this API, `null` values and omitted properties have specific meanings:

**For Objects (settings, validation, cover\_page, etc.):**

- ❌ `"settings": null` - INVALID, don't set entire object to null
- ✅ `"settings": {"accept_responses": true, "require_login": null}` - VALID
- ✅ `"settings": {}` - VALID (empty object, use defaults)
- ✅ Omit object entirely - VALID (use defaults)

**For Individual Properties:**

- `"max_length": null` - No validation for this property
- `"max_length": 100` - Apply validation with value 100
- Omit property entirely - Same as `null`, no validation

**Key Rule:**

- **Individual keys can be `null`** (means "not applicable" or "disabled")
- **Entire objects should NOT be `null`** (use empty object `{}` or omit instead)

**Examples:**

✅ **Correct:**

```json
{
  "validation": {
    "min": null,
    "max": 100
  }
}

```

✅ **Correct:**

```json
{
  "validation": {}
}

```

✅ **Correct:**

```json
{
  // validation omitted entirely
}

```

❌ **Incorrect:**

```json
{
  "validation": null
}

```

---

## Services

### Service Structure

Services represent the various programs, calls, or initiatives on the platform. Each service can have one or more forms attached to it.

```json
{
  "service": {
    "id": "uuid",
    "name": "FUND_APPLICATION",
    "title": "2026 Research Innovation Fund",
    "description": "Annual research funding program",
    "status": "ACTIVE",
    "start_date": "2026-02-01T00:00:00Z",
    "end_date": "2026-03-31T23:59:59Z",
    "settings": {
      "max_applications": 500,
      "require_review": true,
      "auto_acknowledge": true
    },
    "created_by": "uuid",
    "created_at": "2026-01-01T00:00:00Z"
  }
}

```

### Service Types (Enums)

```json
{
  "service_types": [
    "CALL_FOR_APPLICATIONS",
    "FUND_APPLICATION",
    "INNOVATION_APPLICATION",
    "EVENT_REGISTRATION",
    "SURVEY",
    "FEEDBACK_FORM",
    "SCHOLARSHIP_APPLICATION",
    "VENDOR_REGISTRATION",
    "MEMBERSHIP_APPLICATION"
  ]
}

```

---

## Forms

### Form Structure

Forms are the data collection instruments. Each form belongs to a service and contains pages with fields.

```json
{
  "form": {
    "id": "uuid",
    "title": "Startup Funding Application",
    "description": "Apply for our startup incubator program",
    "service_id": "uuid",
    "service_name": "FUND_APPLICATION",
    "status": "PUBLISHED",
    "created_by": "uuid",
    "created_at": "2026-01-10T00:00:00Z",
    
    "cover_page": {
      "enabled": true,
      "title": "Welcome to Startup Funding 2026",
      "description": "Thank you for your interest in our program. This application will take approximately 15 minutes to complete.",
      "image_url": "https://example.com/cover-image.jpg",
      "button_text": "Start Application"
    },
    
    "settings": {
      "accept_responses": true,
      "require_login": true,
      "allow_multiple_submissions": false,
      "response_deadline": "2026-03-31T23:59:59Z",
      "send_confirmation_email": true,
      "allow_save_draft": true
    },
    "structure": {
      "pages": []
    }
  }
}

```

### Cover Page

The cover page is an optional introduction screen shown before the first page of the form. It provides context and sets expectations for the user.

**Cover Page Configuration:**

Each property can be:

- **Set to a value**: Property is used
- **Set to `null`**: Property not used (use defaults)
- **Omitted entirely**: Property not used

**Cover Page Properties:**

- `enabled`: `true` = show cover page, `false` or `null` = skip to first page
- `title`: String or `null` (uses form title as default)
- `description`: String or `null` (no description shown)
- `image_url`: String URL or `null` (no image)
- `button_text`: String or `null` (defaults to "Start")

**Example with all properties:**

```json
{
  "cover_page": {
    "enabled": true,
    "title": "2026 Research Innovation Fund Application",
    "description": "Welcome! We're excited that you're applying for our research funding program. This application consists of 3 sections and will take approximately 20 minutes to complete. You can save your progress and return at any time.",
    "image_url": "https://storage.example.com/fund-banner.jpg",
    "button_text": "Start Application"
  }
}

```

**Example with nulls (minimal cover page):**

```json
{
  "cover_page": {
    "enabled": true,
    "title": "Welcome",
    "description": null,    // No description
    "image_url": null,      // No image
    "button_text": null     // Defaults to "Start"
  }
}

```

**Example: No cover page:**

```json
{
  "cover_page": {
    "enabled": false,
    "title": null,
    "description": null,
    "image_url": null,
    "button_text": null
  }
}

```

OR simply omit the cover\_page object entirely.

**When cover page is enabled, the user flow is:**

1. User opens form → sees cover page
2. User clicks "Start Application" → navigates to first page
3. User completes pages → submits form

**When cover page is disabled:**

1. User opens form → directly loads first page
2. User completes pages → submits form

### Form Settings

Settings control form behavior and user experience. Each setting can be:

- **Set to a value**: Setting is applied
- **Set to `null`**: Setting not applicable/disabled
- **Omitted entirely**: Setting not applicable/disabled

**IMPORTANT:**

- ❌ `"settings": null` - This is INVALID, don't use this
- ✅ `"settings": {"accept_responses": true, "require_login": null}` - This is VALID
- ✅ `"settings": {}` - This is VALID (all settings disabled/default)

**Available Settings:**

- **accept\_responses**: `true` = accepting submissions, `false` = closed, `null` = default (true)
- **require\_login**: `true` = authenticated only, `false` = allow anonymous, `null` = default (false)
- **allow\_multiple\_submissions**: `true` = multiple allowed, `false` = one per user, `null` = default (false)
- **response\_deadline**: ISO datetime string or `null` (no deadline)
- **send\_confirmation\_email**: `true` = send email, `false` = no email, `null` = default (false)
- **allow\_save\_draft**: `true` = can save drafts, `false` = must complete, `null` = default (false)

**Examples:**

```json
// All settings specified
{
  "settings": {
    "accept_responses": true,
    "require_login": true,
    "allow_multiple_submissions": false,
    "response_deadline": "2026-03-31T23:59:59Z",
    "send_confirmation_email": true,
    "allow_save_draft": true
  }
}

```

```json
// Some settings null (not applicable)
{
  "settings": {
    "accept_responses": true,
    "require_login": true,
    "allow_multiple_submissions": false,
    "response_deadline": null,              // No deadline
    "send_confirmation_email": null,        // Use default (false)
    "allow_save_draft": true
  }
}

```

```json
// Minimal settings (others default)
{
  "settings": {
    "accept_responses": true,
    "require_login": true
  }
}

```

---

## Form Structure

### Pages

Forms are organized into pages for better user experience and logical grouping.

```json
{
  "structure": {
    "pages": [
      {
        "page_id": "uuid",
        "title": "Basic Information",
        "description": "Tell us about your company",
        "order": 1,
        "action": {
          "type": "NEXT",
          "button_text": "Continue",
          "next_page_id": "uuid-page-2"
        },
        "fields": []
      },
      {
        "page_id": "uuid-page-2",
        "title": "Project Details",
        "description": "Describe your project",
        "order": 2,
        "action": {
          "type": "SUBMIT",
          "button_text": "Submit Application",
          "next_page_id": null
        },
        "fields": []
      }
    ]
  }
}

```

**Page Properties:**

- `page_id`: Unique identifier (UUID)
- `title`: Page heading displayed to users
- `description`: Optional help text for the page
- `order`: Display sequence (1, 2, 3...)
- `action`: What happens when user completes this page
- `fields`: Array of field definitions

**Page Actions:**

Pages can have different actions that determine what happens when the user clicks the button at the bottom of the page.

**Action Types:**

1. **NEXT** - Navigate to next page

```json
{
  "action": {
    "type": "NEXT",
    "button_text": "Continue",
    "next_page_id": "uuid-of-next-page"
  }
}

```

2. **SUBMIT\_AND\_NEXT** - Save as draft and go to next page

```json
{
  "action": {
    "type": "SUBMIT_AND_NEXT",
    "button_text": "Save & Continue",
    "next_page_id": "uuid-of-next-page"
  }
}

```

3. **SUBMIT** - Final submission (last page)

```json
{
  "action": {
    "type": "SUBMIT",
    "button_text": "Submit Application",
    "next_page_id": null
  }
}

```

The action type determines:

- Button text shown to user
- Whether data is saved as draft or final submission
- Which page loads next (if any)

---

## Fields

### Field Types

Fields are the individual input elements within pages. The platform supports various field types:

#### Standard Input Fields

**TEXT**

- Single-line text input
- Use for: names, titles, short answers
- Validation: min\_length, max\_length

**TEXTAREA**

- Multi-line text input
- Use for: descriptions, essays, detailed answers
- Validation: min\_length, max\_length

**EMAIL**

- Email address with format validation
- Use for: contact emails, business emails
- Validation: email format (automatic)

**PHONE**

- Phone number input
- Use for: contact numbers, mobile phones
- Validation: phone format (automatic)

**NUMBER**

- Numeric input
- Use for: age, quantity, amounts
- Validation: min, max

**URL**

- Website URL with validation
- Use for: company website, portfolio links
- Validation: url format (automatic)

**DATE**

- Date picker
- Use for: birth dates, project start dates
- Validation: min\_date, max\_date

**TIME**

- Time picker
- Use for: meeting times, availability
- Validation: time format (automatic)

**DATETIME**

- Combined date and time picker
- Use for: event dates, deadlines
- Validation: min\_datetime, max\_datetime

**DROPDOWN**

- Select one option from dropdown
- Use for: countries, industries, categories
- Requires: options array with option\_id

**RADIO**

- Radio button selection (single choice)
- Use for: yes/no, gender, preferences
- Requires: options array with option\_id

**CHECKBOX**

- Multiple selection checkboxes
- Use for: skills, interests, technologies
- Requires: options array with option\_id
- Validation: min\_selections, max\_selections

**FILE**

- File upload
- Use for: resumes, pitch decks, documents
- Validation: accept (file types), max\_size\_mb

**RATING**

- Star or numeric rating
- Use for: satisfaction, skill level
- Configuration: max\_rating (e.g., 5 stars)

**SCALE**

- Linear scale (1-10)
- Use for: agreement scales, priority levels
- Configuration: min\_value, max\_value

**SLIDER**

- Draggable slider
- Use for: budget ranges, confidence levels
- Configuration: min, max, step

**ADDRESS**

- Full address input
- Use for: mailing addresses, office locations
- Auto-formats address fields

**CURRENCY**

- Currency amount input
- Use for: funding amounts, budgets
- Configuration: currency\_code
- Validation: min, max

**SIGNATURE**

- Digital signature capture
- Use for: agreements, authorizations

#### Display Fields

**SECTION\_HEADER**

- Visual divider with heading text
- Use for: organizing form sections

**PARAGRAPH**

- Display-only text
- Use for: instructions, disclaimers, information

#### Auto-Collect Fields

**SOCIAL\_PROFILE**

- Auto-fill from user's social profile
- Can pull: email, phone, name, organization, etc.
- User can modify if allowed

**SYSTEM\_FIELD**

- Auto-populated system metadata
- Examples: timestamps, IPs, user IDs, service context
- Never user-modifiable

---

## Field Definition

### Complete Field Structure

```json
{
  "field": {
    "field_id": "uuid",
    "order": 1,
    "type": "TEXT",
    "label": "Company Name",
    "description": "Enter your registered company name",
    "placeholder": "e.g., Tech Innovations Inc",
    "required": true,
    
    "validation": {
      "min_length": 2,
      "max_length": 100
    }
  }
}

```

### Field Properties Explained

**Core Properties:**

- `field_id`: Unique identifier (UUID)
- `order`: Display sequence within the page
- `type`: Field type (TEXT, EMAIL, DROPDOWN, etc.)
- `label`: Question or field label shown to user
- `description`: Help text displayed below the field
- `placeholder`: Example text inside input
- `required`: Whether field must be answered

**Validation:**

- Rules to ensure data quality
- Type-specific validators (min\_length, max, min\_date, etc.)
- System generates appropriate error messages

**Options (for selection fields):**

- DROPDOWN, RADIO, CHECKBOX require `options` array
- Each option has: `option_id`, `label`, `order`

---

## Social Profile Fields

### Purpose

Automatically populate user information from their profile to reduce friction and ensure data accuracy.

### Configuration

```json
{
  "field": {
    "field_id": "uuid",
    "order": 1,
    "type": "SOCIAL_PROFILE",
    "label": "Your Information",
    "description": "This will be auto-filled from your profile",
    "profile_id": "user_profile_id",
    "user_can_modify": true,
    "required": true
  }
}

```

**No need to specify which profile fields to pull!** The system automatically returns all available profile data:

- EMAIL
- PHONE
- FIRST\_NAME
- LAST\_NAME
- FULL\_NAME
- PROFILE\_PICTURE
- DATE\_OF\_BIRTH
- GENDER
- ADDRESS
- COUNTRY
- CITY
- ORGANIZATION
- JOB\_TITLE
- DEPARTMENT
- LANGUAGE
- TIMEZONE

If a field doesn't exist in the user's profile, it will be null or omitted.

### User Control

**user\_can\_modify**:

- `true`: User can edit the auto-filled values
- `false`: All fields are read-only, user cannot change anything

### Privacy &amp; Consent

**Social profile fields containing sensitive data require user consent:**

Sensitive profile fields include:

- **EMAIL**
- **PHONE**
- **DATE\_OF\_BIRTH**
- **ADDRESS**

**How Consent Works:**

```json
{
  "field": {
    "field_id": "uuid",
    "order": 1,
    "type": "SOCIAL_PROFILE",
    "label": "Your Contact Information",
    "description": "This will be auto-filled from your profile",
    "profile_id": "user_profile_id",
    "user_can_modify": true,
    "required": true,
    "requires_consent": true,
    "consent_text": "I consent to sharing my email and phone number for this application."
  }
}

```

**Consent Properties:**

- `requires_consent`: Set to `true` for sensitive data
- `consent_text`: Custom message explaining what data is being collected and why

**When Form Loads:**

1. Social profile data is fetched but not displayed
2. Consent checkbox appears with the specified `consent_text`
3. User must check the box to accept
4. Only after consent is given, the fields are populated and shown
5. Consent decision is recorded with the response

**Non-Sensitive Profile Fields (No Consent Required):**

- FIRST\_NAME
- LAST\_NAME
- FULL\_NAME
- PROFILE\_PICTURE
- ORGANIZATION
- JOB\_TITLE
- DEPARTMENT
- LANGUAGE
- TIMEZONE
- COUNTRY
- CITY (without full address)

**Multiple Social Profile Fields:**

You can add multiple SOCIAL\_PROFILE fields in the same form with different settings:

```json
{
  "fields": [
    {
      "field_id": "field-uuid-1",
      "type": "SOCIAL_PROFILE",
      "label": "Primary Contact Information",
      "profile_id": "user_profile_id",
      "user_can_modify": true
    },
    {
      "field_id": "field-uuid-2",
      "type": "SOCIAL_PROFILE",
      "label": "Account Details (Read-only)",
      "profile_id": "user_profile_id",
      "user_can_modify": false
    }
  ]
}

```

Both pull from the same profile but have different modification permissions.

---

## System Fields

### Purpose

Capture system-generated metadata automatically without user input. Used for tracking, auditing, and context.

### Configuration

```json
{
  "field": {
    "field_id": "uuid",
    "order": 99,
    "type": "SYSTEM_FIELD",
    "label": "Submission Timestamp",
    
    "system_field_type": "SUBMISSION_TIMESTAMP",
    "user_can_modify": false,
    "show_in_form": false
  }
}

```

### Available System Field Types

**User Context:**

- **USER\_ID**: Unique user identifier
- **REGISTRATION\_DATE**: When user registered on platform

**Submission Context:**

- **SUBMISSION\_TIMESTAMP**: Exact time of form submission
- **IP\_ADDRESS**: User's IP address
- **USER\_AGENT**: Browser and device information
- **DEVICE\_TYPE**: Desktop, Mobile, or Tablet
- **BROWSER**: Browser name and version
- **REFERRER\_URL**: Page user came from

**Service Context:**

- **SERVICE\_ID**: Associated service UUID
- **SERVICE\_NAME**: Service type (FUND\_APPLICATION, etc.)
- **FORM\_ID**: Form UUID
- **FORM\_TITLE**: Name of the form

### Characteristics

- Always `user_can_modify: false`
- Usually `show_in_form: false` (hidden)
- Auto-populated at submission time
- Cannot be edited by users

### Privacy &amp; Consent

**Sensitive system fields require user consent before collection:**

Sensitive fields include:

- **EMAIL** (from user profile)
- **PHONE** (from user profile)
- **IP\_ADDRESS**
- **USER\_AGENT**
- **DEVICE\_TYPE**
- **BROWSER**
- **REFERRER\_URL**

**How Consent Works:**

1. Form must display consent checkbox for each sensitive field type being collected
2. User must explicitly check the box to accept data collection
3. Form cannot be submitted until consent is given
4. Consent is recorded with the response

**Consent Configuration:**

```json
{
  "field": {
    "field_id": "uuid",
    "order": 99,
    "type": "SYSTEM_FIELD",
    "label": "IP Address",
    "system_field_type": "IP_ADDRESS",
    "user_can_modify": false,
    "show_in_form": false,
    "requires_consent": true,
    "consent_text": "I agree to share my IP address for security and fraud prevention purposes."
  }
}

```

**Multiple Consents Example:**

```json
{
  "fields": [
    {
      "field_id": "sys-field-1",
      "type": "SYSTEM_FIELD",
      "system_field_type": "IP_ADDRESS",
      "requires_consent": true,
      "consent_text": "I consent to collection of my IP address for security purposes."
    },
    {
      "field_id": "sys-field-2",
      "type": "SYSTEM_FIELD",
      "system_field_type": "USER_AGENT",
      "requires_consent": true,
      "consent_text": "I consent to collection of my browser information for analytics."
    }
  ]
}

```

**Non-Sensitive Fields (No Consent Required):**

- USER\_ID
- SUBMISSION\_TIMESTAMP
- SERVICE\_ID
- SERVICE\_NAME
- FORM\_ID
- FORM\_TITLE

These are necessary for basic form functionality and don't require explicit consent.

---

## Field Examples

### Text Field

```json
{
  "field_id": "uuid",
  "order": 1,
  "type": "TEXT",
  "label": "Company Name",
  "placeholder": "e.g., Acme Corporation",
  "required": true,
  "validation": {
    "min_length": 2,
    "max_length": 100
  }
}

```

### Email Field

```json
{
  "field_id": "uuid",
  "order": 2,
  "type": "EMAIL",
  "label": "Contact Email",
  "placeholder": "name@company.com",
  "required": true,
  "validation": {
    "email_format": true
  }
}

```

### Dropdown Field

```json
{
  "field_id": "uuid",
  "order": 3,
  "type": "DROPDOWN",
  "label": "Industry",
  "placeholder": "Select your industry",
  "required": true,
  "options": [
    {"option_id": "opt-tech-uuid", "label": "Technology", "order": 1},
    {"option_id": "opt-health-uuid", "label": "Healthcare", "order": 2},
    {"option_id": "opt-finance-uuid", "label": "Finance", "order": 3},
    {"option_id": "opt-education-uuid", "label": "Education", "order": 4}
  ]
}

```

**Response (selected option\_id):**

```json
{
  "answers": {
    "field-uuid-industry": {
      "value": "opt-tech-uuid",
      "answered_at": "2026-01-15T14:28:30Z",
      "auto_populated": false,
      "edited": false
    }
  }
}

```

### Radio Button Field

```json
{
  "field_id": "uuid",
  "order": 4,
  "type": "RADIO",
  "label": "Company Stage",
  "required": true,
  "options": [
    {"option_id": "opt-idea-uuid", "label": "Idea Stage", "order": 1},
    {"option_id": "opt-mvp-uuid", "label": "MVP", "order": 2},
    {"option_id": "opt-revenue-uuid", "label": "Revenue Generating", "order": 3}
  ]
}

```

**Response (selected option\_id):**

```json
{
  "answers": {
    "field-uuid-stage": {
      "value": "opt-mvp-uuid",
      "answered_at": "2026-01-15T14:26:00Z",
      "auto_populated": false,
      "edited": false
    }
  }
}

```

### File Upload Field

```json
{
  "field_id": "uuid",
  "order": 5,
  "type": "FILE",
  "label": "Pitch Deck",
  "description": "Upload your presentation",
  "required": true,
  "validation": {
    "accept": ".pdf,.ppt,.pptx",
    "max_size_mb": 10,
    "multiple": false
  }
}

```

### Number Field (for currency, amounts, etc.)

```json
{
  "field_id": "uuid",
  "order": 6,
  "type": "NUMBER",
  "label": "Funding Amount Requested (USD)",
  "placeholder": "50000",
  "required": true,
  "validation": {
    "min": 1000,
    "max": 100000
  }
}

```

### Checkbox Field

```json
{
  "field_id": "uuid",
  "order": 7,
  "type": "CHECKBOX",
  "label": "Technologies Used",
  "description": "Select all that apply",
  "required": true,
  "options": [
    {
      "option_id": "opt-uuid-1",
      "label": "Artificial Intelligence",
      "order": 1
    },
    {
      "option_id": "opt-uuid-2",
      "label": "Blockchain",
      "order": 2
    },
    {
      "option_id": "opt-uuid-3",
      "label": "Internet of Things",
      "order": 3
    },
    {
      "option_id": "opt-uuid-4",
      "label": "Cloud Computing",
      "order": 4
    }
  ],
  "validation": {
    "min_selections": 1,
    "max_selections": 3
  }
}

```

**Response (array of option\_ids):**

```json
{
  "answers": {
    "field-uuid-tech": {
      "value": ["opt-uuid-1", "opt-uuid-2"],
      "answered_at": "2026-01-15T14:25:00Z",
      "auto_populated": false,
      "edited": false
    }
  }
}

```

---

## Validation System

### How Validation Works

Validation is defined by **individual keys** within the validation object. Each key can be:

- **Set to a value**: Validation is applied
- **Set to `null`**: No validation for that specific rule
- **Omitted entirely**: No validation for that specific rule

**IMPORTANT:**

- ❌ `"validation": null` - This is INVALID, don't use this
- ✅ `"validation": {"min": null, "max": 20}` - This is VALID (no min, but max is 20)
- ✅ `"validation": {}` - This is VALID (no validation at all)
- ✅ Omit validation object entirely - This is VALID (no validation at all)

### Examples

**No validation at all:**

```json
{
  "type": "TEXT"
  // No validation object at all
}

```

OR

```json
{
  "type": "TEXT",
  "validation": {}
  // Empty validation object
}

```

**Only maximum (no minimum):**

```json
{
  "type": "NUMBER",
  "validation": {
    "min": null,  // No minimum validation
    "max": 100    // Maximum is 100
  }
}

```

**Only minimum (no maximum):**

```json
{
  "type": "TEXT",
  "validation": {
    "min_length": 5,      // Minimum 5 characters
    "max_length": null    // No maximum limit
  }
}

```

**Both min and max:**

```json
{
  "type": "NUMBER",
  "validation": {
    "min": 1,
    "max": 100
  }
}

```

### Validation Rules by Field Type

**TEXT / TEXTAREA:**

```json
{
  "validation": {
    "min_length": 2,      // null or omit = no minimum
    "max_length": 100     // null or omit = no maximum
  }
}

```

**NUMBER:**

```json
{
  "validation": {
    "min": 1000,    // null or omit = no minimum
    "max": 100000   // null or omit = no maximum
  }
}

```

**DATE:**

```json
{
  "validation": {
    "min_date": "2026-01-01",  // null or omit = any past date allowed
    "max_date": "2026-12-31"   // null or omit = any future date allowed
  }
}

```

**FILE:**

```json
{
  "validation": {
    "accept": ".pdf,.doc,.docx",  // null or omit = any file type
    "max_size_mb": 10,            // null or omit = no size limit
    "multiple": false             // true allows multiple files
  }
}

```

**CHECKBOX:**

```json
{
  "validation": {
    "min_selections": 1,  // null or omit = no minimum
    "max_selections": 3   // null or omit = unlimited selections
  }
}

```

**EMAIL / PHONE / URL:**

```json
{
  "validation": {
    "format": true  // Always validates format for these types (automatic)
  }
}
// Or just omit validation object entirely - format validation is automatic
{
  "type": "EMAIL"
  // Format validation applied automatically
}

```

---

## Complete Form Example

```json
{
  "form": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "title": "Startup Funding Application 2026",
    "description": "Apply for our startup incubator program",
    "service_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "service_name": "FUND_APPLICATION",
    "status": "PUBLISHED",
    
    "cover_page": {
      "enabled": true,
      "title": "Welcome to Startup Funding 2026",
      "description": "Thank you for your interest! This application takes about 15 minutes. You can save and continue later.",
      "image_url": "https://storage.example.com/cover.jpg",
      "button_text": "Start Application"
    },
    
    "structure": {
      "pages": [
        {
          "page_id": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
          "title": "Applicant Information",
          "description": "Tell us about yourself and your company",
          "order": 1,
          "action": {
            "type": "NEXT",
            "button_text": "Continue to Project Details",
            "next_page_id": "b2c3d4e5-f6a7-4b5c-8d9e-0f1a2b3c4d5e"
          },
          "fields": [
            {
              "field_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "order": 1,
              "type": "SOCIAL_PROFILE",
              "label": "Your Information",
              "description": "This will be auto-filled from your profile",
              "profile_id": "user_profile_id",
              "user_can_modify": true,
              "required": true
            },
            {
              "field_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
              "order": 2,
              "type": "TEXT",
              "label": "Company Name",
              "placeholder": "e.g., Tech Innovations Inc",
              "required": true,
              "validation": {
                "min_length": 2,
                "max_length": 100
              }
            },
            {
              "field_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
              "order": 3,
              "type": "URL",
              "label": "Company Website",
              "placeholder": "https://www.example.com",
              "required": false
            }
          ]
        },
        {
          "page_id": "b2c3d4e5-f6a7-4b5c-8d9e-0f1a2b3c4d5e",
          "title": "Project Details",
          "description": "Tell us about your project and funding needs",
          "order": 2,
          "action": {
            "type": "SUBMIT_AND_NEXT",
            "button_text": "Save & Continue to Documents",
            "next_page_id": "c3d4e5f6-a7b8-4c5d-9e0f-1a2b3c4d5e6f"
          },
          "fields": [
            {
              "field_id": "field-uuid-1",
              "order": 1,
              "type": "TEXTAREA",
              "label": "Project Description",
              "description": "Describe your project objectives and expected impact",
              "placeholder": "Tell us about your project...",
              "required": true,
              "validation": {
                "min_length": 100,
                "max_length": 2000
              }
            },
            {
              "field_id": "field-uuid-2",
              "order": 2,
              "type": "DROPDOWN",
              "label": "Industry",
              "placeholder": "Select your industry",
              "required": true,
              "options": [
                {
                  "option_id": "opt-tech-uuid",
                  "label": "Technology",
                  "order": 1
                },
                {
                  "option_id": "opt-health-uuid",
                  "label": "Healthcare",
                  "order": 2
                },
                {
                  "option_id": "opt-finance-uuid",
                  "label": "Finance",
                  "order": 3
                }
              ]
            },
            {
              "field_id": "field-uuid-3",
              "order": 3,
              "type": "NUMBER",
              "label": "Funding Amount Requested (USD)",
              "placeholder": "50000",
              "required": true,
              "validation": {
                "min": 1000,
                "max": 100000
              }
            },
            {
              "field_id": "field-uuid-4",
              "order": 4,
              "type": "CHECKBOX",
              "label": "Technologies Used",
              "description": "Select all that apply",
              "required": true,
              "options": [
                {
                  "option_id": "tech-ai-uuid",
                  "label": "Artificial Intelligence",
                  "order": 1
                },
                {
                  "option_id": "tech-bc-uuid",
                  "label": "Blockchain",
                  "order": 2
                },
                {
                  "option_id": "tech-iot-uuid",
                  "label": "IoT",
                  "order": 3
                }
              ],
              "validation": {
                "min_selections": 1,
                "max_selections": 3
              }
            }
          ]
        },
        {
          "page_id": "c3d4e5f6-a7b8-4c5d-9e0f-1a2b3c4d5e6f",
          "title": "Documents",
          "description": "Upload required documents",
          "order": 3,
          "action": {
            "type": "SUBMIT",
            "button_text": "Submit Application",
            "next_page_id": null
          },
          "fields": [
            {
              "field_id": "field-uuid-5",
              "order": 1,
              "type": "FILE",
              "label": "Pitch Deck",
              "description": "Upload your presentation",
              "required": true,
              "validation": {
                "accept": ".pdf,.ppt,.pptx",
                "max_size_mb": 10,
                "multiple": false
              }
            },
            {
              "field_id": "field-uuid-6",
              "order": 2,
              "type": "DATE",
              "label": "Proposed Project Start Date",
              "required": true,
              "validation": {
                "min_date": "2026-02-01",
                "max_date": "2026-12-31"
              }
            }
          ]
        }
      ]
    }
  }
}

```

---

## Responses

### Response Structure

When a user submits a form, a response is created containing all their answers.

```json
{
  "response": {
    "id": "9b7d8f6a-3c2e-4b1a-9d8f-7e6c5b4a3d2e",
    "form_id": "550e8400-e29b-41d4-a716-446655440000",
    "service_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "service_name": "FUND_APPLICATION",
    "submitted_by": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
    "submitted_at": "2026-01-15T14:30:00Z",
    "status": "SUBMITTED",
    "completion_time_seconds": 245,
    
    "consents": {
      "social_profile_email_phone": {
        "field_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
        "consented": true,
        "consented_at": "2026-01-15T14:24:30Z",
        "consent_text": "I consent to sharing my email and phone number for this application."
      },
      "ip_address": {
        "field_id": "sys-field-ip",
        "consented": true,
        "consented_at": "2026-01-15T14:24:35Z",
        "consent_text": "I consent to collection of my IP address for security purposes."
      }
    },
    
    "answers": {},
    
    "metadata": {
      "ip_address": "192.168.1.1",
      "user_agent": "Mozilla/5.0...",
      "browser": "Chrome",
      "device": "Desktop",
      "started_at": "2026-01-15T14:24:55Z"
    }
  }
}

```

### Response Status

Responses can have different statuses throughout their lifecycle:

- **DRAFT**: User started but hasn't submitted
- **SUBMITTED**: User completed and submitted
- **UNDER\_REVIEW**: Being reviewed by administrators
- **APPROVED**: Accepted/approved
- **REJECTED**: Not accepted
- **WITHDRAWN**: User withdrew their submission

---

## Answer Format

### Object Structure

Answers are stored as an object where keys are field IDs and values contain the answer data.

```json
{
  "answers": {
    "field_uuid_1": {
      "value": "answer value",
      "answered_at": "2026-01-15T14:25:00Z",
      "auto_populated": false,
      "edited": false
    },
    "field_uuid_2": {
      "value": "another answer",
      "answered_at": "2026-01-15T14:25:30Z",
      "auto_populated": false,
      "edited": true,
      "edit_count": 2,
      "last_edited_at": "2026-01-15T14:26:00Z"
    }
  }
}

```

### Answer Properties

**Core:**

- `value`: The actual answer (string, number, array, object, etc.)
- `answered_at`: Timestamp when answered

**Tracking:**

- `auto_populated`: Was this auto-filled?
- `edited`: Did user modify it?
- `edit_count`: How many times edited
- `last_edited_at`: When last modified

**Source (for auto-populated):**

- `source`: Where data came from (social\_profile, system)
- `profile_id`: For social profile fields
- `system_field_type`: For system fields

**Files:**

- `file_url`: URL to uploaded file
- `file_name`: Original filename
- `file_size`: Size in bytes
- `file_type`: MIME type

### Answer Examples by Field Type

**Text/Textarea/Email/Phone/URL:**

```json
{
  "field-uuid": {
    "value": "Tech Innovations Inc",
    "answered_at": "2026-01-15T14:26:00Z"
  }
}

```

**Number:**

```json
{
  "field-uuid": {
    "value": 75000,
    "answered_at": "2026-01-15T14:29:00Z"
  }
}

```

**Dropdown (stores selected option\_id):**

```json
{
  "field-uuid-industry": {
    "value": "opt-tech-uuid",
    "answered_at": "2026-01-15T14:28:30Z"
  }
}

```

**Radio (stores selected option\_id):**

```json
{
  "field-uuid-stage": {
    "value": "opt-mvp-uuid",
    "answered_at": "2026-01-15T14:26:00Z"
  }
}

```

**Checkbox (stores array of option\_ids):**

```json
{
  "field-uuid-tech": {
    "value": ["opt-uuid-1", "opt-uuid-2"],
    "answered_at": "2026-01-15T14:25:00Z"
  }
}

```

**Date:**

```json
{
  "field-uuid-date": {
    "value": "2026-06-15",
    "answered_at": "2026-01-15T14:29:30Z"
  }
}

```

**File:**

```json
{
  "field-uuid-file": {
    "value": null,
    "answered_at": "2026-01-15T14:29:30Z",
    "file_url": "https://storage.example.com/uploads/pitch-deck.pdf",
    "file_name": "pitch-deck.pdf",
    "file_size": 2048576,
    "file_type": "application/pdf"
  }
}

```

---

## Complete Response Example

```json
{
  "response": {
    "id": "9b7d8f6a-3c2e-4b1a-9d8f-7e6c5b4a3d2e",
    "form_id": "550e8400-e29b-41d4-a716-446655440000",
    "service_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "service_name": "FUND_APPLICATION",
    "submitted_by": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
    "submitted_at": "2026-01-15T14:30:00Z",
    "status": "SUBMITTED",
    "completion_time_seconds": 245,
    
    "consents": {
      "social_profile_contact": {
        "field_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
        "consented": true,
        "consented_at": "2026-01-15T14:24:30Z",
        "consent_text": "I consent to sharing my email and phone number for this application."
      },
      "system_ip_tracking": {
        "field_id": "sys-field-ip",
        "consented": true,
        "consented_at": "2026-01-15T14:24:35Z",
        "consent_text": "I consent to collection of my IP address for security purposes."
      }
    },
    
    "answers": {
      "f47ac10b-58cc-4372-a567-0e02b2c3d479": {
        "value": {
          "EMAIL": "founder@techinnovations.com",
          "PHONE": "+1234567890",
          "FULL_NAME": "John Doe",
          "ORGANIZATION": "Tech Innovations Inc"
        },
        "answered_at": "2026-01-15T14:25:00Z",
        "auto_populated": true,
        "source": "social_profile",
        "profile_id": "user_profile_id",
        "edited": true,
        "edited_fields": ["EMAIL"],
        "user_can_modify": true
      },
      
      "6ba7b810-9dad-11d1-80b4-00c04fd430c8": {
        "value": "Tech Innovations Inc",
        "answered_at": "2026-01-15T14:26:00Z",
        "auto_populated": false,
        "edited": false
      },
      
      "3f2504e0-4f89-41d3-9a0c-0305e82c3301": {
        "value": "https://techinnovations.com",
        "answered_at": "2026-01-15T14:26:30Z",
        "auto_populated": false,
        "edited": false
      },
      
      "c3d4e5f6-a7b8-4c5d-9e0f-1a2b3c4d5e6f": {
        "value": "Our project aims to revolutionize climate modeling using AI...",
        "answered_at": "2026-01-15T14:28:00Z",
        "auto_populated": false,
        "edited": false
      },
      
      "d4e5f6a7-b8c9-4d5e-0f1a-2b3c4d5e6f7a": {
        "value": "opt-tech-uuid",
        "answered_at": "2026-01-15T14:28:30Z",
        "auto_populated": false,
        "edited": false
      },
      
      "e5f6a7b8-c9d0-4e5f-1a2b-3c4d5e6f7a8b": {
        "value": 75000,
        "answered_at": "2026-01-15T14:29:00Z",
        "auto_populated": false,
        "edited": false
      },
      
      "field-uuid-4": {
        "value": ["tech-ai-uuid", "tech-bc-uuid"],
        "answered_at": "2026-01-15T14:29:15Z",
        "auto_populated": false,
        "edited": false
      },
      
      "a7b8c9d0-e1f2-4a5b-3c4d-5e6f7a8b9c0d": {
        "value": null,
        "answered_at": "2026-01-15T14:29:30Z",
        "auto_populated": false,
        "edited": false,
        "file_url": "https://storage.example.com/uploads/pitch-deck.pdf",
        "file_name": "pitch-deck.pdf",
        "file_size": 2048576,
        "file_type": "application/pdf"
      }
    },
    
    "metadata": {
      "ip_address": "192.168.1.1",
      "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
      "browser": "Chrome 120.0",
      "device": "Desktop",
      "location": {
        "country": "US",
        "city": "San Francisco"
      },
      "started_at": "2026-01-15T14:24:55Z",
      "last_saved_at": "2026-01-15T14:29:45Z"
    }
  }
}

```

---

## User Flows

### 1. Admin Creates Service

**Steps:**

1. Navigate to Services
2. Click "Create New Service"
3. Select service type (FUND\_APPLICATION, CALL\_FOR\_APPLICATIONS, etc.)
4. Fill in service details: 
    - Title
    - Description
    - Start/end dates
    - Settings (max applications, review requirements)
5. Save service
6. Service receives unique UUID

**Result:** Active service ready to have forms attached

---

### 2. Admin Creates Form

**Steps:**

1. Navigate to service
2. Click "Add Form" or "Create Form"
3. Enter form details: 
    - Title
    - Description
    - Settings (deadline, login required, etc.)
4. Form is created and linked to service with: 
    - `service_id`: UUID of parent service
    - `service_name`: Service type enum
5. Form builder opens

**Result:** Empty form ready for fields

---

### 3. Admin Builds Form

**Steps:**

**Add Page:**

1. Click "Add Page"
2. Enter page title and description
3. Page receives order number (1, 2, 3...)

**Add Regular Field:**

1. Select page
2. Click "Add Field"
3. Choose field type (TEXT, EMAIL, DROPDOWN, etc.)
4. Configure field: 
    - Label
    - Description/placeholder
    - Required/optional
    - Validation rules
    - Type-specific properties
5. Field receives: 
    - UUID
    - Order number within page

**Add Social Profile Field:**

1. Click "Add Field"
2. Choose "Social Profile"
3. Select which profile fields to pull: 
    - EMAIL
    - PHONE
    - FULL\_NAME
    - etc.
4. Configure: 
    - Can user modify? (yes/no)
    - Show in form? (yes/no)
    - Read-only display? (yes/no)
5. Field is created with `type: SOCIAL_PROFILE`

**Add System Field:**

1. Click "Add Field"
2. Choose "System Field"
3. Select system field type: 
    - SUBMISSION\_TIMESTAMP
    - USER\_ID
    - IP\_ADDRESS
    - etc.
4. System fields are typically: 
    - Not modifiable
    - Hidden from users
5. Auto-populated on submission

**Reorder:**

1. Drag and drop to reorder pages
2. Drag and drop to reorder fields within pages
3. Order numbers update automatically

**Result:** Complete multi-page form ready for publishing

---

### 4. Admin Publishes Form

**Steps:**

1. Review form structure
2. Test form (preview mode)
3. Change status to "PUBLISHED"
4. Form becomes available to users

**Result:** Users can now access and submit form

---

### 5. User Submits Form

**Steps:**

**Form Load:**

1. User navigates to service
2. User clicks on form
3. System checks if login required
4. **If form has fields requiring consent:**
    - Display consent checkboxes for each sensitive field
    - User must check each consent box
    - Consent text explains what data is collected and why
    - Only after all consents are given can user proceed
5. If cover page enabled: 
    - Show cover page with welcome message
    - User clicks "Start Application" button
    - Navigate to first page
6. If no cover page: 
    - Load first page directly
7. If SOCIAL\_PROFILE fields exist: 
    - System fetches user profile by `profile_id`
    - Auto-fills ALL available profile data (only if consent was given)
    - User sees pre-filled data (if `user_can_modify: true`)

**Page Navigation:**

1. User fills in fields on current page
2. User clicks page action button (e.g., "Continue", "Save &amp; Continue")
3. System validates required fields
4. Based on action type: 
    - **NEXT**: Move to next page (no save)
    - **SUBMIT\_AND\_NEXT**: Save as draft, move to next page
    - **SUBMIT**: Final submission
5. System navigates to `next_page_id` (if specified)

**Final Submission:**

1. User completes last page
2. User clicks "Submit Application" button (type: SUBMIT)
3. System validates all required fields across all pages
4. Response created with status "SUBMITTED"
5. **Consents recorded:**
    - All consent decisions saved with timestamps
    - Consent text recorded for audit trail
    - Cannot be modified after submission
6. System fields auto-populated (only if consent was given): 
    - USER\_ID
    - SUBMISSION\_TIMESTAMP
    - IP\_ADDRESS (if consented)
    - USER\_AGENT (if consented)
    - etc.
7. Confirmation email sent (if enabled)
8. User redirected to thank you page

**Draft Saving:**

- If `allow_save_draft: true` in form settings
- User can save progress at any time
- Response saved with status "DRAFT"
- User can return and continue later

**Result:** Complete response stored in system

---

## Key Takeaways

### Selection Fields Use option\_id

All selection-based fields (DROPDOWN, RADIO, CHECKBOX) use `option_id` in their configuration:

```json
{
  "options": [
    {"option_id": "uuid-1", "label": "Option 1", "order": 1},
    {"option_id": "uuid-2", "label": "Option 2", "order": 2}
  ]
}

```

### Responses Store option\_id Values

When users select options, responses store the `option_id`:

- **DROPDOWN &amp; RADIO**: Single `option_id` string
- **CHECKBOX**: Array of `option_id` strings

```json
{
  "answers": {
    "dropdown-field": {"value": "opt-uuid-1"},
    "radio-field": {"value": "opt-uuid-2"},
    "checkbox-field": {"value": ["opt-uuid-1", "opt-uuid-3"]}
  }
}

```

This ensures data integrity and allows option labels to be updated without affecting existing responses.

### Privacy &amp; Consent Required

Sensitive data collection requires explicit user consent:

**Sensitive Fields:**

- EMAIL, PHONE (from social profile)
- IP\_ADDRESS, USER\_AGENT, BROWSER (system fields)
- DATE\_OF\_BIRTH, ADDRESS (from social profile)

**Consent Flow:**

1. Field configured with `requires_consent: true`
2. User sees consent checkbox with `consent_text`
3. User must check box to proceed
4. Consent decision recorded with timestamp
5. Data only collected if consent given

```json
{
  "requires_consent": true,
  "consent_text": "I consent to collection of my email for communication purposes."
}

```

**Non-Sensitive Fields** (no consent needed):

- USER\_ID, SUBMISSION\_TIMESTAMP, FORM\_ID
- FIRST\_NAME, LAST\_NAME, ORGANIZATION
- COUNTRY, CITY (without full address)