using System.Collections.Generic;
using GB5Shared.DTO.Framework.Criteria;
namespace AnalyticsDAL.DTO.AnalysisAggregation.V1
{
/// The versioned shaped-data request contract every analytics consumer (pivot,
/// chart, export, snapshot) builds and re-submits to IAnalysisAggregationService.
/// See the plan's "How slice/dice/drill-down actually works" section — every interaction
/// (filter, re-pivot, drill) is a frontend concern that produces a new instance of this
/// class and calls RunBIQuery again; there is no server-side session/cursor state.
public class AnalysisQueryDefinition
{
public const string SchemaVersion = "1.1";
/// Resolves through MBICATALOG.BICATALOGID via IDatasetResolver.
public int DatasetId { get; set; }
public List Dimensions { get; set; } = new();
public List Measures { get; set; } = new();
public List Filters { get; set; } = new();
/// Result field names of MBIFIELDMAPPING.MAPPEDAS=2 (Computed) rows to evaluate
/// after the dataset resolver returns. Deliberately a THIRD list, not entries in
/// Dimensions/Measures: both of those are validated against the physical registry
/// (ValidateAdditivity + WarehouseDAL.ResolveDimensionColumn/measuresByColumn) and would
/// reject a computed field's name outright. Every source field a computed expression
/// references must ALSO appear in Dimensions/Measures — see
/// AnalysisAggregationService.ApplyComputedFieldsAsync — a computed field can never
/// silently pull in an unselected/unaggregated measure. Additive and default-empty, so
/// every existing MBIVIEW.BIDEFINITIONJSON row deserializes unchanged.
public List ComputedFields { get; set; } = new();
/// Pivot placement — which Dimensions[].Field values are currently rows vs columns.
public List Rows { get; set; } = new();
public List Columns { get; set; } = new();
/// Ordered hierarchy levels drilled so far (e.g. ["Year","Quarter","Month"]).
public List DrillPath { get; set; } = new();
public List Sort { get; set; } = new();
public int? TopN { get; set; }
}
}