using System;
using System.Collections.Generic;
namespace FinlyticEngine.Services.Ai;
///
/// Outgoing request body for the n8n AI trade-validation webhook. Service-local (not FinlyticCore): this
/// shape is an integration detail of only, not a cross-service MQTT
/// contract (Rules.md §3 - core placement applies to data shared across services, not to a single service's
/// own outbound HTTP integration). Serialized with JsonNamingPolicy.CamelCase, so every property here
/// reaches n8n as camelCase without needing per-property [JsonPropertyName] attributes.
///
public record N8nValidationRequestPayload(
string Instructions,
N8nAssetSection Asset,
N8nTechnicalSetupSection TechnicalSetup,
N8nWatchlistContextSection? WatchlistContext,
N8nSentimentSection Sentiment,
N8nFundamentalsSection Fundamentals,
N8nReliabilitySection? Reliability,
N8nScoreBreakdownSection ScoreBreakdown
);
public record N8nAssetSection(string Isin, string Symbol, decimal CurrentPrice);
public record N8nPatternSection(string Type, string Bias, decimal QualityScore, string Description);
public record N8nTechnicalSetupSection(
string Strategy,
string StrategyName,
string Direction,
decimal Entry,
decimal StopLoss,
decimal TakeProfit1,
decimal RiskRewardRatio,
decimal QualityScore,
string Rationale,
string? MarketRegime,
List TriggeringPatterns,
Dictionary IndicatorSnapshot
);
/// Why FinlyticTechnicals was even scanning this ISIN (see TechnicalUniverseManager).
public record N8nWatchlistContextSection(string Source, DateTime EnteredAtUtc);
public record N8nSentimentSection(string Label, double WeightedScore, string Trend, string LatestHighlight);
///
/// Fundamental data + the two temporal suppression gates (/
/// ). Ratio fields (ReturnOnEquityRatio etc.) are
/// forwarded as raw fractions (e.g. 0.15 = 15%) exactly as stored, rather than guessing a ×100
/// conversion that could silently misrepresent the source data (Rules.md §4).
/// is the one exception: an honest, explicitly computed ratio (OperatingIncome / TotalRevenue × 100), only
/// populated when both inputs are real numbers.
///
public record N8nFundamentalsSection(
decimal? ForwardPe,
decimal? OperatingMarginPercent,
decimal? RevenueGrowthYoYRatio,
decimal? ReturnOnEquityRatio,
decimal? DebtToEquity,
decimal? FreeCashFlow,
string? ConsensusRating,
decimal? PriceTargetMean,
decimal? ShortPercentOfFloatRatio,
int? DaysToEarnings,
bool PassedEarningsLockout,
int? DaysToNextExDividend,
bool PassedDividendGate
);
/// FinlyticSimulation's backtest verdict for this exact (Isin, StrategyKey) - see .
public record N8nReliabilitySection(
decimal ReliabilityScore,
decimal WinRatePercent,
decimal ProfitFactor,
int SampleTradeCount,
bool IsStrategyApprovedForAsset,
string RecommendedAction
);
public record N8nScoreBreakdownSection(
decimal CompositeScore,
decimal TechnicalScore,
decimal SentimentScore,
decimal FundamentalScore,
decimal ReliabilityBonus
);
///
/// Expected shape of a successful n8n webhook response - deliberately identical field-for-field to
/// (camelCase JSON) instead of the previous,
/// undocumented ad hoc vocabulary (status/action_recommendation/raw_validation_result.*)
/// that no prompt ever actually specified. is nullable because a validator that
/// declines to give a numeric confidence must not have one fabricated for it (Rules.md §4).
///
public record N8nValidationResponsePayload(
bool? IsApproved,
decimal? Confidence,
string? ThesisSummary,
string? InvalidationReason,
List? KeyCatalysts,
List? IdentifiedRisks
);