Skip to main content
Forms define what data is collected, how it is validated and shown, and where it is deployed. A form contains elements (fields), settings, and metadata, and is deployed to sites and years to collect submissions.

Form Architecture

Forms consist of five closely related parts:
  • Form: Container with metadata and settings (including workflow overrides)
  • FormElement: Individual fields and UI components within the form
  • FormSite: Deployment link connecting a form to a specific site and year
  • FormSubmission: Submission container for a form at a site/year
  • FormElementSubmission: Individual field values inside a submission

Form Settings

Every form stores behavioral controls inside a settings object that is validated by updateForm. Fields are optional—if you omit one, the form falls back to the organization default or the existing persisted value.

Public submission options

  • allowPublicSubmissionEdits: When true, public contributors can reopen an existing submission (or draft) and change their answers without staff intervention. When omitted, the platform’s default editing policy is applied.
  • allowPublicSubmissionSupportingDocuments: Enables the supporting-document drawer for unauthenticated contributors so they can upload evidence while filling out public forms. Leaving it undefined preserves the default document policy.
  • publicSupportingDocumentsMode: Controls how broadly attachments are allowed once allowPublicSubmissionSupportingDocuments is turned on. Accepted values:
    • all (default): Every element that supports attachments exposes the public drawer.
    • opt-in: Only elements with metadata allowSupportingDocumentsUpload: true will expose the drawer. Admins toggle this per element in the builder next to the Required switch.
All three fields are optional. If you omit a key the existing value is preserved.

Workflow override

workflowOverride is an optional object with a single type key. Accepted values are DIRECT_APPROVAL and REQUIRE_APPROVAL, matching the workflow states described below. Supplying null or omitting the object makes the form inherit the organization-level workflow rules.

Scheduling and reminders

Use the optional schedules object to force due dates and reminder behavior for either phase of the process:
  • dataEntry: Controls contributor deadlines.
  • approval: Controls reviewer deadlines.
Each schedule is a partial object with the following fields:
  • period: Currently must be the literal "MONTHLY". Other cadences will be added later, so the schema pins the value with z.literal("MONTHLY").
  • dueDay: Integer day of month between 1 and 28 (UTC).
  • reminders: Optional { enabled: boolean; offsets: number[] } block. Offsets represent how many days before dueDay to send a reminder and must be drawn from {1, 3, 7}. Invalid entries are rejected by the schema. Reminders can also be omitted entirely, which disables notifications while keeping the due day.
Under the hood, the backend uses parseFormSettings and getReminderConfig (see apps/azalt/src/server/api/routers/form/methods.ts) to coerce stored JSON and to discard malformed dueDay or offset values before running scheduled jobs.
// Example payload supplied to updateForm
{
  settings: {
    allowPublicSubmissionSupportingDocuments: true,
    workflowOverride: { type: "REQUIRE_APPROVAL" },
    schedules: {
      dataEntry: {
        period: "MONTHLY",
        dueDay: 12,
        reminders: { enabled: true, offsets: [1, 3] }
      },
      approval: {
        period: "MONTHLY",
        dueDay: 20,
        reminders: { enabled: false, offsets: [] }
      }
    }
  }
}

Form Types & Deployment

Internal forms (private)
  • One submission per FormSite (site + year) is enforced while not deleted
  • Team members enter data directly in the platform
  • CSV bulk import/export and API integration for automation
  • Auto-save UX depending on the view (create/update on change)
External forms (public)
  • Public endpoints per FormSite (no authentication)
  • Multiple submissions per site/year are allowed
  • Optional review via per-field approvals (see Workflow)
  • Optional branded header via form metadata (logo, colors)

Smart Form Features

Conditional logic: Dynamic behavior based on other elements
// Example: Show energy source details only if renewable energy is selected
{
  type: "CONDITION",
  field: "energy-type",
  operator: "equals",
  value: "renewable",
  action: "show"
}
Time Period Configuration: Flexible data collection cycles
  • YEARLY: One period unit (1)
  • MONTHLY: 12 period units (1–12)
  • QUARTERLY: 4 period units (1–4)
  • TIMESTAMP: Point-in-time entries with a recordedAt UTC timestamp (periodUnit derived from recorded month)
Distribution mode (NUMBER elements)
  • total: Values represent totals that roll up over time (e.g., emissions)
  • snapshot: Point-in-time values that should not be distributed (e.g., factors)
Units: Associate measurement units with elements for clear labeling and validation

Advanced Form Builder

Visual editor: Drag-and-drop interface for form construction
  • Real-time preview
  • Element reordering and nesting
  • Copy/paste elements across forms
  • Create from CSV or duplicate existing forms
Create forms via:
  • CSV import (bulk)
  • Duplicate & customize
  • Manual builder
