## Purpose Define the TradeItem extraction schema, ExtractionResult wrapper, and mapping rules for converting sales email content into structured trade data. ## Requirements ### Requirement: TradeItem schema The system SHALL define a `TradeItem` class with the following fields representing a single trade leg extracted from a sales email: - `valuedate` (string, dd/MM/yyyy format) - `counterparty` (string, full legal name as it appears in the email) - `legal_entity` (string, nullable — populated after counterparty disambiguation via lookup tool) - `trade_id` (long, Murex trade identifier) - `display_ccy` (string, ISO currency code e.g. "GBP", "USD") - `pv` (double, present value) - `breakclause` (string, "Y" or "N") JSON serialization SHALL use snake_case property names via `[JsonPropertyName]` attributes. #### Scenario: All fields populated - **WHEN** the extraction agent produces a TradeItem with all fields - **THEN** the JSON output contains all seven fields with snake_case keys and correct types #### Scenario: Legal entity null before disambiguation - **WHEN** the extraction agent produces a TradeItem before counterparty lookup - **THEN** the `legal_entity` field is null and all other fields are populated ### Requirement: ExtractionResult wrapper The system SHALL define an `ExtractionResult` class containing a `List Items` property. All extraction output from a single email SHALL be wrapped in this object. #### Scenario: Single email with multiple trade legs - **WHEN** an email contains two swaps with two legs each (4 trades total) - **THEN** the ExtractionResult contains an `items` array with 4 TradeItem objects #### Scenario: JSON output structure - **WHEN** the ExtractionResult is serialized to JSON - **THEN** the output has the shape `{"items": [{"valuedate": "...", ...}, ...]}` ### Requirement: Extraction mapping rules The extraction agent SHALL follow these mapping rules when converting email content to TradeItems: - Each swap leg (identified by a unique Murex trade ID) becomes a separate TradeItem - The `valuedate` SHALL be parsed from date references in the email (e.g., "OB 27/11/2025") and formatted as dd/MM/yyyy - The `counterparty` SHALL be the full legal entity name as stated in the email prose - The `display_ccy` SHALL be derived from the currency symbol or code in the email (e.g., "£" or "PV (£)" → "GBP") - The `breakclause` SHALL default to "N" if not explicitly mentioned in the email - The `pv` SHALL be the numeric present value without formatting (no commas, no currency symbols) #### Scenario: Flatten multi-leg swap into individual items - **WHEN** the email contains a swap with Coupon Leg (Murex 79353083) and APD leg (Murex 79353084) - **THEN** the output contains two separate TradeItems, one per Murex ID #### Scenario: Currency symbol to ISO code mapping - **WHEN** the email shows PV values in "PV (£)" column - **THEN** the `display_ccy` field is set to "GBP" #### Scenario: Default breakclause - **WHEN** the email does not mention break clauses - **THEN** all TradeItems have `breakclause` set to "N"