<?xml version="1.0"?>
<doc>
    <assembly>
        <name>Jupiter.Market.Elastic.Comparables</name>
    </assembly>
    <members>
        <member name="T:Jupiter.Market.Elastic.Comparables.Constants.QueryConstants">
            <summary>
            Provides a centralized collection of SQL query strings used throughout the application for property and deal data retrieval.
            </summary>
            <remarks>
            See the detailed conceptual article: [Query Constants Logic](../articles/query-constants-logic.md).
            <para>
            The <c>Queries</c> dictionary contains named SQL queries for retrieving property, deal, and enrichment data from the database. Each key represents a specific data retrieval scenario (e.g., EPC, geometry, images, use class, floors, built years, sales, listings, leases, etc.) for either UPRN or Title-based entities.
            </para>
            <para>
            These queries are referenced by mappers and services to populate domain models and support indexing, enrichment, and reporting workflows.
            </para>
            </remarks>
        </member>
        <member name="F:Jupiter.Market.Elastic.Comparables.Constants.QueryConstants.Queries">
            <summary>
            Gets the dictionary of named SQL queries for various property and deal data operations.
            </summary>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Helpers.DocumentHash">
            <summary>
            Provides deterministic hash computation for documents using canonical JSON serialization.
            </summary>
            <remarks>
            The hash is computed using SHA-256 over a canonical JSON representation:
            <list type="bullet">
            <item>camelCase property naming</item>
            <item>Stable enum serialization (camelCase)</item>
            <item>Ignores null values</item>
            <item>Ignores property order</item>
            <item>No indentation or whitespace differences</item>
            </list>
            This is used for efficient change detection in bulk indexing scenarios (e.g., Elasticsearch).
            </remarks>
        </member>
        <member name="F:Jupiter.Market.Elastic.Comparables.Helpers.DocumentHash.Options">
            <summary>
            Canonical JSON serialization options for hash computation.
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.DocumentHash.Compute``1(``0)">
            <summary>
            Computes a deterministic SHA-256 hash for the given document using canonical JSON serialization.
            </summary>
            <typeparam name="T">The type of the document.</typeparam>
            <param name="doc">The document to hash.</param>
            <returns>A lowercase hexadecimal string representing the SHA-256 hash of the canonical JSON.</returns>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Helpers.GeoHelper">
            <summary>
            Provides geometry transformation and enrichment utilities for property data, including reprojection and entry geometry construction.
            </summary>
            <remarks>
            See the detailed conceptual article: [Geo Helper Logic](../articles/geo-helper-logic.md).
            <para>
            Includes methods for reprojection between coordinate systems, building entry geometry for indexing, and NetTopologySuite polygon extensions.
            </para>
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.GeoHelper.ReprojectCoordinate(NetTopologySuite.Geometries.Coordinate)">
            <summary>
            Converts a single coordinate pair from EPSG:3857 to EPSG:4326.
            </summary>
            <param name="coord">The coordinate to reproject.</param>
            <returns>The reprojected coordinate.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.GeoHelper.ReprojectGeometry(NetTopologySuite.Geometries.Geometry)">
            <summary>
            Reprojects a geometry from EPSG:3857 to EPSG:4326.
            </summary>
            <param name="geom">The geometry to reproject.</param>
            <returns>The reprojected geometry, or null if input is null.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.GeoHelper.BuildEntryGeometry(System.Nullable{System.Guid},System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{System.Object}},Jupiter.Market.Elastic.Comparables.Helpers.ProjectionHelper)">
            <summary>
            Builds an <see cref="T:Jupiter.Market.Elastic.Comparables.Models.EntryGeometry"/> object for a given entry, using geometry and projection helpers.
            </summary>
            <param name="entryId">The entry ID (UPRN or Title).</param>
            <param name="geometryByUprnId">Dictionary of geometry data by entry ID.</param>
            <param name="projectionHelper">The projection helper for geometry conversion.</param>
            <returns>An <see cref="T:Jupiter.Market.Elastic.Comparables.Models.EntryGeometry"/> object, or null if no geometry is available.</returns>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Helpers.NetTopologySuiteExtensions">
            <summary>
            NetTopologySuite polygon extension methods for coordinate extraction.
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.NetTopologySuiteExtensions.CoordinatesToLinearRings(NetTopologySuite.Geometries.Polygon)">
            <summary>
            Converts a polygon's coordinates to a list of linear rings (exterior and interior).
            </summary>
            <param name="polygon">The polygon to convert.</param>
            <returns>A list of linear rings, each as a list of [lon, lat] pairs.</returns>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper">
            <summary>
            Provides helper methods for conditional logging based on configuration settings.
            </summary>
            <remarks>
            See the detailed conceptual article: <see href="xref:articles/logger-helper-logic"/>.
            <para>
            This class enables or disables information and warning logging at runtime, based on configuration keys such as <c>Logging:EnableInformationLogging</c> and <c>Logging:EnableWarningLogging</c>.
            </para>
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper.#ctor(Microsoft.Extensions.Configuration.IConfiguration,Microsoft.Extensions.Logging.ILogger)">
            <summary>
            Initializes a new instance of the <see href="xref:Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper"/> class.
            </summary>
            <param name="configuration">The application configuration.</param>
            <param name="logger">The logger instance.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper.LogInformation(System.String,System.Object[])">
            <summary>
            Logs an information message if information logging is enabled in configuration.
            </summary>
            <param name="message">The log message.</param>
            <param name="args">Optional message arguments.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper.LogWarning(System.String,System.Object[])">
            <summary>
            Logs a warning message if warning logging is enabled in configuration.
            </summary>
            <param name="message">The log message.</param>
            <param name="args">Optional message arguments.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper.LogInformation(System.Exception,System.String,System.Object[])">
            <summary>
            Logs an information message with an exception if information logging is enabled in configuration.
            </summary>
            <param name="exception">The exception to log.</param>
            <param name="message">The log message.</param>
            <param name="args">Optional message arguments.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper.LogWarning(System.Exception,System.String,System.Object[])">
            <summary>
            Logs a warning message with an exception if warning logging is enabled in configuration.
            </summary>
            <param name="exception">The exception to log.</param>
            <param name="message">The log message.</param>
            <param name="args">Optional message arguments.</param>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Helpers.ProjectionHelper">
            <summary>
            Provides helper methods for converting NetTopologySuite geometries to ElasticSearch geo shapes.
            </summary>
            <remarks>
            See the detailed conceptual article: [Projection Helper Logic](../articles/projection-helper-logic.md).
            <para>
            This class supports conversion of <c>Polygon</c> and <c>MultiPolygon</c> geometries to <see href="xref:Nest.MultiPolygonGeoShape"/> for ElasticSearch indexing.
            </para>
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.ProjectionHelper.ConvertToMultiPolygonGeoShape(NetTopologySuite.Geometries.Geometry)">
            <summary>
            Converts a NetTopologySuite <see cref="T:NetTopologySuite.Geometries.Geometry"/> (Polygon or MultiPolygon) to a <see cref="T:Nest.MultiPolygonGeoShape"/> for ElasticSearch.
            </summary>
            <param name="geometry">The geometry to convert.</param>
            <returns>A <see cref="T:Nest.MultiPolygonGeoShape"/> representing the geometry.</returns>
            <exception cref="T:System.ArgumentException">Thrown if the geometry is not a Polygon or MultiPolygon.</exception>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.ProjectionHelper.GetPolygonCoordinates(NetTopologySuite.Geometries.Polygon)">
            <summary>
            Extracts the coordinates from a polygon as a collection of linear rings.
            </summary>
            <param name="polygon">The polygon to extract coordinates from.</param>
            <returns>A collection of linear rings, each as a collection of <see cref="T:Nest.GeoCoordinate"/>.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Helpers.ProjectionHelper.ConvertLinearRingToCoordinates(NetTopologySuite.Geometries.LineString)">
            <summary>
            Converts a linear ring to a collection of <see cref="T:Nest.GeoCoordinate"/> objects.
            </summary>
            <param name="ring">The linear ring to convert.</param>
            <returns>A collection of <see cref="T:Nest.GeoCoordinate"/> objects.</returns>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper">
            <summary>
            Maps raw and enriched property data into <see href="xref:Jupiter.Market.Elastic.Comparables.Models.Comparable"/> domain entities for indexing and downstream processing.
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper.#ctor(Jupiter.Market.Elastic.Comparables.Helpers.ProjectionHelper)">
            <summary>
            Initializes a new instance of the <see href="xref:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper"/> class.
            </summary>
            <param name="projectionHelper">The projection helper for geometry transformations.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper.MapComparable(Jupiter.Market.Elastic.Comparables.Models.Comparable,System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{System.Object}},System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{System.Object}},System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{System.Object}},System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{System.Object}},System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{System.Object}},System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{System.Object}},System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{System.Object}})">
            <summary>
            Maps a <see href="xref:Jupiter.Market.Elastic.Comparables.Models.Comparable"/> and associated enrichment dictionaries into a fully populated <see href="xref:Jupiter.Market.Elastic.Comparables.Models.Comparable"/> entity.
            </summary>
            <param name="data">The base comparable data.</param>
            <param name="epcData">Dictionary of EPC ratings keyed by UPRN or TitleId.</param>
            <param name="geometryData">Dictionary of geometry data keyed by UPRN or TitleId.</param>
            <param name="imageData">Dictionary of image data keyed by UPRN or TitleId.</param>
            <param name="useClassData">Dictionary of use class data keyed by UPRN or TitleId.</param>
            <param name="floorsData">Dictionary of floor data keyed by UPRN or TitleId.</param>
            <param name="builtData">Dictionary of built year data keyed by UPRN or TitleId.</param>
            <param name="voaData">Dictionary of VOA data keyed by UPRN or TitleId.</param>
            <returns>A fully mapped <see cref="T:Jupiter.Market.Elastic.Comparables.Models.Comparable"/> entity with all available enrichment fields populated.</returns>
            <remarks>
            See the detailed conceptual article: [Comparable Mapping Logic](../articles/comparable-mapping-logic.md).
            <para>
            The method attempts to enrich the base comparable using available data keyed by <c>UPRNId</c> or <c>TitleId</c>.
            Geometry, EPC ratings, images, use classes, floors, and built years are extracted and mapped to the output entity.
            Core fields are mapped directly, while derived fields (such as <c>DealPricePerAcre</c> and <c>DealPricePerUnit</c>) are calculated if possible.
            Deal type, ownership type, and transaction type are determined using <see cref="T:Jupiter.Market.Elastic.Comparables.Mappers.DealTypeMapper"/>.
            </para>
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper.NormalizePostgresArray(System.String[])">
            <summary>
            Normalizes a Postgres array string to a string array, splitting on commas if necessary.
            </summary>
            <param name="input">The input array, possibly in Postgres array string format.</param>
            <returns>A normalized string array.</returns>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper">
            <summary>
            Maps comparable property data and deal references into a consolidated <see href="xref:Jupiter.Market.Elastic.Comparables.Models.DealData"/> domain model for indexing and downstream processing.
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper.#ctor(Microsoft.Extensions.Logging.ILogger{Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper})">
            <summary>
            Initializes a new instance of the <see href="xref:Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper"/> class.
            </summary>
            <param name="logger">The logger instance for diagnostic output.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper.MapFromComparables(Jupiter.Market.Elastic.Comparables.Models.DealReference,System.Collections.Generic.List{Jupiter.Market.Elastic.Comparables.Models.Comparable})">
            <summary>
            Maps a <see href="xref:Jupiter.Market.Elastic.Comparables.Models.DealReference"/> and a list of <see href="xref:Jupiter.Market.Elastic.Comparables.Models.Comparable"/>s into a single <see href="xref:Jupiter.Market.Elastic.Comparables.Models.DealData"/> object, prioritizing registered sales, quoting prices, and leases.
            </summary>
            <param name="dealReference">The reference information for the deal.</param>
            <param name="comparables">A list of comparable property records to aggregate.</param>
            <returns>A populated <see cref="T:Jupiter.Market.Elastic.Comparables.Models.DealData"/> instance representing the mapped deal, or a minimal object if no comparables are provided.</returns>
            <remarks>
            <para><b>Ordering Comparables:</b> Comparables are ordered by <c>ComparableStatus</c> (RegisteredSale first), then by <c>DataSource</c> priority, and finally by most recent <c>DealDate</c>.</para>
            <para><b>Deal Price Extraction Logic:</b> See the detailed conceptual article: <see href="xref:articles/deal-price-extraction"/>.</para>
            <list type="number">
              <item>
                <description>
                  If any comparables are leases (<c>IsLease == true</c>):
                  <list type="bullet">
                    <item>
                      <description>
                        <c>DealPrice</c> is taken from the first lease comparable with a non-null <c>DealPrice</c>.
                      </description>
                    </item>
                    <item>
                      <description>
                        <c>PremiumPrice</c> and <c>IsPremium</c> are also extracted from the first lease comparable with those values.
                      </description>
                    </item>
                  </list>
                </description>
              </item>
              <item>
                <description>
                  If there are no lease comparables, <c>DealPrice</c> is taken from the first ordered comparable with a non-null <c>DealPrice</c>.
                </description>
              </item>
              <item>
                <description>
                  <c>IndexedPrice</c> is always taken from the first ordered comparable with a non-null <c>DealPrice</c>.
                </description>
              </item>
              <item>
                <description>
                  <c>TotalFloorAreaInSquareFeet</c> and <c>SiteAreaInSquareFeet</c> are taken from quoting comparables first, then from sale comparables if not present.
                </description>
              </item>
              <item>
                <description>
                  <c>NumberOfUnits</c> is taken from the first ordered comparable with a non-null value.
                </description>
              </item>
              <item>
                <description>
                  Derived fields (<c>DealPricePerSquareFoot</c>, <c>DealPricePerAcre</c>, <c>DealPricePerUnit</c>) are calculated from the above values if available.
                </description>
              </item>
            </list>
            <para>
              This prioritization ensures that lease comparables take precedence for lease deals, while registered sales and quoting prices are used for other deal types, following business rules for data reliability.
            </para>
            <para>Additional fields such as <c>DealAddress</c>, <c>CountryIsoCode</c>, <c>UseClasses</c>, <c>BuiltYears</c>, and <c>Floors</c> are aggregated from the comparables as appropriate.</para>
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper.CalculateDealPricePerSquareFoot(System.Nullable{System.Decimal},System.Nullable{System.Decimal})">
            <summary>
            Calculates the price per square foot for a deal.
            </summary>
            <param name="dealPrice">The total deal price.</param>
            <param name="totalFloorAreaInSquareFeet">The total floor area in square feet.</param>
            <returns>The price per square foot, or null if not calculable.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper.CalculateDealPricePerAcre(System.Nullable{System.Decimal},System.Nullable{System.Double})">
            <summary>
            Calculates the price per acre for a deal.
            </summary>
            <param name="dealPrice">The total deal price.</param>
            <param name="siteAreaInSquareFeet">The site area in square feet.</param>
            <returns>The price per acre, or null if not calculable.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper.CalculateDealPricePerUnit(System.Nullable{System.Decimal},System.Nullable{System.Int32})">
            <summary>
            Calculates the price per unit for a deal.
            </summary>
            <param name="dealPrice">The total deal price.</param>
            <param name="numberOfUnits">The number of units in the deal.</param>
            <returns>The price per unit, or null if not calculable.</returns>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Mappers.DealTypeMapper">
            <summary>
            Provides mapping logic for deal type, ownership type, and transaction type classification based on property and lease attributes.
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.DealTypeMapper.MapDealType(Jupiter.Market.Elastic.Comparables.Models.PropertyCategory,System.Nullable{Jupiter.Market.Elastic.Comparables.Models.LeaseType},System.Boolean,System.Boolean)">
            <summary>
            Maps property and lease attributes to a <see href="xref:Jupiter.Market.Elastic.Comparables.Models.DealType"/> classification.
            </summary>
            <param name="propertyCategory">The property category (e.g., Residential, Land, Commercial).</param>
            <param name="leaseType">The lease type, if any.</param>
            <param name="vacantPossession">Indicates if the deal is vacant possession.</param>
            <param name="investmentDeal">Indicates if the deal is an investment.</param>
            <returns>The mapped <see cref="T:Jupiter.Market.Elastic.Comparables.Models.DealType"/>.</returns>
            <remarks>
            See the detailed conceptual article: [Deal Type Mapping Logic](../articles/deal-type-mapping-logic.md).
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.DealTypeMapper.MapOwnershipType(System.Nullable{Jupiter.Market.Elastic.Comparables.Models.LeaseType},Jupiter.Market.Elastic.Comparables.Models.Tenure)">
            <summary>
            Maps lease type and tenure to an <see href="xref:Jupiter.Market.Elastic.Comparables.Models.OwnershipType"/> classification.
            </summary>
            <param name="leaseType">The lease type, if any.</param>
            <param name="tenure">The tenure classification.</param>
            <returns>The mapped <see cref="T:Jupiter.Market.Elastic.Comparables.Models.OwnershipType"/>.</returns>
            <remarks>
            See the detailed conceptual article: <see href="xref:articles/deal-type-mapping-logic"/>.
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Mappers.DealTypeMapper.MapTransactionType(Jupiter.Market.Elastic.Comparables.Models.PropertyCategory,System.String,Jupiter.Market.Elastic.Comparables.Models.Tenure,System.Nullable{Jupiter.Market.Elastic.Comparables.Models.LeaseType},System.Nullable{Jupiter.Market.Elastic.Comparables.Models.TransactionType})">
            <summary>
            Maps property, sales notice, tenure, and lease attributes to a <see href="xref:Jupiter.Market.Elastic.Comparables.Models.TransactionType"/> classification.
            </summary>
            <param name="propertyCategory">The property category.</param>
            <param name="salesNoticeType">The sales notice type (e.g., "ToLet").</param>
            <param name="tenure">The tenure classification.</param>
            <param name="leaseType">The lease type, if any.</param>
            <param name="transactionType">The original transaction type, if any.</param>
            <returns>The mapped <see cref="T:Jupiter.Market.Elastic.Comparables.Models.TransactionType"/>.</returns>
            <remarks>
            See the detailed conceptual article: <see href="xref:articles/deal-type-mapping-logic"/>.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.DealReference">
            <summary>
            Represents a reference to a deal from [Table.Deal](xref:Table.Deal), containing core identifiers and metadata.
            </summary>
            <remarks>
            This class is used to fetch initial deal information before enrichment with comparables.
            See <see cref="T:Jupiter.Market.Elastic.Comparables.Models.Comparable"/> for enrichment.
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.Id">
            <summary>Gets or sets the unique identifier for the deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.UprnId">
            <summary>Gets or sets the UPRN (Unique Property Reference Number) identifier, if available.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.TitleId">
            <summary>Gets or sets the Title identifier, if available.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.PropertyType">
            <summary>Gets or sets the array of property types associated with this deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.ComparableType">
            <summary>Gets or sets the comparable type (Land, Residential, or Commercial).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.MixedUse">
            <summary>Gets or sets a value indicating whether the deal is mixed-use.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.SiteSizeInAcres">
            <summary>Gets or sets the site size in acres.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.ModifiedDate">
            <summary>Gets or sets the last modified date of the deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.DealType">
            <summary>Gets or sets the deal type (Investment, VacantPossession, etc.).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.Tenure">
            <summary>Gets or sets the tenure type (Freehold, Leasehold, etc.).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.TransactionType">
            <summary>Gets or sets the transaction type (Sale or Letting).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealReference.ValidationStatus">
            <summary>Gets or sets the validation status of the deal.</summary>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.Deal">
            <summary>
            Represents a complete deal with all associated comparables and enriched data, indexed into the [Comparables Index](xref:Elastic.ComparablesIndex).
            </summary>
            <remarks>
            <para>
            This is the primary document type indexed into the [Comparables Index](xref:Elastic.ComparablesIndex).
            Each deal aggregates multiple comparables from [Table.Listing](xref:Table.Listing), [Table.Sale](xref:Table.Sale),
            and [Table.Lease](xref:Table.Lease), and derives summary attributes from them.
            </para>
            <para>
            See <see cref="T:Jupiter.Market.Elastic.Comparables.Services.IndexerService"/> for the indexing logic.
            </para>
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.Id">
            <summary>Gets or sets the unique identifier for the deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.DocHash">
            <summary>
            Gets or sets the document hash value.
            </summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.UprnId">
            <summary>Gets or sets the UPRN identifier for the deal, if applicable.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.TitleId">
            <summary>Gets or sets the Title identifier for the deal, if applicable.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.PropertyType">
            <summary>Gets or sets the array of property types.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.ComparableType">
            <summary>Gets or sets the comparable type.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.MixedUse">
            <summary>Gets or sets a value indicating whether this is a mixed-use deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.SiteSizeInAcres">
            <summary>Gets or sets the site size in acres.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.ComparableStatus">
            <summary>Gets or sets the status of the comparable (RegisteredSale or QuotingPrice).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.OwnershipType">
            <summary>Gets or sets the ownership type (Freehold, Leasehold, etc.).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.DealType">
            <summary>Gets or sets the deal type (Investment, VacantPossession, etc.).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.ValidationStatus">
            <summary>Gets or sets the validation status of the deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.Comparables">
            <summary>Gets or sets the list of comparables associated with this deal.</summary>
            <remarks>
            Comparables include listings, sales, and leases that are aggregated to form the complete deal picture.
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Deal.DealData">
            <summary>Gets or sets the enriched deal data derived from comparables.</summary>
            <remarks>
            This contains aggregated and calculated fields such as deal price, address, and derived metrics.
            See <see cref="T:Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper"/> for mapping logic.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.DealData">
            <summary>
            Contains enriched and aggregated data for a deal, derived from its comparables.
            </summary>
            <remarks>
            This class holds calculated fields, aggregated attributes, and derived metrics that represent
            the overall deal characteristics. Values are determined by <see cref="T:Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper"/>.
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DealId">
            <summary>Gets or sets the deal identifier.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DealGeometry">
            <summary>Gets or sets the geometry information for the deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DealDate">
            <summary>Gets or sets the deal date.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.EndDate">
            <summary>Gets or sets the Lease end date.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.LeaseTerm">
            <summary>Gets or sets the Lease term in years.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DealPrice">
            <summary>Gets or sets the deal price.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.IndexedPrice">
            <summary>Gets or sets the indexed price adjusted for house price inflation.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.PremiumPrice">
            <summary>Gets or sets the premium price for the deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.IsPremium">
            <summary>Gets or sets a value indicating whether this is a premium deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.NumberOfUnits">
            <summary>Gets or sets the number of units in the deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.SiteAreaInSquareMeters">
            <summary>Gets or sets the site area in square meters.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.SiteAreaInSquareFeet">
            <summary>Gets or sets the site area in square feet.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DealPricePerSquareFoot">
            <summary>Gets or sets the deal price per square foot.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DealPricePerAcre">
            <summary>Gets or sets the deal price per acre.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DealPricePerUnit">
            <summary>Gets or sets the deal price per unit.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.TotalFloorAreaInSquareFeet">
            <summary>Gets or sets the total floor area in square feet.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.PropertyTypeArray">
            <summary>Gets or sets the array of property types.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.PropertyType">
            <summary>Gets or sets the comma-separated property type string.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.ComparableType">
            <summary>Gets or sets the comparable type.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DealAddress">
            <summary>Gets or sets the full address of the deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DealType">
            <summary>Gets or sets the deal type.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DataSources">
            <summary>Gets or sets the comma-separated data sources.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.UseClasses">
            <summary>Gets or sets the comma-separated use classes.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.UseClass">
            <summary>Gets or sets the list of use class codes.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.VoaCode">
            <summary>Gets or sets the list of VOA codes.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.PropertyCondition">
            <summary>Gets or sets the property condition (Newbuild, Secondhand, etc.).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.Floors">
            <summary>Gets or sets the comma-separated floor information.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.BuiltYears">
            <summary>Gets or sets the comma-separated built years.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.DaysOnMarket">
            <summary>Gets or sets the number of days the property was on market.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.NetYield">
            <summary>Gets or sets the net yield percentage.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.ListingAgent">
            <summary>Gets or sets the listing agent name.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.LastModified">
            <summary>Gets or sets the last modified timestamp.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.TransactionType">
            <summary>Gets or sets the transaction type (Sale or Letting).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealData.CountryIsoCode">
            <summary>Gets or sets the ISO country code.</summary>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.Comparable">
            <summary>
            Represents a single comparable property (listing, sale, or lease) associated with a deal.
            </summary>
            <remarks>
            <para>
            Comparables are sourced from [Table.Listing](xref:Table.Listing), [Table.Sale](xref:Table.Sale),
            and [Table.Lease](xref:Table.Lease), and enriched with geospatial data, EPC ratings, images, and other attributes.
            </para>
            <para>
            Multiple comparables are aggregated to form a complete <see cref="T:Jupiter.Market.Elastic.Comparables.Models.Deal"/>.
            See <see cref="T:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper"/> for mapping logic.
            </para>
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.Id">
            <summary>Gets or sets the unique identifier for the comparable.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.UPRNId">
            <summary>Gets or sets the UPRN identifier.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.TitleId">
            <summary>Gets or sets the Title identifier, if applicable.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.DealId">
            <summary>Gets or sets the associated deal identifier.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.TitleNumber">
            <summary>Gets or sets the title number.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.UPRN">
            <summary>Gets or sets the UPRN (Unique Property Reference Number).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.FullAddress">
            <summary>Gets or sets the full address of the property.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.Postcode">
            <summary>Gets or sets the postcode.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.CountryIsoCode">
            <summary>Gets or sets the ISO country code.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.ImageURL">
            <summary>Gets or sets the image URL for the property.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.OwnershipType">
            <summary>Gets or sets the ownership type.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.DealType">
            <summary>Gets or sets the deal type.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.ComparableType">
            <summary>Gets or sets the comparable type.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.TransactionType">
            <summary>Gets or sets the transaction type.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.ComparableStatus">
            <summary>Gets or sets the comparable status (RegisteredSale or QuotingPrice).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.PropertyType">
            <summary>Gets or sets the array of property types.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.BuiltYears">
            <summary>Gets or sets the array of built years.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.Floors">
            <summary>Gets or sets the array of floor information.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.TotalFloorAreaInSquareMeters">
            <summary>Gets or sets the total floor area in square meters.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.TotalFloorAreaInSquareFeet">
            <summary>Gets or sets the total floor area in square feet.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.Tenure">
            <summary>Gets or sets the tenure type.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.InvestmentPurchaseType">
            <summary>Gets or sets a value indicating whether this is an investment purchase.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.VacantPossessionPurchaseType">
            <summary>Gets or sets a value indicating whether this is a vacant possession purchase.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.SaleDate">
            <summary>Gets or sets the sale date.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.EndDate">
            <summary>Gets or sets the Lease end date.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.LeaseTerm">
            <summary>Gets or sets the Lease term in years.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.ListingDate">
            <summary>Gets or sets the listing date.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.DealDate">
            <summary>Gets or sets the deal date.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.SiteAreaInSquareMeters">
            <summary>Gets or sets the site area in square meters.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.SiteAreaInSquareFeet">
            <summary>Gets or sets the site area in square feet.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.PropertyCondition">
            <summary>Gets or sets the property condition.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.NumberOfUnits">
            <summary>Gets or sets the number of units.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.NumberOfBedrooms">
            <summary>Gets or sets the number of bedrooms.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.NumberOfBathrooms">
            <summary>Gets or sets the number of bathrooms.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.NumberOfReceptionRooms">
            <summary>Gets or sets the number of reception rooms.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.EPCRating">
            <summary>Gets or sets the list of EPC (Energy Performance Certificate) ratings.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.UseClasses">
            <summary>Gets or sets the list of use classes.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.UseClass">
            <summary>Gets or sets the list of use classes.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.VoaCode">
            <summary>Gets or sets the list of VOA codes.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.DataSource">
            <summary>Gets or sets the data source (Researched, Contributed, PublicRecords, etc.).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.SoldWithPlanningConsent">
            <summary>Gets or sets a value indicating whether the property was sold with planning consent.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.LandWithoutPlanning">
            <summary>Gets or sets a value indicating whether this is land without planning permission.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.ApplicationWithinSixMonthsOfSale">
            <summary>Gets or sets a value indicating whether a planning application was made within six months of sale.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.LastModified">
            <summary>Gets or sets the last modified timestamp.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.Geometry">
            <summary>Gets or sets the geometry information including polygon and centroid.</summary>
            <remarks>
            Geometry is transformed from Web Mercator (SRID 3857) to WGS84 (SRID 4326) for Elasticsearch compatibility.
            See <see cref="T:Jupiter.Market.Elastic.Comparables.Helpers.GeoHelper"/> and <see cref="T:Jupiter.Market.Elastic.Comparables.Helpers.ProjectionHelper"/> for transformation logic.
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.DealPrice">
            <summary>Gets or sets the deal price.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.PremiumPrice">
            <summary>Gets or sets the premium price.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.IsPremium">
            <summary>Gets or sets a value indicating whether this is a premium deal.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.DealPricePerSquareFoot">
            <summary>Gets or sets the deal price per square foot.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.DealPricePerAcre">
            <summary>Gets or sets the deal price per acre.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.DealPricePerUnit">
            <summary>Gets or sets the deal price per unit.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.IndexedPrice">
            <summary>Gets or sets the indexed price adjusted for house price inflation.</summary>
            <remarks>
            Calculated using house price indices and postcode region data.
            See <see cref="T:Jupiter.Market.Elastic.Comparables.Services.DataService"/> for calculation logic.
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.NetYield">
            <summary>Gets or sets the net yield percentage.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.LeaseType">
            <summary>Gets or sets the lease type.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.PropertyCategory">
            <summary>Gets or sets the property category.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.DaysOnMarket">
            <summary>Gets or sets the number of days the property was on market.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.RateableValue">
            <summary>Gets or sets the rateable value.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.SalesNoticeType">
            <summary>Gets or sets the sales notice type.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.ListingAgent">
            <summary>Gets or sets the listing agent name.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.Comparable.IsLease">
            <summary>Gets or sets a value indicating whether this is a lease.</summary>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.DealUprnPair">
            <summary>
            Represents a pairing of a Deal ID with a UPRN ID for batch query operations.
            </summary>
            <remarks>
            Used as a composite type parameter in PostgreSQL functions for efficient batch processing.
            Mapped to PostgreSQL composite type 'market.deal_uprn_pair2'.
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealUprnPair.DealId">
            <summary>Gets or sets the deal identifier.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealUprnPair.UprnId">
            <summary>Gets or sets the UPRN identifier.</summary>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.DealTitlePair">
            <summary>
            Represents a pairing of a Deal ID with a Title ID for batch query operations.
            </summary>
            <remarks>
            Used as a composite type parameter in PostgreSQL functions for efficient batch processing.
            Mapped to PostgreSQL composite type 'market.deal_title_pair2'.
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealTitlePair.DealId">
            <summary>Gets or sets the deal identifier.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.DealTitlePair.TitleId">
            <summary>Gets or sets the title identifier.</summary>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.EntryGeometry">
            <summary>
            Represents geospatial information for a property entry, including polygon geometry and centroid.
            </summary>
            <remarks>
            Geometry is stored in WGS84 (SRID 4326) format for Elasticsearch compatibility.
            Coordinates are transformed from Web Mercator (SRID 3857) during data processing.
            See <see cref="T:Jupiter.Market.Elastic.Comparables.Helpers.GeoHelper"/> and <see cref="T:Jupiter.Market.Elastic.Comparables.Helpers.ProjectionHelper"/> for transformation logic.
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.EntryGeometry.EntryId">
            <summary>Gets or sets the entry identifier (UPRN or Title ID).</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.EntryGeometry.MultiPolygonGeometry">
            <summary>Gets or sets the multi-polygon geometry representing the property boundary.</summary>
            <remarks>
            Indexed as geo_shape in Elasticsearch with recursive strategy for efficient spatial queries.
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.EntryGeometry.Centroid">
            <summary>Gets or sets the centroid point of the geometry.</summary>
            <remarks>
            Indexed as geo_point in Elasticsearch for distance and bounding box queries.
            </remarks>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.EntryGeometry.Area">
            <summary>Gets or sets the area of the geometry in square meters.</summary>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.GeoPoint">
            <summary>
            Represents a geographic point with latitude and longitude coordinates.
            </summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.GeoPoint.Lat">
            <summary>Gets or sets the latitude coordinate.</summary>
        </member>
        <member name="P:Jupiter.Market.Elastic.Comparables.Models.GeoPoint.Lon">
            <summary>Gets or sets the longitude coordinate.</summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Models.GeoPoint.#ctor(System.Double,System.Double)">
            <summary>
            Initializes a new instance of the <see cref="T:Jupiter.Market.Elastic.Comparables.Models.GeoPoint"/> class.
            </summary>
            <param name="lat">The latitude coordinate.</param>
            <param name="lon">The longitude coordinate.</param>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.DealIdOnly">
            <summary>
            Represents a lightweight projection containing only a deal ID and metadata.
            </summary>
            <remarks>
            Used for efficient queries and projections.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.MessageDeal">
            <summary>
            Represents a message containing a deal ID and priority for queueing.
            </summary>
            <remarks>
            Used for Service Bus message payloads.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.Postcode">
            <summary>
            Represents a postcode and its associated region.
            </summary>
            <remarks>
            Used for mapping property locations to regions and house price indices.
            See <see href="xref:Jupiter.Market.Elastic.Comparables.Models.Region"/> and <see href="xref:Jupiter.Market.Elastic.Comparables.Models.HousePriceIndex"/>.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.Region">
            <summary>
            Represents a region for house price indices and postcode grouping.
            </summary>
            <remarks>
            Contains a list of <see href="xref:Jupiter.Market.Elastic.Comparables.Models.HousePriceIndex"/> for the region.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.HousePriceIndex">
            <summary>
            Represents a house price index entry for a region and date.
            </summary>
            <remarks>
            Used for calculating indexed prices in <see href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService.CalculateIndexedPrice"/>.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.ServiceBusOffset">
            <summary>
            Represents the offset state for Service Bus message processing.
            </summary>
            <remarks>
            Used to track the last processed message for incremental data ingestion.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.ServiceBusSettings">
            <summary>
            Represents configuration settings for Azure Service Bus integration.
            </summary>
            <remarks>
            Used by <see href="xref:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService"/>.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Models.TitleNumberOnly">
            <summary>
            Represents a lightweight projection containing only a title number.
            </summary>
            <remarks>
            Used for efficient queries and projections.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Services.DataService">
            <summary>
            Provides data access, enrichment, and mapping logic for property deals, comparables, and enrichment data from PostgreSQL.
            </summary>
            <remarks>
            See the detailed conceptual article: <see href="xref:articles/data-service-logic"/>.
            <para>
            This service manages database connections, query execution, enrichment data loading, and mapping to domain models for the indexing pipeline.
            </para>
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.#ctor(Microsoft.Extensions.Options.IOptions{ElasticsearchSettings},Microsoft.Extensions.Options.IOptions{PostgresSettings},Microsoft.Extensions.Options.IOptions{IndexerSettings},Microsoft.Extensions.Logging.ILogger{Jupiter.Market.Elastic.Comparables.Services.DataService},Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper)">
            <summary>
            Initializes a new instance of the <see href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService"/> class.
            </summary>
            <param name="esOptions">Elasticsearch settings (<see href="xref:Jupiter.Market.Elastic.Comparables.Models.ElasticsearchSettings"/>).</param>
            <param name="pgOptions">PostgreSQL settings (<see href="xref:Jupiter.Market.Elastic.Comparables.Models.PostgresSettings"/>).</param>
            <param name="indexerOptions">Indexer settings (<see href="xref:Jupiter.Market.Elastic.Comparables.Models.IndexerSettings"/>).</param>
            <param name="logger">The logger instance (<see href="xref:Microsoft.Extensions.Logging.ILogger"/>).</param>
            <param name="loggerHelper">The logger helper for conditional logging (<see href="xref:Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper"/>).</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.InitAsync">
            <summary>
            Initializes the PostgreSQL connection, type handlers, and verifies PostGIS connectivity.
            </summary>
            <remarks>
            Registers composite types and type handlers for Dapper/Npgsql. See <see href="xref:articles/data-service-logic"/> and <see href="xref:Jupiter.Market.Elastic.Comparables.Models.DealUprnPair"/>, <see href="xref:Jupiter.Market.Elastic.Comparables.Models.DealTitlePair"/>.
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.GetConnectionAsync(System.Threading.CancellationToken)">
            <summary>
            Opens a new PostgreSQL connection.
            </summary>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>An open <see href="xref:Npgsql.NpgsqlConnection"/>.</returns>
            <seealso href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService.InitAsync"/>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.RunQueryAsync``1(System.String,System.Object,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Executes a SQL query and returns the results, with optional retry logic.
            </summary>
            <typeparam name="T">The result type.</typeparam>
            <param name="query">The SQL query string.</param>
            <param name="parameters">Query parameters.</param>
            <param name="useRetry">Whether to use retry logic.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>The query results as <see href="xref:System.Collections.Generic.IEnumerable{T}"/>.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.RunQueryByKeyAsync``1(System.String,System.Object,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Executes a named query from <see href="xref:Jupiter.Market.Elastic.Comparables.Constants.QueryConstants.Queries"/> and returns the results.
            </summary>
            <typeparam name="T">The result type.</typeparam>
            <param name="queryKey">The query key (see <see href="xref:Jupiter.Market.Elastic.Comparables.Constants.QueryConstants"/>).</param>
            <param name="parameters">Query parameters.</param>
            <param name="useRetry">Whether to use retry logic.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>The query results as <see href="xref:System.Collections.Generic.IEnumerable{T}"/>.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.GetDealReferenceByIdAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>
            Gets a deal reference by deal ID, mapping the result to a <see href="xref:Jupiter.Market.Elastic.Comparables.Models.DealReference"/>.
            </summary>
            <param name="dealId">The deal ID.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>The <see href="xref:Jupiter.Market.Elastic.Comparables.Models.DealReference"/> or null if not found.</returns>
            <seealso href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService.RunQueryByKeyAsync"/>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.NormalizePostgresArray(System.String[])">
            <summary>
            Normalizes a Postgres array string to a string array, splitting on commas if necessary.
            </summary>
            <param name="input">The input array, possibly in Postgres array string format.</param>
            <returns>A normalized string array.</returns>
            <seealso href="xref:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper.NormalizePostgresArray"/>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.GetGroupedByDealUprnIdAsync``1(System.String,System.Object,System.Boolean,System.Func{``0,System.Tuple{System.Guid,System.Guid}},System.Threading.CancellationToken)">
            <summary>
            Groups query results by (DealId, UprnId) using the provided selector.
            </summary>
            <typeparam name="T">The result type.</typeparam>
            <param name="key">The query key.</param>
            <param name="parameters">Query parameters.</param>
            <param name="spatial">Whether the query is spatial.</param>
            <param name="idSelector">Function to select the grouping key.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>A dictionary grouped by (DealId, UprnId).</returns>
            <seealso href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService.GetGroupedByDealTitleIdAsync"/>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.GetGroupedByDealTitleIdAsync``1(System.String,System.Object,System.Boolean,System.Func{``0,System.Tuple{System.Guid,System.Guid}},System.Threading.CancellationToken)">
            <summary>
            Groups query results by (DealId, TitleId) using the provided selector.
            </summary>
            <typeparam name="T">The result type.</typeparam>
            <param name="key">The query key.</param>
            <param name="parameters">Query parameters.</param>
            <param name="spatial">Whether the query is spatial.</param>
            <param name="idSelector">Function to select the grouping key.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>A dictionary grouped by (DealId, TitleId).</returns>
            <seealso href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService.GetGroupedByDealUprnIdAsync"/>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.GetListingComparablesForDealUprnSingleAsync(System.Guid,System.Guid,System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{Jupiter.Market.Elastic.Comparables.Models.HousePriceIndex}},System.Collections.Generic.Dictionary{System.String,Jupiter.Market.Elastic.Comparables.Models.Postcode},System.Threading.CancellationToken)">
            <summary>
            Gets listing comparables for a deal and UPRN, including enrichment data.
            </summary>
            <remarks>
            See <see href="xref:articles/comparable-mapping-logic"/> and <see href="xref:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper.MapComparable"/> for mapping logic.
            </remarks>
            <param name="dealId">The deal ID.</param>
            <param name="uprnId">The UPRN ID.</param>
            <param name="housePriceIndicesByRegion">House price indices by region.</param>
            <param name="postcodesByValue">Postcodes by value.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>A dictionary of comparables grouped by (DealId, UprnId).</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.GetSaleComparablesForDealUprnSingleAsync(System.Guid,System.Guid,System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{Jupiter.Market.Elastic.Comparables.Models.HousePriceIndex}},System.Collections.Generic.Dictionary{System.String,Jupiter.Market.Elastic.Comparables.Models.Postcode},System.Threading.CancellationToken)">
            <summary>
            Gets sale comparables for a deal and UPRN, including enrichment data.
            </summary>
            <remarks>
            See <see href="xref:articles/comparable-mapping-logic"/> and <see href="xref:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper.MapComparable"/> for mapping logic.
            </remarks>
            <param name="dealId">The deal ID.</param>
            <param name="uprnId">The UPRN ID.</param>
            <param name="housePriceIndicesByRegion">House price indices by region.</param>
            <param name="postcodesByValue">Postcodes by value.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>A dictionary of comparables grouped by (DealId, UprnId).</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.GetLeaseComparablesForDealUprnSingleAsync(System.Guid,System.Guid,System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{Jupiter.Market.Elastic.Comparables.Models.HousePriceIndex}},System.Collections.Generic.Dictionary{System.String,Jupiter.Market.Elastic.Comparables.Models.Postcode},System.Threading.CancellationToken)">
            <summary>
            Gets lease comparables for a deal and UPRN, including enrichment data.
            </summary>
            <remarks>
            See <see href="xref:articles/comparable-mapping-logic"/> and <see href="xref:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper.MapComparable"/> for mapping logic.
            </remarks>
            <param name="dealId">The deal ID.</param>
            <param name="uprnId">The UPRN ID.</param>
            <param name="housePriceIndicesByRegion">House price indices by region.</param>
            <param name="postcodesByValue">Postcodes by value.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>A dictionary of comparables grouped by (DealId, UprnId).</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.GetListingComparablesForDealTitleSingleAsync(System.Guid,System.Guid,System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{Jupiter.Market.Elastic.Comparables.Models.HousePriceIndex}},System.Collections.Generic.Dictionary{System.String,Jupiter.Market.Elastic.Comparables.Models.Postcode},System.Threading.CancellationToken)">
            <summary>
            Gets listing comparables for a deal and Title, including enrichment data.
            </summary>
            <remarks>
            See <see href="xref:articles/comparable-mapping-logic"/> and <see href="xref:Jupiter.Market.Elastic.Comparables.Mappers.ComparableMapper.MapComparable"/> for mapping logic.
            </remarks>
            <param name="dealId">The deal ID.</param>
            <param name="titleId">The Title ID.</param>
            <param name="housePriceIndicesByRegion">House price indices by region.</param>
            <param name="postcodesByValue">Postcodes by value.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>A dictionary of comparables grouped by (DealId, TitleId).</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.GetAllHousePriceIndicesAsync(System.Threading.CancellationToken)">
            <summary>
            Gets all house price indices from the database.
            </summary>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>A list of <see href="xref:Jupiter.Market.Elastic.Comparables.Models.HousePriceIndex"/> objects.</returns>
            <seealso href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService.GetAllPostcodesAsync"/>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.DataService.CalculateIndexedPrice(Jupiter.Market.Elastic.Comparables.Models.Comparable,System.Collections.Generic.Dictionary{System.Guid,System.Collections.Generic.List{Jupiter.Market.Elastic.Comparables.Models.HousePriceIndex}},System.Collections.Generic.Dictionary{System.String,Jupiter.Market.Elastic.Comparables.Models.Postcode})">
            <summary>
            Calculates the indexed price for a <see href="xref:Jupiter.Market.Elastic.Comparables.Models.Comparable"/> using house price indices and postcode data.
            </summary>
            <param name="comparable">The comparable to update.</param>
            <param name="housePriceIndicesByRegion">House price indices by region.</param>
            <param name="postcodesByValue">Postcodes by value.</param>
            <seealso href="xref:articles/comparable-mapping-logic"/>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService">
            <summary>
            Handles indexing, cleanup, and synchronization of deal data with the <see cref="!:Elastic.ComparablesIndex"/> in Elasticsearch.
            </summary>
            <remarks>
            <para>
            This service manages the lifecycle of the [Comparables Index](../api/Elastic-ComparablesIndex.md), reading from
            [Table.Deal](../api/Table-Deal.md), [Table.Listing](../api/Table-Listing.md), [Table.Sale](../api/Table-Sale.md),
            and [Table.Lease](../api/Table-Lease.md) to populate and maintain the index.
            </para>
            <para>
            See the detailed conceptual article: [ElasticIndexService Logic](../articles/technical/elastic-index-service-logic.md).
            </para>
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService.#ctor(Microsoft.Extensions.Options.IOptions{ElasticsearchSettings},Microsoft.Extensions.Options.IOptions{IndexerSettings},Jupiter.Market.Elastic.Comparables.Services.DataService,Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService,Microsoft.Extensions.Logging.ILogger{Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService},Microsoft.Extensions.Options.IOptions{Jupiter.Market.Elastic.Comparables.Models.ServiceBusSettings})">
            <summary>
            Initializes a new instance of the <see cref="T:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService"/> class.
            </summary>
            <param name="esOptions">Elasticsearch settings.</param>
            <param name="indexerOptions">Indexer settings.</param>
            <param name="dataService">The data service for deal retrieval.</param>
            <param name="serviceBusMessageService">The service bus message service for deal messaging.</param>
            <param name="logger">The logger instance.</param>
            <param name="serviceBusSettingsOptions">Service Bus settings.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService.InitAsync">
            <summary>
            Initializes the Elasticsearch client and connection pool for the [Comparables Index](xref:Elastic.ComparablesIndex).
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService.GetClientAsync">
            <summary>
            Gets the Elasticsearch client instance for the [Comparables Index](xref:Elastic.ComparablesIndex).
            </summary>
            <returns>The <see cref="T:Nest.ElasticClient"/> instance.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService.GetMissingEntries(System.Boolean)">
            <summary>
            Finds missing entries in the [Comparables Index](xref:Elastic.ComparablesIndex) compared to [Table.Deal](xref:Table.Deal), and optionally sends them to Service Bus.
            </summary>
            <param name="sendToServiceBus">Whether to send missing entries to Service Bus.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService.CleanElasticIndexAsync(System.Nullable{Jupiter.Market.Elastic.Comparables.Models.ComparableType})">
            <summary>
            Cleans the [Comparables Index](xref:Elastic.ComparablesIndex) by removing stale documents not present in [Table.Deal](xref:Table.Deal).
            </summary>
            <param name="comparableType">Optional comparable type filter.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService.DeleteIndex">
            <summary>
            Deletes the entire [Comparables Index](xref:Elastic.ComparablesIndex).
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService.CreateIndex">
            <summary>
            Creates the [Comparables Index](xref:Elastic.ComparablesIndex) with the required mapping.
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService.UpsertIndex(System.Collections.Generic.List{Jupiter.Market.Elastic.Comparables.Models.Deal})">
            <summary>
            Performs a bulk upsert of deals into the [Comparables Index](xref:Elastic.ComparablesIndex) using hash-based change detection.
            </summary>
            <remarks>
            <para>
            This method computes a deterministic SHA-256 hash (DocHash) for each <see cref="T:Jupiter.Market.Elastic.Comparables.Models.Deal"/> using a canonical JSON representation (camelCase, stable enum serialization, ignoring nulls and property order).
            It then fetches all existing documents' hashes from Elasticsearch in a single ids query, compares the hashes, and only bulk indexes documents whose hash is missing or different.
            This avoids unnecessary re-indexing and eliminates per-document GETs and deep JSON comparisons, optimizing for production-scale indexing.
            </para>
            <para>
            Steps:
            <list type="number">
            <item>Compute DocHash for each input <see cref="T:Jupiter.Market.Elastic.Comparables.Models.Deal"/>.</item>
            <item>Fetch existing DocHash values for all IDs in a single Elasticsearch query.</item>
            <item>Compare hashes and filter to only changed or new documents.</item>
            <item>Bulk index only the changed/new documents.</item>
            </list>
            </para>
            </remarks>
            <param name="comps">The list of deals to upsert. Each deal will have its <c>DocHash</c> property set before indexing.</param>
            <returns>The bulk response from Elasticsearch, or <c>null</c> if no documents required re-indexing.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService.DeleteFromIndex(System.Guid)">
            <summary>
            Deletes a single deal from the [Comparables Index](xref:Elastic.ComparablesIndex) by deal ID.
            </summary>
            <param name="dealId">The deal ID to delete.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService.QueryAndSendToServiceBusAsync(System.Threading.CancellationToken)">
            <summary>
            Queries Elasticsearch using the query from configuration and sends matching document IDs to Service Bus.
            </summary>
            <param name="cancellationToken">Cancellation token for the operation.</param>
            <returns>A task representing the asynchronous operation.</returns>
            <remarks>
            <para>This method:</para>
            <list type="number">
            <item>Parses the QueryJson from ElasticsearchSettings configuration</item>
            <item>Executes a scroll query against the Elasticsearch index</item>
            <item>Streams document IDs in batches to Service Bus via ServiceBusMessageService</item>
            <item>Logs progress periodically</item>
            </list>
            <para>The query can potentially match millions of documents and uses Elasticsearch scroll API
            for efficient streaming without loading all results into memory.</para>
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Services.IndexerService">
            <summary>
            Orchestrates the end-to-end indexing pipeline for the [Comparables Index](xref:Elastic.ComparablesIndex).
            </summary>
            <remarks>
            <para>
            This service coordinates Service Bus consumption, deal enrichment from [Table.Deal](../api/Table-Deal.md) and related tables,
            and synchronization with the [Comparables Index](../api/Elastic-ComparablesIndex.md).
            </para>
            <para>
            See the detailed conceptual article: [IndexerService Logic](../articles/technical/indexer-service-logic.md).
            </para>
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.#ctor(Microsoft.Extensions.Options.IOptions{ElasticsearchSettings},Microsoft.Extensions.Options.IOptions{IndexerSettings},Jupiter.Market.Elastic.Comparables.Services.DataService,Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService,Microsoft.Extensions.Logging.ILogger{Jupiter.Market.Elastic.Comparables.Services.IndexerService},Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper,Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper,Azure.Messaging.ServiceBus.ServiceBusClient,Microsoft.Extensions.Options.IOptions{Jupiter.Market.Elastic.Comparables.Models.ServiceBusSettings},Azure.Messaging.ServiceBus.Administration.ServiceBusAdministrationClient,Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService)">
            <summary>
            Initializes a new instance of the <see cref="T:Jupiter.Market.Elastic.Comparables.Services.IndexerService"/> class.
            </summary>
            <param name="esOptions">Elasticsearch settings.</param>
            <param name="indexerOptions">Indexer settings.</param>
            <param name="dataService">The data service for deal retrieval.</param>
            <param name="elasticIndexService">The ElasticSearch index service.</param>
            <param name="logger">The logger instance.</param>
            <param name="loggerHelper">The logger helper for conditional logging.</param>
            <param name="dealDataMapper">The deal data mapper for enrichment.</param>
            <param name="serviceBusClient">The Azure Service Bus client.</param>
            <param name="serviceBusOptions">Service Bus settings.</param>
            <param name="serviceBusAdministrationClient">The Service Bus administration client.</param>
            <param name="serviceBusMessageService">The Service Bus message service.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.RunAsync(System.Boolean,System.Int32,System.Threading.CancellationToken)">
            <summary>
            Runs the main indexing pipeline, optionally reprocessing dead-letter messages.
            </summary>
            <param name="reprocessDeadLetterQueue">Whether to reprocess dead-letter queue messages.</param>
            <param name="maxDeadLetterMessagesToProcess">Maximum number of dead-letter messages to process.</param>
            <param name="cancellationToken">Cancellation token.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.ResendOldestUpdated">
            <summary>
            Re-queues the oldest updated deals in ElasticSearch for reprocessing.
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.RunManualAsync(System.Threading.CancellationToken)">
            <summary>
            Runs the manual reindexing pipeline for deals listed in the manual file.
            </summary>
            <param name="cancellationToken">Cancellation token.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.ErrorHandler(Azure.Messaging.ServiceBus.ProcessErrorEventArgs)">
            <summary>
            Handles errors encountered during Service Bus message processing.
            </summary>
            <param name="args">The error event arguments.</param>
            <returns>A completed task.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.LogServiceBusProgress">
            <summary>
            Logs progress and statistics for Service Bus message processing.
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.ReprocessDeadLetterMessagesAsync(System.Int32,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Reprocesses messages in the dead-letter queue, either for the standard or high-priority subscription.
            </summary>
            <param name="maxMessagesToProcess">The maximum number of messages to process.</param>
            <param name="usePriority">Whether to use the high-priority subscription.</param>
            <param name="cancellationToken">Cancellation token.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.IndexDealByIdAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>
            Indexes a deal by its ID into the [Comparables Index](xref:Elastic.ComparablesIndex), fetching and combining all relevant comparables.
            </summary>
            <param name="dealId">The deal ID to index.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>A tuple indicating success and an error message if applicable.</returns>
            <remarks>
            <para>
            Retrieves data from [Table.Deal](xref:Table.Deal), [Table.Listing](xref:Table.Listing),
            [Table.Sale](xref:Table.Sale), and [Table.Lease](xref:Table.Lease) to construct the enriched <see cref="T:Jupiter.Market.Elastic.Comparables.Models.Deal"/> object.
            </para>
            <para><b>Title/UPRN Split Logic:</b></para>
            <list type="number">
              <item>
                <description>
                  If the deal has a <c>TitleId</c> (and not <c>UprnId</c>), all comparables are fetched using the Title-based queries and grouped by <c>(DealId, TitleId)</c>.
                </description>
              </item>
              <item>
                <description>
                  If the deal has a <c>UprnId</c> (and not <c>TitleId</c>), all comparables are fetched using the UPRN-based queries and grouped by <c>(DealId, UprnId)</c>.
                </description>
              </item>
              <item>
                <description>
                  If neither is present, the deal is skipped and a warning is logged.
                </description>
              </item>
            </list>
            <para><b>Deal Construction:</b></para>
            <list type="number">
              <item>
                <description>
                  All comparables for the deal are combined into a <c>ConcurrentBag&lt;Comparable&gt;</c>.
                </description>
              </item>
              <item>
                <description>
                  The <see cref="T:Jupiter.Market.Elastic.Comparables.Models.Deal"/> object is constructed with IDs, property type, comparable type/status, all comparables, and enriched <see cref="T:Jupiter.Market.Elastic.Comparables.Models.DealData"/> using <see cref="M:Jupiter.Market.Elastic.Comparables.Mappers.DealDataMapper.MapFromComparables(Jupiter.Market.Elastic.Comparables.Models.DealReference,System.Collections.Generic.List{Jupiter.Market.Elastic.Comparables.Models.Comparable})"/>
                </description>
              </item>
              <item>
                <description>
                  <c>DealType</c> and <c>OwnershipType</c> are determined from the comparables and deal reference.
                </description>
              </item>
              <item>
                <description>
                  The constructed deal is upserted into the [Comparables Index](xref:Elastic.ComparablesIndex).
                </description>
              </item>
            </list>
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.GetDealTypeForDeal(System.Collections.Concurrent.ConcurrentBag{Jupiter.Market.Elastic.Comparables.Models.Comparable})">
            <summary>
            Determines the <see cref="T:Jupiter.Market.Elastic.Comparables.Models.DealType"/> for a deal based on its comparables.
            </summary>
            <param name="combinedComps">The combined comparables.</param>
            <returns>The determined <see cref="T:Jupiter.Market.Elastic.Comparables.Models.DealType"/>.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.GetOwnershipTypeForDeal(System.Collections.Concurrent.ConcurrentBag{Jupiter.Market.Elastic.Comparables.Models.Comparable},Jupiter.Market.Elastic.Comparables.Models.DealReference)">
            <summary>
            Determines the <see cref="T:Jupiter.Market.Elastic.Comparables.Models.OwnershipType"/> for a deal based on its comparables and reference.
            </summary>
            <param name="combinedComps">The combined comparables.</param>
            <param name="dealReference">The deal reference.</param>
            <returns>The determined <see cref="T:Jupiter.Market.Elastic.Comparables.Models.OwnershipType"/>.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.GetComparableStatusForDeal(System.Collections.Concurrent.ConcurrentBag{Jupiter.Market.Elastic.Comparables.Models.Comparable})">
            <summary>
            Determines the <see cref="T:Jupiter.Market.Elastic.Comparables.Models.ComparableStatus"/> for a deal based on its comparables.
            </summary>
            <param name="combinedComps">The combined comparables.</param>
            <returns>The determined <see cref="T:Jupiter.Market.Elastic.Comparables.Models.ComparableStatus"/>.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.IndexerService.LoadHousePriceIndexDataAsync(System.Threading.CancellationToken)">
            <summary>
            Loads and caches house price index and postcode data for enrichment.
            </summary>
            <param name="cancellationToken">Cancellation token.</param>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService">
            <summary>
            Handles Azure Service Bus message publishing for deal data, including batching, offset tracking, and progress logging.
            </summary>
            <remarks>
            See the detailed conceptual article: [ServiceBusMessageService Logic](../articles/service-bus-message-service-logic.md).
            <para>
            This service manages the lifecycle of deal messages sent to Azure Service Bus, including initialization, batching, retry logic, offset persistence, and statistics logging.
            </para>
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService.#ctor(Microsoft.Extensions.Options.IOptions{IndexerSettings},Microsoft.Extensions.Options.IOptions{Jupiter.Market.Elastic.Comparables.Models.ServiceBusSettings},Microsoft.Extensions.Options.IOptions{QueriesSettings},Jupiter.Market.Elastic.Comparables.Services.DataService,Microsoft.Extensions.Logging.ILogger{Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService},Jupiter.Market.Elastic.Comparables.Helpers.LoggerHelper)">
            <summary>
            Initializes a new instance of the <see cref="T:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService"/> class.
            </summary>
            <param name="indexerOptions">Indexer settings.</param>
            <param name="serviceBusOptions">Service Bus settings.</param>
            <param name="queriesOptions">Queries settings for configurable SQL queries.</param>
            <param name="dataService">The data service for deal retrieval.</param>
            <param name="logger">The logger instance.</param>
            <param name="loggerHelper">The logger helper for conditional logging.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService.InitAsync">
            <summary>
            Initializes the Service Bus sender and data service.
            </summary>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService.GetDealsForServiceBusAsync(System.Boolean,System.Int32,System.Threading.CancellationToken)">
            <summary>
            Asynchronously yields batches of deals to be sent to Service Bus, handling offset tracking and statistics.
            </summary>
            <param name="usePriority">Whether to use priority query for deal selection.</param>
            <param name="batchSize">The batch size for deal retrieval.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>An async enumerable of deal batches.</returns>
            <remarks>
            See the detailed conceptual article: <a href="~/articles/service-bus-message-service-logic.md">ServiceBusMessageService Logic</a>.
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService.SendMessagesAsync(System.Collections.Generic.IEnumerable{Jupiter.Market.Elastic.Comparables.Models.DealIdOnly},System.Threading.CancellationToken)">
            <summary>
            Sends a batch of deal messages to Azure Service Bus, with retry and batching logic.
            </summary>
            <param name="deals">The deals to send.</param>
            <param name="cancellationToken">Cancellation token.</param>
            <returns>A task representing the asynchronous operation.</returns>
            <remarks>
            See the detailed conceptual article: <a href="~/articles/service-bus-message-service-logic.md">ServiceBusMessageService Logic</a>.
            </remarks>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService.LoadOffset(System.String)">
            <summary>
            Loads the persisted Service Bus offset from disk.
            </summary>
            <param name="path">The file path to load the offset from.</param>
            <returns>The loaded <see cref="T:Jupiter.Market.Elastic.Comparables.Models.ServiceBusOffset"/>.</returns>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService.SaveOffset(System.String,Jupiter.Market.Elastic.Comparables.Models.ServiceBusOffset)">
            <summary>
            Saves the Service Bus offset to disk atomically.
            </summary>
            <param name="path">The file path to save the offset to.</param>
            <param name="offset">The offset to save.</param>
        </member>
        <member name="M:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService.LogServiceBusMessageServiceProgress">
            <summary>
            Logs progress and statistics for Service Bus message processing.
            </summary>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.TypeHandlers.ComparableTypeTypeHandler">
            <summary>
            Dapper type handler for mapping <see href="xref:Jupiter.Market.Elastic.Comparables.Models.ComparableType"/> values to and from the database.
            </summary>
            <remarks>
            Used by <see href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService"/> for PostgreSQL composite type handling.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.TypeHandlers.DealTitlePairListTypeHandler">
            <summary>
            Dapper type handler for mapping lists of <see href="xref:Jupiter.Market.Elastic.Comparables.Models.DealTitlePair"/> to PostgreSQL composite arrays.
            </summary>
            <remarks>
            Used by <see href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService"/> for batch query operations.
            </remarks>
        </member>
        <member name="T:Jupiter.Market.Elastic.Comparables.TypeHandlers.DealUprnPairListTypeHandler">
            <summary>
            Dapper type handler for mapping lists of <see href="xref:Jupiter.Market.Elastic.Comparables.Models.DealUprnPair"/> to PostgreSQL composite arrays.
            </summary>
            <remarks>
            Used by <see href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService"/> for batch query operations.
            </remarks>
        </member>
        <member name="T:ElasticsearchSettings">
            <summary>
            Represents configuration settings for Elasticsearch integration.
            </summary>
            <remarks>
            Used by <see href="xref:Jupiter.Market.Elastic.Comparables.Services.ElasticIndexService"/> and <see href="xref:Jupiter.Market.Elastic.Comparables.Services.IndexerService"/>.
            </remarks>
        </member>
        <member name="P:ElasticsearchSettings.QueryJson">
            <summary>
            Gets or sets the Elasticsearch query JSON for the elastic-query command.
            </summary>
            <remarks>
            This should contain a valid Elasticsearch query DSL JSON that will be used
            to filter documents when using the 'elastic-query' command.
            </remarks>
        </member>
        <member name="T:PostgresSettings">
            <summary>
            Represents configuration settings for PostgreSQL integration.
            </summary>
            <remarks>
            Used by <see href="xref:Jupiter.Market.Elastic.Comparables.Services.DataService"/>.
            </remarks>
        </member>
        <member name="T:IndexerSettings">
            <summary>
            Represents configuration settings for the indexing pipeline.
            </summary>
            <remarks>
            Used by <see href="xref:Jupiter.Market.Elastic.Comparables.Services.IndexerService"/>.
            </remarks>
        </member>
        <member name="T:QueriesSettings">
            <summary>
            Represents configuration settings for database queries.
            </summary>
            <remarks>
            Allows override of specific queries from appsettings.json instead of hardcoded constants.
            Used by <see href="xref:Jupiter.Market.Elastic.Comparables.Services.ServiceBusMessageService"/>.
            </remarks>
        </member>
        <member name="P:QueriesSettings.DealsForServiceBusPriority">
            <summary>
            Gets or sets the query for retrieving deals for Service Bus priority processing.
            </summary>
            <remarks>
            If not specified, falls back to the query defined in QueryConstants.
            </remarks>
        </member>
    </members>
</doc>