Conditional logic builder: Visual interface for complex branching
  • Drag-and-drop condition creation
  • Multiple condition types (equals, contains, greater than, etc.)
  • Nested condition groups with AND/OR logic
  • Real-time validation and preview

Data Collection Workflow

1. Form Design: Build form structure with elements and logic 2. Deployment: Assign to specific sites and years
Manufacturing Plant A - 2024
Regional Office B - 2024, 2025
Supplier Network - 2024 (External)
3. Data collection: Multiple input methods
  • Direct platform entry
  • CSV import with validation
  • API integration
  • Public form submissions (if enabled)
4. Validation: Real-time and batch validation
  • Required field enforcement
  • Type/format validation
  • Conditional logic
  • Unit compatibility checks
5. Export & analysis: Flexible data extraction
  • CSV/XLSX export
  • API endpoints
  • Dashboard integration
  • Summary statistics

Workflow and Approvals

Forms inherit the organization’s default workflow and can optionally override it per form via settings:
  • DIRECT_APPROVAL: New values are saved as APPROVED
  • REQUIRE_APPROVAL: New values are saved as COMPLETED and require approval
Status is tracked on each FormElementSubmission (COMPLETED, APPROVED, REJECTED). In REQUIRE_APPROVAL mode, the submission interface exposes:
  • Inline approval controls: Each period row shows Approve, Reject, and Revert buttons with live status badges. Values that are rejected automatically revert to COMPLETED once edited again.
  • Bulk actions: For monthly or quarterly NUMBER/SINGLE_CHOICE/MULTIPLE_CHOICE/LONG_TEXT/SHORT_TEXT elements, approvers can approve or reject every populated period in one click. ACTIVITY elements continue to support bulk approvals for all rows within the same period.
  • Status persistence: Status changes update immediately in the UI (no refresh required) and are reflected in downstream reporting.
When a form is in DIRECT_APPROVAL, approval buttons are hidden and newly saved data is marked as APPROVED automatically.

Supporting Documents

Each element row can open a supporting-document drawer:
  • Private submissions: Files are attached directly to the underlying FormElementSubmission. Users can upload new evidence, download existing files, and (with permission) delete attachments.
  • Public submissions: Opening the drawer creates (or reuses) a draft submission so public contributors can upload files without logging in. The drawer lists previously uploaded documents and exposes download links; deletes are limited to authenticated staff.
  • Counters and indicators: Attachment buttons show a badge with the number of linked files, and upload/delete operations refresh immediately.
These files remain associated with the element, period unit, and (if applicable) timestamp sequence for full auditability.

Developer Mode

Submission pages expose a Copy cURL control when developer mode is enabled. The action copies a ready-to-run curl command that mirrors the current element identifier, site, year, period unit, and latest value. Teams use this to bootstrap API integrations quickly or to test REST submissions without manually crafting payloads.

Task Progress Tracking

While users enter data, the renderer emits optimistic task-progress metrics:
  • Data entry progress: Counts remaining vs. total period/element combinations up to the current month, highlighting overdue months based on schedule due days.
  • Approval progress: When approvals are required, approvers see remaining vs. total items awaiting review, plus overdue counts.
Consumers (dashboards, widgets, or custom pages) can subscribe to these callbacks to surface live completion rings, overdue badges, or workflow summaries next to the form.

Public Form Settings

For public forms, additional settings exist on the form:
  • allowPublicSubmissionEdits
  • allowPublicSubmissionSupportingDocuments

Constraints and Notes

  • FormElement keys are unique within a form
  • ACTIVITY elements cannot use the TIMESTAMP period
  • Private forms enforce one active FormSubmission per FormSite (non-deleted)

Real-World Examples

Energy Tracking Form:
  • Monthly electricity consumption (NUMBER with kWh unit)
  • Energy source selection (SINGLE_CHOICE: Grid/Solar/Wind)
  • Conditional renewable details (shown only if renewable selected)
  • Supporting documentation upload (FILE_UPLOAD)
Waste Management Form:
  • Quarterly waste streams (GROUP with multiple NUMBER fields)
  • Waste treatment method (MULTIPLE_CHOICE)
  • Diversion rate calculation (ACTIVITY with custom formula)
  • Site-specific disposal procedures (LONG_TEXT)
Supplier Assessment Form (External):
  • Company information (SHORT_TEXT fields)
  • Scope 1, 2, 3 emissions (NUMBER with tCO2e units)
  • Activity-based calculations (ACTIVITY for complex emissions)
  • Monthly data collection (MONTHLY period setting)

Operational Benefits

  • Consistency: Same form structure across all sites and time periods
  • Efficiency: Auto-save, bulk operations, and template reuse
  • Compliance: Built-in validation and audit trails
  • Scalability: Handle hundreds of sites and thousands of submissions
  • Flexibility: Adapt forms without losing historical data