<?xml version="1.0" encoding="UTF-8"?>
<!--
  "Integration API errors": receives AE/AR ACKs and rejected per-event results routed by the sender
  channels (api-platform §12.3.1: never hold the queue on AE/AR). It keeps codes and positions only,
  raises an engine alert and writes a line the interface team reviews. It never resends.
-->
<channel version="4.5.0">
  <id>0b1d2c3e-4f50-4a61-8b72-93a4b5c6d7e4</id>
  <nextMetaDataId>2</nextMetaDataId>
  <name>Integration API errors</name>
  <description>Review queue for refused messages and events (AE, AR, rejected). Fix the mapping, then resend from the source channel.</description>
  <revision>1</revision>
  <sourceConnector version="4.5.0">
    <metaDataId>0</metaDataId>
    <name>sourceConnector</name>
    <properties class="com.mirth.connect.connectors.vm.VmReceiverProperties" version="4.5.0">
      <pluginProperties/>
      <sourceConnectorProperties version="4.5.0">
        <responseVariable>None</responseVariable>
        <respondAfterProcessing>true</respondAfterProcessing>
        <processBatch>false</processBatch>
        <firstResponse>false</firstResponse>
        <processingThreads>1</processingThreads>
        <queueBufferSize>1000</queueBufferSize>
      </sourceConnectorProperties>
    </properties>
    <transformer version="4.5.0">
      <elements>
        <com.mirth.connect.plugins.javascriptstep.JavaScriptStep version="4.5.0">
          <name>Codes only</name>
          <sequenceNumber>0</sequenceNumber>
          <enabled>true</enabled>
          <script><![CDATA[
// Keep what the API answered with (codes and positions), never the patient message itself.
var text = String(connectorMessage.getRawData());
var summary = { ack: '', codes: [] };
if (text.indexOf('MSA|') !== -1) {
  summary.ack = ingestAckCode(text);
  var segments = text.split(/\r\n|\r|\n/);
  for (var i = 0; i < segments.length; i++) {
    if (segments[i].indexOf('ERR|') === 0) {
      var fields = segments[i].split('|');
      summary.codes.push({ code: (fields[5] || '').split('^')[0], location: fields[2] || '', severity: fields[4] || '' });
    }
  }
} else {
  try {
    var result = JSON.parse(text);
    summary.codes.push({ code: result.error ? result.error.code : 'rejected', location: result.error ? result.error.path : '' });
  } catch (e) {
    summary.codes.push({ code: 'unparseable_response' });
  }
}
alerts.sendAction('Integration API refused a message: ' + JSON.stringify(summary));
channelMap.put('errorSummary', JSON.stringify(summary));
]]></script>
        </com.mirth.connect.plugins.javascriptstep.JavaScriptStep>
      </elements>
      <inboundDataType>RAW</inboundDataType>
      <outboundDataType>RAW</outboundDataType>
    </transformer>
    <filter version="4.5.0">
      <elements/>
    </filter>
    <transportName>Channel Reader</transportName>
    <mode>SOURCE</mode>
    <enabled>true</enabled>
    <waitForPrevious>true</waitForPrevious>
  </sourceConnector>
  <destinationConnectors>
    <connector version="4.5.0">
      <metaDataId>1</metaDataId>
      <name>Review log</name>
      <properties class="com.mirth.connect.connectors.js.JavaScriptDispatcherProperties" version="4.5.0">
        <pluginProperties/>
        <destinationConnectorProperties version="4.5.0">
          <queueEnabled>false</queueEnabled>
          <sendFirst>false</sendFirst>
          <retryIntervalMillis>10000</retryIntervalMillis>
          <regenerateTemplate>false</regenerateTemplate>
          <retryCount>0</retryCount>
          <rotate>false</rotate>
          <includeFilterTransformer>false</includeFilterTransformer>
          <threadCount>1</threadCount>
          <threadAssignmentVariable/>
          <validateResponse>false</validateResponse>
          <resourceIds class="linked-hash-map">
            <entry>
              <string>Default Resource</string>
              <string>[Default Resource]</string>
            </entry>
          </resourceIds>
          <queueBufferSize>1000</queueBufferSize>
          <reattachAttachments>true</reattachAttachments>
        </destinationConnectorProperties>
        <script><![CDATA[
logger.warn('integration_api_refused ' + $('errorSummary'));
return new Response(SENT, '', 'Logged for review', '');
]]></script>
      </properties>
      <transformer version="4.5.0">
        <elements/>
        <inboundDataType>RAW</inboundDataType>
        <outboundDataType>RAW</outboundDataType>
      </transformer>
      <responseTransformer version="4.5.0">
        <elements/>
        <inboundDataType>RAW</inboundDataType>
        <outboundDataType>RAW</outboundDataType>
      </responseTransformer>
      <filter version="4.5.0">
        <elements/>
      </filter>
      <transportName>JavaScript Writer</transportName>
      <mode>DESTINATION</mode>
      <enabled>true</enabled>
      <waitForPrevious>true</waitForPrevious>
    </connector>
  </destinationConnectors>
  <preprocessingScript>return message;</preprocessingScript>
  <postprocessingScript>return;</postprocessingScript>
  <deployScript>return;</deployScript>
  <undeployScript>return;</undeployScript>
  <properties version="4.5.0">
    <clearGlobalChannelMap>true</clearGlobalChannelMap>
    <messageStorageMode>PRODUCTION</messageStorageMode>
    <encryptData>true</encryptData>
    <removeContentOnCompletion>false</removeContentOnCompletion>
    <removeOnlyFilteredOnCompletion>false</removeOnlyFilteredOnCompletion>
    <removeAttachmentsOnCompletion>true</removeAttachmentsOnCompletion>
    <initialState>STARTED</initialState>
    <storeAttachments>false</storeAttachments>
    <metaDataColumns/>
    <attachmentProperties version="4.5.0">
      <type>None</type>
      <properties/>
    </attachmentProperties>
    <resourceIds class="linked-hash-map">
      <entry>
        <string>Default Resource</string>
        <string>[Default Resource]</string>
      </entry>
    </resourceIds>
  </properties>
</channel>
