Backend

API contract, database changes, business logic orchestration, and integration points for the Reflex Management backend in crelio-app.

👤 Mohammad Yameen📅 Updated: May 6, 2026🏷️ backend🏷️ reflex

File References

API Layer


Model Layer


Reflex Test Configuration APIs

This section documents all backend endpoints related to:

  • Reflex Test Configuration (CRUD + enable/disable)
  • Manual Reflex Triggering
  • Trigger Evaluation

Base Path

/reflex-test/

## API

```http
POST /api-v3/finance/bill/<lab_bill_id>/update/

Configuration APIs

1. Create Configuration

  • Endpoint: POST /reflex-test/new
  • View: ReflexTestConfigurationView

Description

Creates a new reflex test configuration.

Flow

  • Validates payload → validate_payload()
  • Saves configuration → save_reflex_test_config()
  • Creates parameter rules
  • Returns serialized response

2. Fetch All Configurations

  • Endpoint: GET /reflex-test/
  • View: FetchReflexTestConfigurationView

Description

Fetches all reflex configurations for the logged-in lab.

Response

  • Total configurations
  • List of configurations with parameter rules

3. Fetch Single Configuration

  • Endpoint: GET /reflex-test/{reflex_test_id}

Description

Fetches a specific reflex test configuration.


4. Update Configuration

  • Endpoint: PUT /reflex-test/{reflex_test_id}/update

Flow

  • Validates payload
  • Updates core fields
  • Deletes old parameter rules
  • Recreates rules

5. Delete Configuration

  • Endpoint: DELETE /reflex-test/{reflex_test_id}/delete

Description

Deletes a reflex configuration and logs activity.


6. Enable Configuration

  • Endpoint: PATCH /reflex-test/{reflex_test_id}/enable

7. Disable Configuration

  • Endpoint: PATCH /reflex-test/{reflex_test_id}/disable

Description

Toggles configuration status using:

  • enable_or_disable() method
  • Activity logging

Manual Reflex APIs

Base Path

/reflex-test/manual/

1. Check Trigger Conditions

  • Endpoint: GET /reflex-test/manual/check-triggers/{lab_report_id}
  • View: DetermineTriggerForReflexTests

Description

Evaluates whether reflex tests should be triggered based on:

  • Report values
  • Configured rules
  • Parameter types

Flow

  • Fetch report
  • Fetch applicable configurations
  • Evaluate rules → fetch_triggered_tests()
  • Return triggered tests along with metadata

2. Trigger Reflex Tests Manually

  • Endpoint: POST /reflex-test/manual/trigger-reflex
  • View: ManuallyTriggerReflexTests

Description

Manually triggers reflex tests for a given report.

Required Payload

{
  "labReportId": number,
  "triggeredIndexes": { "index": "value" },
  "triggeringTestsId": number
}

Flow

  • Validates payload
  • Calls enqueue_reflex_trigger()
  • Sends job to async processing (Fusion webhook)

3. Get Configured Reflex Tests

  • Endpoint: GET /reflex-test/manual/get-configured-tests?testIds[]=1&testIds[]=2
  • View: GetConfiguredReflexTests

Description

Returns list of tests that have reflex configurations.


Internal Processing Flow

Validation Layer

  • validate_payload()
    • Checks required fields
    • Validates parameter types
    • Validates rules (range/list/descriptive)
    • Prevents conflicts and duplicates

Rule Evaluation

Handled via:

  • Range → get_range_parameter_trigger_test_ids()
  • List/Descriptive → get_list_descriptive_parameter_trigger_test_ids()
  • Multi-value → evaluate_multi_value_trigger()

Trigger Execution

  • fetch_triggered_tests() → determines eligible tests
  • fetch_related_details() → enriches test metadata
  • enqueue_reflex_trigger() → sends async job

Models Used in Reflex Management


ReflexTestConfiguration

class ReflexTestConfiguration(BaseModel):
    category_id_mapper: dict[int, str] = {
        "created": 628,
        "updated": 629,
        "triggered": 630,
        "deleted": 634,
        "enabled": 644,
        "disabled": 645,
    }

    id = models.AutoField(auto_created=True, primary_key=True)  # noqa A003
    lab = models.ForeignKey(
        "account.Labs",
        on_delete=models.CASCADE,
        null=True,
        default=None,
        db_default=None,
    )
    test = models.ForeignKey(
        "masters.AllTests",
        on_delete=models.CASCADE,
        null=True,
        default=None,
        db_default=None,
    )
    trigger_index = models.PositiveSmallIntegerField(
        null=True, default=None, db_default=None
    )
    trigger_type = models.CharField(
        choices=TRIGGER_TYPE_CHOICES,
        max_length=50,
        default="NORMAL_RANGE",
        db_default="NORMAL_RANGE",
    )
    lower_range = models.FloatField(default=0.0, null=True)
    upper_range = models.FloatField(default=0.0, null=True)
    new_tests = models.TextField(null=True, default="[]")
    create_new_bill = models.BooleanField(default=False, db_default=False)
    is_enabled = models.BooleanField(default=True)
    parameter_type = models.CharField(
        choices=PARAMETER_TYPE_CHOICES,
        max_length=50,
        default="RANGE",
        db_default="RANGE",
    )
    trigger_value = models.TextField(max_length=500, null=True)
    manual_reflex = models.BooleanField(default=False, db_default=False)
    interfacing_reflex = models.BooleanField(default=False, db_default=False)
    created_at = models.DateTimeField(auto_now_add=True, null=True)
    updated_at = models.DateTimeField(auto_now=True, null=True)
    created_by = models.ForeignKey(
        "account.LabUser",
        on_delete=models.SET_NULL,
        related_name="reflex_test_config_created_by",
        null=True,
        default=None,
        db_default=None,
    )
    updated_by = models.ForeignKey(
        "account.LabUser",
        on_delete=models.SET_NULL,
        related_name="reflex_test_config_updated_by",
        null=True,
        default=None,
        db_default=None,
    )

    def __repr__(self):
        return (
            f"ReflexTestConfiguration(id={self.id}, test={self.test}, lab={self.lab})"
        )

    class Meta:
        db_table = "ReflexTestConfiguration"
        unique_together = ("test", "trigger_index")

This model is used to store reflex test configurations.

Each configuration defines:

  • Which test + parameter to monitor
  • What conditions should trigger reflex tests
  • Which tests should be added
  • How they should be billed and executed

Key Fields

  • test → Primary test for which reflex logic is defined

  • trigger_index → Parameter index used for evaluation

  • trigger_type → Type of trigger (NORMAL_RANGE / CRITICAL / CUSTOM / etc.)

  • parameter_type → Determines rule type:

    • RANGE
    • LIST
    • DESCRIPTIVE
  • lower_range / upper_range → Used for numeric range-based conditions

  • trigger_value → Stores value for list/descriptive conditions

  • new_tests → JSON string containing reflex test IDs

  • create_new_bill → Controls billing behavior

  • manual_reflex / interfacing_reflex → Determines trigger mode

  • is_enabled → Enables/disables configuration


ReflexTestDetails

class ReflexTestDetails(BaseModel):
    bill = models.ForeignKey("finance.billing", on_delete=models.CASCADE)
    report = models.ForeignKey("masters.AllTests", on_delete=models.CASCADE)
    lab_report = models.ForeignKey("report.LabReportRelation", on_delete=models.CASCADE)
    is_triggered = models.BooleanField(default=False, db_default=False)
    triggering_method = models.CharField(max_length=100, null=True)
    parameters_triggered = models.TextField(default="[]")
    stop_auto_trigger = models.BooleanField(default=True, db_default=False)
    triggered_by_user = models.ForeignKey(
        "account.LabUser", null=True, on_delete=models.SET_NULL
    )
    triggered_time = models.DateTimeField(auto_now_add=True)
    reports_triggered = models.TextField(default="[]")
    extra_data = models.TextField(default="{}")

    class Meta:
        db_table = "ReflexTestDetails"

This model stores runtime data of triggered reflex tests.

It acts as an audit + tracking layer.

Key Fields

  • bill → Bill where reflex tests were added

  • lab_report → Associated lab report

  • report → Primary test

  • is_triggered → Whether reflex was triggered

  • triggering_method → manual / interfacing

  • parameters_triggered → Indexes that caused trigger (JSON)

  • reports_triggered → Reflex test IDs triggered (JSON)

  • triggered_by_user → User who triggered reflex

  • triggered_time → Timestamp of trigger


Reflex Triggering Flow

Handled via:

  • TriggerReflexTestInBill API view

Overview

This API is responsible for:

  • Evaluating trigger conditions
  • Determining eligible reflex tests
  • Adding tests to bill
  • Logging activity
  • Saving trigger details

Trigger Flow (Step-by-Step)

1. Payload Validation

  • Validates required fields:

    • lab_report_relation_id
    • tests_mapped
    • triggered_indexes
  • Ensures:

    • Device ID exists (for interfacing)
    • Report exists
    • Primary test exists

2. Duplicate Trigger Check

  • Checks if reflex already triggered:
    • Prevents duplicate execution
    • Logs activity

3. Determine Eligible Reflex Tests

Handled via:

  • get_trigger_eligible_tests_data()

Logic

  • Fetch configurations:
    • Based on test + trigger index
  • For each config:
    • Identify parameter type
    • Evaluate condition

4. Rule Evaluation

Range Parameters

  • Handled by:

    • get_range_parameter_trigger_test_ids()
  • Logic:

    • Fetch parameter rules
    • Determine range (custom / normal / critical)
    • Compare value
    • Collect matching reflex tests

List / Descriptive Parameters

  • Handled by:

    • get_list_descriptive_parameter_trigger_test_ids()
  • Supported conditions:

    • IS_NOT
    • CONTAINS
    • EXACT_MATCHES
    • DOES_NOT_CONTAIN
    • CONTAINS_MULTIPLE_VALUES

Multi-value Logic

  • Handled by:
    • evaluate_multi_value_trigger()
Example Structure
{
  "condition": "AND",
  "contains": ["Positive"],
  "does_not_contains": ["Negative"]
}

Evaluation Logic

  • AND
    → All conditions must match

  • OR
    → Any condition must match


5. Add Reflex Tests to Bill

Handled via:

  • add_tests_against_bill()

Flow

  • Separate tests:

    • Existing bill
    • New bill
  • Prepare payload:

    • prepare_payload_for_adding_to_bill()
  • Call billing controller:

    • commonBillAddTestController()

6. Validation Before Adding Tests

Handled via:

  • validate_addition_of_test_for_patient()

Ensures

  • No duplicate test addition
  • No circular dependencies
  • Bill is not locked

7. Activity Logging

Handled via:

  • save_success_activity()

Logs

  • Triggered tests
  • Trigger type (manual/interfacing)
  • Patient
  • Bill
  • Parameter

8. Save Trigger Details

Handled via:

  • save_reflex_details_instance()

Stores

  • Triggered tests
  • Triggering indexes
  • Trigger method
  • User + timestamp

On this page