Skip to content

Data Structure of Research Records Generated by an Airalogy Protocol

A research entry produced through an Airalogy Protocol is called an Airalogy Record.

General Structure

An Airalogy Record is stored as a JSON object that bundles metadata with the actual research data:

json
{
  "airalogy_record_id": "airalogy.id.record.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.v.2",
  "record_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", // Unique within the “record” namespace
  "record_version": 2,                                 // 1 = initial submission; increments on each update
  "metadata": { ... },
  "data": { ... }
}

For ID design details, see Airalogy IDs.

Metadata Block

json
{
  /* ── Protocol provenance ── */
  "airalogy_protocol_id": "airalogy.id.lab.lab_demo.project.project_demo.protocol.protocol_demo.v.0.0.1",

  /* ── Quick navigation fields ── */
  "lab_id": "lab_demo",
  "project_id": "project_demo",
  "protocol_id": "protocol_demo",
  "protocol_version": "0.0.1",
  "record_num": 1, // Sequential number of this record within the protocol

  /* ── Version tracking ── */
  "record_current_version_submission_time": "2024-01-02T00:00:00+08:00",
  "record_current_version_submission_user_id": "user_demo_2",
  "record_initial_version_submission_time": "2024-01-01T00:00:00+08:00",
  "record_initial_version_submission_user_id": "user_demo_1",

  /* ── Integrity check ── */
  "sha1": "c486349125db2a468172a4449b9e309b0c756c59"
}

The SHA-1 value is generated from the data block via airalogy.record.hash.get_data_sha1. Any hash algorithm could be used; SHA-1 is chosen here for speed.

Data Block

Conceptually, the data section records the values of every Airalogy Field across all templates defined in the protocol. Its first-level keys are the template names; each key’s value is a template-specific object.

Template var

json
{
  "var": {
    /* Any JSON-compatible type is allowed; validated against VarModel */

    "var_id_1": "value_1",  // string
    "var_id_2": 1,          // integer
    "var_id_3": 1.1,        // float
    "var_id_4": true,       // boolean
    "var_id_5": null,       // null
    "var_id_6": [ ... ],    // array
    "var_id_7": { ... },    // object

    "datetime": "2024-01-01T00:00:00+08:00",
    "img_airalogy_id":   "airalogy.id.file.<file_id>.png",   // reference to a file
    "record_airalogy_id":"airalogy.id.record.<record_id>.v.1"  // reference to another record
  }
}

Template step

json
{
  "step": {
    "step_id_1": {
      "annotation": "",      // Empty by default
      "checked": null        // Null when the step is not a checklist item
    },
    "step_id_2": {
      "annotation": "note",
      "checked": null
    },
    "step_id_3": {
      "annotation": "",
      "checked": false       // Checklist enabled but not yet ticked
    },
    "step_id_4": {
      "annotation": "",
      "checked": true        // Checklist ticked
    }
  }
}

Template check

json
{
  "check": {
    "check_id_1": {
      "checked": false,  // Always boolean; never null
      "annotation": ""
    },
    "check_id_2": {
      "checked": false,
      "annotation": "calibration failed"
    },
    "check_id_3": {
      "checked": true,
      "annotation": ""
    },
    "check_id_4": {
      "checked": true,
      "annotation": "acceptable deviation"
    }
  }
}

Complete Example

json
{
  "airalogy_record_id": "airalogy.id.record.01234567-0123-0123-0123-0123456789ab.v.2",
  "record_id": "01234567-0123-0123-0123-0123456789ab",
  "record_version": 2,
  "metadata": {
    "airalogy_protocol_id": "airalogy.id.lab.lab_demo.project.project_demo.protocol.protocol_demo.v.0.0.1",
    "lab_id": "lab_demo",
    "project_id": "project_demo",
    "protocol_id": "protocol_demo",
    "protocol_version": "0.0.1",
    "record_num": 1,
    "record_current_version_submission_time": "2024-01-02T00:00:00+08:00",
    "record_current_version_submission_user_id": "user_demo_2",
    "record_initial_version_submission_time": "2024-01-01T00:00:00+08:00",
    "record_initial_version_submission_user_id": "user_demo_1",
    "sha1": "c486349125db2a468172a4449b9e309b0c756c59"
  },
  "data": {
    "var": {
      "solvent_name":   "H2O",
      "solvent_volume": 1.0
    },
    "step": {
      "select_solvent": {
        "annotation": "",
        "checked": null
      }
    },
    "check": {
      "check_remaining_volume": {
        "annotation": "",
        "checked": true
      }
    }
  }
}

Notes

  1. Large or multimodal data The data block stores IDs (e.g. file IDs) rather than raw binaries, keeping records lightweight. Use the file/record APIs to retrieve the actual assets when needed.

  2. Data integritysha1 covers only the data block; metadata updates do not change the hash.

With this structure, Airalogy Records remain compact, version-controlled, and self-describing—ready for both human inspection and automated processing.