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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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