STD: Standard Curve Validation Rule (STDQT)
Version: v1.0.0
Status: Draft
SRS Source: docusaurus/docs/srs/rules/rule-standard-curve-validation.md
Rule Name: STDQT
Domain: RULES-STDCURVE
Overview
This document specifies tests for the Standard Curve Validation rule using decision tables and test vectors. The rule validates CT (cycle threshold) values against configured limits and verifies PCR amplification curve correlation (R-squared) with the standard curve before calculating quantity values.
Rule Characteristics:
- Pure business logic (no UI)
- Sequential validation (applicability, CT range, R2, quantity calculation)
- Configurable limits per mix/target
- Mathematical calculation (R2, quantity formula)
Test Method: TM-API (per Test Plan section 3.3 - Rules use automated API tests)
Verification Approach:
Rule verification is performed using data-driven test vectors. Each row in a decision table represents a complete verification scenario with defined inputs and expected outputs. This format enables exhaustive condition coverage while remaining concise and auditable.
Coverage Summary
| REQ ID | Title | Conditions | Test Vectors | Coverage | Gaps |
|---|
| REQ-RULES-STDCURVE-001 | Validate CT Values Against Standard Curve Parameters | 15 | 22 | 100% | None |
Totals: 1 REQ, 15 Conditions, 22 Test Vectors, 100% Coverage
REQ-RULES-STDCURVE-001: Validate CT Values Against Standard Curve Parameters
| Variable | Type | Valid Values | Description |
|---|
config.has_std_curve | bool | true, false | Whether mix/target has standard curve configuration |
config.ct_lower_limit | float? | null, numeric | Minimum acceptable CT value |
config.ct_upper_limit | float? | null, numeric | Maximum acceptable CT value |
config.r2_threshold | float | 0.0-1.0 (default 0.99) | Minimum R-squared correlation coefficient |
config.slope | float | numeric (non-zero) | Standard curve regression slope |
config.intercept | float | numeric | Standard curve regression intercept |
obs.ct_value | float? | null, NaN, numeric | Observed cycle threshold value |
obs.curve_data | array | data points | Standard curve data for R2 calculation |
calc.r2_value | float | 0.0-1.0 | Calculated R-squared from regression |
Output Variables
| Variable | Type | Description |
|---|
rule.triggered | bool | Whether the rule validation failed |
rule.failure_reason | string? | CT_BELOW_LOWER_LIMIT, CT_ABOVE_UPPER_LIMIT, POOR_CURVE_FIT, or null |
rule.status | string | NOT_APPLICABLE, PASSED, FAILED, ERROR |
well.quantity | float? | Calculated quantity (only if validation passes) |
Decision Table: Applicability Check
| TV | has_std_curve | ct_limits_config | ct_value | status | triggered | Covers |
|---|
| TV-001-001 | false | - | - | NOT_APPLICABLE | false | AC: Skip rule for mixes/targets without standard curve configuration |
| TV-001-002 | true | missing | 25 | ERROR | false | AC: Missing CT limits configuration logs error and skips rule |
| TV-001-003 | true | present | null | ERROR | false | AC: Invalid CT value (null) logs error and skips validation |
| TV-001-004 | true | present | NaN | ERROR | false | AC: Invalid CT value (NaN) logs error and skips validation |
Decision Table: CT Range Validation
| TV | ct_lower | ct_upper | ct_value | triggered | failure_reason | Covers |
|---|
| TV-001-005 | 15 | 35 | 12 | true | CT_BELOW_LOWER_LIMIT | AC: CT below lower limit triggers rule |
| TV-001-006 | 15 | 35 | 14.99 | true | CT_BELOW_LOWER_LIMIT | AC: CT just below lower limit triggers rule |
| TV-001-007 | 15 | 35 | 15 | false | null | AC: CT at lower limit passes (boundary) |
| TV-001-008 | 15 | 35 | 25 | false | null | AC: CT within range passes |
| TV-001-009 | 15 | 35 | 35 | false | null | AC: CT at upper limit passes (boundary) |
| TV-001-010 | 15 | 35 | 35.01 | true | CT_ABOVE_UPPER_LIMIT | AC: CT just above upper limit triggers rule |
| TV-001-011 | 15 | 35 | 38 | true | CT_ABOVE_UPPER_LIMIT | AC: CT above upper limit triggers rule |
Decision Table: R-squared Validation
| TV | ct_in_range | r2_threshold | calc_r2 | triggered | failure_reason | Covers |
|---|
| TV-001-012 | true | 0.99 | 0.85 | true | POOR_CURVE_FIT | AC: R2 below threshold triggers rule |
| TV-001-013 | true | 0.99 | 0.95 | true | POOR_CURVE_FIT | AC: R2 below threshold triggers rule |
| TV-001-014 | true | 0.99 | 0.989 | true | POOR_CURVE_FIT | AC: R2 just below threshold triggers rule |
| TV-001-015 | true | 0.99 | 0.99 | false | null | AC: R2 at threshold passes (boundary) |
| TV-001-016 | true | 0.99 | 0.995 | false | null | AC: R2 above threshold passes |
| TV-001-017 | true | 0.99 | 1.0 | false | null | AC: R2 at maximum passes |
| TV | SS_res | SS_tot | expected_r2 | Covers |
|---|
| TV-001-018 | 0 | 100 | 1.0 | AC: Perfect fit (R2 = 1 - 0/100 = 1.0) |
| TV-001-019 | 1 | 100 | 0.99 | AC: R2 = 1 - 1/100 = 0.99 |
| TV-001-020 | 5 | 100 | 0.95 | AC: R2 = 1 - 5/100 = 0.95 |
Decision Table: Quantity Calculation
| TV | ct_valid | r2_valid | slope | intercept | ct_value | expected_qty | status | Covers |
|---|
| TV-001-021 | true | true | -3.32 | 40 | 25 | 1584.89 | PASSED | AC: Qty = 10^((25-40)/-3.32) when both validations pass |
| TV-001-022 | true | true | -3.0 | 35 | 20 | 3162.28 | PASSED | AC: Qty = 10^((20-35)/-3.0) = 10^5 |
Decision Table: Sequential Validation Flow
| TV | has_std_curve | ct_limits | ct_valid | ct_in_range | r2_meets_threshold | final_status | quantity_calculated | Covers |
|---|
| TV-001-023 | false | - | - | - | - | NOT_APPLICABLE | false | AC: No std curve config skips rule |
| TV-001-024 | true | missing | - | - | - | ERROR | false | AC: Missing limits logs error |
| TV-001-025 | true | present | false | - | - | ERROR | false | AC: Invalid CT skips validation |
| TV-001-026 | true | present | true | false | - | FAILED | false | AC: CT out of range fails |
| TV-001-027 | true | present | true | true | false | FAILED | false | AC: R2 below threshold fails |
| TV-001-028 | true | present | true | true | true | PASSED | true | AC: All validations pass, quantity calculated |
Test File Locations
| Requirement | Test File | Automation Status |
|---|
| REQ-RULES-STDCURVE-001 | tests/Unit/Rules/StdqtRuleTest.php | Automated |
Traceability to Existing Tests
| Requirement | Jira Tests | Status |
|---|
| REQ-RULES-STDCURVE-001 | Pending | Gap |
Gap Analysis
Identified Gaps
| Gap | Requirement | Description | Priority | Owner |
|---|
| GAP-001 | REQ-RULES-STDCURVE-001 | No Jira test ticket for standard curve validation | High | TBD |
- GAP-001: Create test ticket covering TV-001-001 through TV-001-028, with emphasis on:
- Boundary conditions (CT at limits, R2 at threshold)
- Error handling (missing config, invalid CT)
- Quantity calculation verification