import { type SupportedDateLiteral } from '../models/date-literal.js'; import type { DateLiteralRange } from '../models/date-literal.js'; import type { YearRange } from '../models/year-range.js'; import type { CascadeSkipAccumulator } from '../models/cascade-skip-accumulator.js'; import type { SObjectInfo } from '../services/ObjectFilteringService.js'; import type { CreateDefinitionInput } from '../services/ProfilingDefinitionService.js'; /** * Maps a Salesforce object to its outcome boolean field with human-readable labels. */ export type OutcomeFieldMapping = { /** The boolean field API name (e.g., 'IsWon') */ fieldName: string; /** Label for the true outcome (e.g., 'Won') */ trueLabel: string; /** Label for the false outcome (e.g., 'Lost') */ falseLabel: string; }; /** * A single expression line in the ISV expression builder JSON format. * This schema must match what `fsc_expressionBuilder3` LWC expects. */ export type ExpressionLine = { id?: number; objectType: string; parameter: string; parameterValue: string | null; dataType: string; label: string; type: string; fieldName: string; operator: string; operatorSymbol: string; value: string; dateLiteral: string; }; /** * The expression builder JSON structure stored in Prop_Filter_JSON_SetA__c / SetB__c. */ export type ExpressionBuilderJson = { expressions: ExpressionLine[]; logicType: 'AND' | 'OR' | 'CUSTOM'; customLogic?: string; }; /** * A single filter set within the filterJson API payload. * `json` must be an OBJECT (not a string) — the API does JSON.serialize() on it. */ export type FilterSet = { json: ExpressionBuilderJson; expression: string; }; /** * The filterJson API payload envelope. */ export type FilterJsonPayload = { hasFilters: boolean; setA: FilterSet; setB?: FilterSet; }; /** * An entry in the DATE_LITERAL_MAP: maps a key to its $Constant display value, * SOQL literal, and human-readable display name. */ export type DateLiteralEntry = { constant: string; soqlLiteral: string; displayName: string; }; /** * Resolved definition metadata — category, time, segment, and description. * Produced by resolveDefinitionMetadata(), the single source of truth for definition classification. */ export type DefinitionMetadata = { category: string; timeCategory: string; segmentCategory: string; description: string; }; /** * Context for resolveDefinitionMetadata() — provides the inputs needed to determine * the correct classification for any definition type. */ export type DefinitionMetadataContext = { timeLabel?: string; year?: number; unbounded?: boolean; /** * When true, signals the comparative variant is "lifetime vs X" — SetA is unfiltered (all records), SetB is the * supplied secondary filter. Drives name/timeCategory/segmentCategory/description derivations for the variant. */ lifetimePrimary?: boolean; recordTypeName?: string; outcomeLabels?: { trueLabel: string; falseLabel: string; }; categoryOverride?: string; timeCategoryOverride?: string; segmentCategoryOverride?: string; descriptionOverride?: string; noValueFrequency?: boolean; namePrefix?: string; nameSuffix?: string; origin?: string; }; /** * Subset of CreateOptions needed by field generation methods. * Avoids importing the full CreateOptions type from the operation layer. */ export type FieldGenerationOptions = { method?: 'metadata' | 'historical' | 'comparative' | 'recordtype' | 'outcome' | 'full'; year?: number; usePrior?: boolean; /** * When true with method='comparative', selects the lifetime-vs-X variant (SetA unfiltered, SetB filtered by the * supplied secondary filter). Read by buildCandidateInputs to branch filter JSON construction and metadata derivation. */ lifetimePrimary?: boolean; category?: string; timeCategory?: string; segmentCategory?: string; description?: string; noValueFrequency?: boolean; namePrefix?: string; nameSuffix?: string; origin?: string; recordType?: string; dateLiteralRange?: DateLiteralRange; }; /** * Pure field generation service for profiling definitions. * * Encapsulates stateless naming, categorisation, description, and candidate-input * building logic extracted from DefinitionCreateOperation. Every method is * `public static` — no constructor dependencies, no adapters, no connection. * * The DefinitionCreateOperation delegates to this service for: * - Definition name resolution (buildName, resolveDefinitionName) * - Category / time-category / segment-category resolution * - Description template generation * - Candidate input construction for metadata, historical, comparative, record-type, and outcome methods * - Outcome field lookup and filter JSON construction */ export declare class DefinitionFieldGenerationService { /** Exposes the date literal constant map for external consumers and tests. */ static readonly DATE_LITERAL_MAP: Record; /** The bullet separator used in definition names. */ static readonly NAME_SEPARATOR = " \u2022 "; /** * Resolves the definition name from the method and context. * Single source of truth for definition naming across all definition types. * * @param label - Object label (e.g., 'Account', 'Lead') * @param method - ISV method (metadata, historical, comparative) * @param context - Optional context: timeLabel, year, recordTypeName, outcomeLabels, unbounded * @returns The formatted definition name */ static resolveDefinitionName(label: string, method: 'metadata' | 'historical' | 'comparative', context?: DefinitionMetadataContext): string; /** * Resolves all definition metadata (category, timeCategory, segmentCategory, description) * from the method and context. Single source of truth for definition classification. * * @param label - Object label (e.g., 'Account', 'Lead') * @param method - ISV method (metadata, historical, comparative) * @param context - Optional context: timeLabel, year, recordTypeName, outcomeLabels, overrides * @returns Resolved metadata for the definition */ static resolveDefinitionMetadata(label: string, method: 'metadata' | 'historical' | 'comparative', context?: DefinitionMetadataContext): DefinitionMetadata; /** * Maps Salesforce objects to their outcome boolean fields. * * @param objectName - Salesforce object API name (e.g., 'Opportunity', 'Case', 'Lead') * @returns Outcome field mapping, or undefined if the object has no outcome field */ static getOutcomeField(objectName: string): OutcomeFieldMapping | undefined; /** * Builds a single outcome definition input for a given object, outcome mapping, and optional time/RT context. * Consolidates the repeated context + input construction pattern used across buildOutcomeCandidateInputs * and buildInputsForRecordType. * * @param obj - Resolved SObject metadata * @param outcome - Outcome field mapping for the object * @param options - Field generation options * @param timeLabel - Optional time label (e.g., 'This Year') * @param recordTypeName - Optional record type developer name * @param dateLiteral - Optional date literal key * @param dateField - Optional date field API name * @returns A single CreateDefinitionInput for the outcome comparison */ static buildOutcomeInput(obj: SObjectInfo, outcome: OutcomeFieldMapping, options: FieldGenerationOptions, timeLabel?: string, recordTypeName?: string, dateLiteral?: string, dateField?: string): CreateDefinitionInput; /** * Builds an ISV-compatible filterJson string for business process outcome comparisons. * SetA filters for the true outcome, SetB filters for the false outcome. * Produces the expression builder JSON schema that `fsc_expressionBuilder3` expects. * * @param fieldName - Boolean field API name (e.g., 'IsWon', 'IsClosed', 'IsConverted') * @param objectName - Salesforce object API name (e.g., 'Opportunity', 'Case', 'Lead') * @param dateLiteral - Optional date literal key for time-scoped outcome filters * @param dateField - Optional date field API name * @param objectLabel - Optional object label for display in date expressions * @returns JSON string compatible with GlobalProfilingService.createProfilingDefinition() */ static buildOutcomeFilterJson(fieldName: string, objectName: string, dateLiteral?: string, dateField?: string, objectLabel?: string, yearBoundary?: { year: number; unbounded: boolean; }): string; /** * Builds the base definition name from an object label, method, and context. * * @param label - Object label (e.g., 'Account', 'Lead') * @param method - ISV method string * @param ctx - Definition metadata context * @returns Formatted base definition name (without prefix/suffix) */ static buildName(label: string, method: string, ctx: DefinitionMetadataContext): string; /** * Resolves the time-segment label for the lifetime-vs-X comparative variant. Prefers an explicit * timeLabel (set by the operation layer for date literals or year-range spans), then falls back * to the year for single-year cascade entries. Used by buildName, resolveTimeCategoryFromContext, * and resolveDescription so the lifetime variant renders consistently. */ static resolveLifetimeTimeLabel(ctx: DefinitionMetadataContext): string; /** * Resolves the primary category from method and context. * * @param method - ISV method string * @param ctx - Definition metadata context * @returns Category string (e.g., 'Metadata', 'Baseline', 'Comparative', 'Record Types') */ static resolveCategory(method: string, ctx: DefinitionMetadataContext): string; /** * Resolves the time category from method and context. * * @param method - ISV method string * @param ctx - Definition metadata context * @returns Time category string (e.g., 'N/A', 'Lifetime', '2025 vs 2024') */ static resolveTimeCategoryFromContext(method: string, ctx: DefinitionMetadataContext): string; /** * Resolves the segment category from method and context. * * @param method - ISV method string * @param ctx - Definition metadata context * @returns Segment category string (e.g., 'N/A', 'Historical', 'Comparative', record type name) */ static resolveSegmentCategory(method: string, ctx: DefinitionMetadataContext): string; /** * Generates a human-readable description from label, method, and context. * * @param label - Object label (e.g., 'Account', 'Lead') * @param method - ISV method string * @param ctx - Definition metadata context * @returns Generated description string */ static resolveDescription(label: string, method: string, ctx: DefinitionMetadataContext): string; /** * Selects the comparative filter JSON for a date-literal entry. * lifetimePrimary → SetA empty (all records), SetB = supplied literal. * regular comparative → SetA = literal, SetB = prior from LITERAL_CASCADES[literal][1]; falls back to SetA-only when no prior exists. * historical/metadata → SetA only. */ static pickDateLiteralComparativeFilter(literal: SupportedDateLiteral, isLifetimeComparative: boolean, dateField: string, objectName: string, objectLabel: string, isRegularComparative?: boolean): string; /** * Selects the comparative filter JSON for a year-range entry. Returns the lifetime-vs-X * variant when in lifetimePrimary mode; otherwise the existing year-vs-prior comparative * filter (CLI-2944). */ static pickYearComparativeFilter(entry: { year: number; unbounded?: boolean; }, lifetimePrimary: boolean, objectName: string, objectLabel: string): string; /** * Builds candidate CreateDefinitionInput entries for non-recordtype methods. * * For comparative method, creates one input per object per YearRange entry. * For metadata/historical, creates one input per object (yearRange is ignored). * * @param objects - Resolved SObject metadata entries * @param method - ISV method (metadata, historical, comparative) * @param year - Comparative year (default: current year) * @param yearRange - Resolved year range entries * @param options - Field generation options * @returns Array of candidate definition inputs */ static buildCandidateInputs(objects: SObjectInfo[], method: 'metadata' | 'historical' | 'comparative', year: number, yearRange: YearRange, options: FieldGenerationOptions): CreateDefinitionInput[]; /** * Builds candidate inputs for a single record type on a single object. * * Creates 1 historical + N comparative definitions (one per YearRange entry). * For outcome-capable objects in full method, also adds outcome split per RT. * * @param obj - Resolved SObject metadata * @param rtName - Record type developer name * @param yearRange - Resolved year range entries * @param options - Field generation options * @returns Array of candidate definition inputs for this record type */ static buildInputsForRecordType(obj: SObjectInfo, rtName: string, yearRange: YearRange, options: FieldGenerationOptions): CreateDefinitionInput[]; /** * Builds candidate inputs for business process outcome profiling. * Creates one definition per object that has a business process outcome boolean field. * * @param objects - Resolved SObject metadata entries * @param options - Field generation options * @param warnings - Mutable warnings array to append skip messages (standalone callers only) * @param yearRange - Optional year range for outcome scoping * @param cascade - Optional accumulator. Presence signals cascade-mode (`buildFullCandidateInputs`): * objects with no outcome field are silently skipped — no warning is emitted (CLI-3611). * Absence is the standalone caller (`--method outcome`) — per-object warning fires as before. * @returns Array of candidate definition inputs for outcome-capable objects */ static buildOutcomeCandidateInputs(objects: SObjectInfo[], options: FieldGenerationOptions, warnings: string[], yearRange?: YearRange, cascade?: CascadeSkipAccumulator): CreateDefinitionInput[]; /** * Builds one filter-free metadata-only input per object. Extracted from `buildCandidateInputs` * (CLI-3375) to enforce the contract that a metadata-only definition is filter-irrelevant by * design — independent of whether the caller passed a date-literal range. Used by the * metadata-variant short-circuit at the top of `buildCandidateInputs`. */ private static buildMetadataInputsForObjects; /** * Builds (object × dateLiteralEntry) inputs for historical and comparative methods. Extracted * from `buildCandidateInputs` (CLI-3375) to keep that method's cyclomatic complexity within * lint limits after introducing the metadata-variant short-circuit. The metadata variant does * NOT route through here — see `buildMetadataInputsForObjects` for that path. */ private static buildDateLiteralInputs; }