Skip to content
scsiwyg
sign insign up
get startedmcpcommunityapiplaygroundswaggersign insign up
Quality Controls·The Form Engine: JSON Schemas, ZIP Packages, and Five Scopes of Inspection Forms17 Apr 2026David Olsson
Quality Controls

The Form Engine: JSON Schemas, ZIP Packages, and Five Scopes of Inspection Forms

#forms#feature#architecture#building-in-public#aimqc#devlog#quality-control

David OlssonDavid Olsson

QC forms are not generic. A transmittal form, a daily report, an NCR, and a calibration record look nothing alike. Different fields. Different signature blocks. Different required vs. optional rules. Client A's NCR form is not the same as Client B's — and both are different from the industry default. We built a form engine that handles all of this without hardcoding any of it.


The problem with hardcoded forms

The obvious approach to QC forms is to hardcode them: build a React component for each form type, wire it to a database model, done. This works for the first three form types and breaks when a client needs a different layout, an additional field, or a custom signature block.

In construction QC, form templates are part of the quality plan. Clients often have approved templates that cannot be changed without an approval process. The software has to accommodate the client's form, not force the client to use the software's form.

JSON-schema-driven templates

Every form in AIMQC is defined by a FormTemplate record with a formDefinition JSON field. The field schema describes:

  • Field list: field ID, label, type (text, number, date, select, signature, checkbox), and required status
  • Section groupings: how fields are organized visually
  • Validation rules: required fields, format constraints, conditional requirements
  • Signature block configuration: which parties sign, in what order, whether witness signature is required
  • Theme: client branding, logo placement, header format
{
  "formId": "QF-005",
  "title": "Non-Conformance Report",
  "sections": [
    {
      "id": "header",
      "fields": [
        { "id": "ncrNo", "label": "NCR No.", "type": "text", "required": true },
        { "id": "dateRaised", "label": "Date Raised", "type": "date", "required": true },
        { "id": "discipline", "label": "Discipline", "type": "select",
          "options": ["MECH", "PIPE", "ELEC", "INST", "WELD"], "required": true }
      ]
    },
    {
      "id": "description",
      "fields": [
        { "id": "description", "label": "Description of Non-Conformance",
          "type": "textarea", "required": true },
        { "id": "codeReference", "label": "Code / Spec Reference", "type": "text" }
      ]
    }
  ],
  "signatures": [
    { "role": "raisedBy", "label": "Raised By", "required": true },
    { "role": "reviewedBy", "label": "QC Manager Review", "required": true },
    { "role": "clientAcceptance", "label": "Client Acceptance", "required": false }
  ]
}

The renderer reads the schema and generates the form dynamically. Adding a field means updating the JSON. No code deployment required.

ZIP package upload

Organizations upload form packages as ZIP archives. A package contains:

  • index.json — the manifest listing all forms in the package
  • One JSON schema file per form type
  • Optional CSS or theme overrides
  • Optional logo and branding assets

We ship two reference packages in the codebase — mccool-forms and sundown-forms — covering the standard QC form set (QF-001 through QF-020): transmittals, RFIs, daily reports, NCRs, CAPAs, material inspection records, calibration logs, and more. These can be used as-is or overridden by client packages.

Five scopes

A form instance can be attached to five different parent record types:

ScopeModelExample
ProjectProjectFormProject-level quality register
Turnover PackageTurnoverPackageFormPackage-level checklist
ITPITPFormPre-inspection checklist for an ITP
ITRITRFormInspection record form
NCRNCRFormNon-conformance documentation

The same FormTemplate can be instantiated at any scope. An NCR form template generates an NCRForm instance when linked to an NCR record. The formData JSON field on the instance holds the filled-in values.

Signature capture

Signature fields in a form definition render as touch/mouse signature capture widgets. Captured signatures are stored as JSON blobs (base64 SVG or PNG) on the form instance. For high-volume deployments, the storage recommendation is to persist signature images to file storage and keep only a reference URL in the field.

Why this matters operationally

The form engine is what allows AIMQC to onboard a new client with a custom form set without a code change. The development cost of supporting a new client template is a JSON file and a ZIP upload. The forms work the first day on the new project.


David Olsson is CTO at AIMQC. Contact: dolsson@aimqc.com

Share
𝕏 Post