Skip to content

feat: Add interpretation trace mode for step-by-step rule execution visibility #86

Description

@MagPasulke

Summary

Add an optional trace mode to the interpretation engine that returns step-by-step details of how each rule in a RuleSet was evaluated against the input string. When enabled via ?trace=true on the HTTP API, the response includes a trace array alongside the existing results.

Example Response (trace enabled)

{
  "rulesetId": "GS1_DATAMATRIX",
  "input": "01034531200000111719112510ABC123",
  "results": [
    { "targetField": "GTIN", "value": "03453120000011" },
    { "targetField": "EXPIRY_DATE", "value": "2019-11-25" },
    { "targetField": "BATCH", "value": "ABC123" }
  ],
  "trace": {
    "totalRules": 4,
    "matchedRules": 3,
    "steps": [
      {
        "step": 1,
        "ruleId": "010",
        "type": "MATCH",
        "targetField": "GTIN",
        "regex": "01(\\d{14})",
        "offset": 0,
        "matched": true,
        "capturedGroup": "03453120000011",
        "matchPosition": { "start": 0, "end": 16 },
        "resultValue": "03453120000011"
      },
      {
        "step": 2,
        "ruleId": "020",
        "type": "MATCH",
        "targetField": "EXPIRY_RAW",
        "regex": "17(\\d{6})",
        "offset": 0,
        "matched": true,
        "capturedGroup": "191125",
        "matchPosition": { "start": 16, "end": 24 },
        "resultValue": "191125"
      },
      {
        "step": 3,
        "ruleId": "030",
        "type": "REPLACE",
        "targetField": "EXPIRY_DATE",
        "regex": "(\\d{2})(\\d{2})(\\d{2})",
        "replacePattern": "20$1-$2-$3",
        "offset": 0,
        "sourceValue": "191125",
        "matched": true,
        "resultValue": "2019-11-25"
      },
      {
        "step": 4,
        "ruleId": "040",
        "type": "MATCH",
        "targetField": "BATCH",
        "regex": "10([A-Za-z0-9]{1,20})",
        "offset": 0,
        "matched": true,
        "capturedGroup": "ABC123",
        "matchPosition": { "start": 24, "end": 32 },
        "resultValue": "ABC123"
      }
    ]
  }
}

Implementation Suggestions

Data Model (new objects)

Object Type Description
zasis_trace_step Structure Single trace entry: step#, rule_id, type, regex, target_field, matched, raw_match, position_start, position_end, result_value, source_value (for REPLACE), offset_pre, offset_post
zasis_tt_trace Table Type Standard table of zasis_trace_step

Changes to Existing Objects

Object Change
zasis_interpret_output Add optional field trace TYPE zasis_tt_trace
zasis_if_interpreter~execute Add optional parameter with_trace TYPE abap_bool DEFAULT abap_false
zasis_cl_interpreter Inside the rule LOOP, conditionally collect trace data; use FIND ... MATCH OFFSET ... MATCH LENGTH for position tracking in MATCH rules
zasis_cl_http_handler_core Parse ?trace=true query parameter; pass to interpreter; serialize trace in JSON response

Design Principles

  • Zero overhead when offIF with_trace = abap_true guard around trace collection; no extra allocations or regex calls when disabled
  • Same execution path — Trace observes existing logic, does not alter rule evaluation behavior
  • Optional in response — JSON serializer skips empty trace field; existing consumers see no change
  • Position tracking — Replace match() with FIND ... RESULTS to capture match offset/length (only when trace is active, or always if the overhead is negligible)

Affected Layers

  1. dm — New structure + table type
  2. bo — Interpreter interface + implementation
  3. srv — HTTP handler query param parsing + JSON serialization
  4. tests — Unit tests for trace output, ICF integration tests for ?trace=true endpoint

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions