205 lines
6.2 KiB
Dart
205 lines
6.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import '../../../core/theme/app_theme.dart';
|
|
|
|
/// Mirrors `FinlyticCore.Dtos.Trading.OutcomeReason` (`TradeEnums.cs`), which the
|
|
/// `/api/v1/admin/evaluations` endpoint serializes as a `JsonStringEnumConverter`
|
|
/// string using the exact C# member name (e.g. `"Approved"`, `"BelowScoreThreshold"`).
|
|
///
|
|
/// [unknown] is the fallback both for the server's own `Unknown = 0` default (an
|
|
/// honest "we don't know" rather than a fabricated reason, Rules.md §4) and for any
|
|
/// future server-side member this client doesn't recognize yet.
|
|
enum OutcomeReason {
|
|
unknown,
|
|
approved,
|
|
belowScoreThreshold,
|
|
earningsLockout,
|
|
simulationVeto,
|
|
aiRejected,
|
|
noTechnicalSetups,
|
|
duplicateActiveProposal,
|
|
dividendGate;
|
|
|
|
static OutcomeReason fromJson(String? raw) {
|
|
switch (raw) {
|
|
case 'Approved':
|
|
return OutcomeReason.approved;
|
|
case 'BelowScoreThreshold':
|
|
return OutcomeReason.belowScoreThreshold;
|
|
case 'EarningsLockout':
|
|
return OutcomeReason.earningsLockout;
|
|
case 'SimulationVeto':
|
|
return OutcomeReason.simulationVeto;
|
|
case 'AiRejected':
|
|
return OutcomeReason.aiRejected;
|
|
case 'NoTechnicalSetups':
|
|
return OutcomeReason.noTechnicalSetups;
|
|
case 'DuplicateActiveProposal':
|
|
return OutcomeReason.duplicateActiveProposal;
|
|
case 'DividendGate':
|
|
return OutcomeReason.dividendGate;
|
|
case 'Unknown':
|
|
default:
|
|
return OutcomeReason.unknown;
|
|
}
|
|
}
|
|
|
|
/// Exact server-side enum member name. `[FromQuery] OutcomeReason?` on
|
|
/// `AdminEvaluationHistoryController` model-binds a bare enum member name from
|
|
/// the query string (ASP.NET Core's default `Enum.TryParse`-based binder), not a
|
|
/// JSON string — so this is what must be sent back as the `outcome` filter value.
|
|
String toApiValue() {
|
|
switch (this) {
|
|
case OutcomeReason.approved:
|
|
return 'Approved';
|
|
case OutcomeReason.belowScoreThreshold:
|
|
return 'BelowScoreThreshold';
|
|
case OutcomeReason.earningsLockout:
|
|
return 'EarningsLockout';
|
|
case OutcomeReason.simulationVeto:
|
|
return 'SimulationVeto';
|
|
case OutcomeReason.aiRejected:
|
|
return 'AiRejected';
|
|
case OutcomeReason.noTechnicalSetups:
|
|
return 'NoTechnicalSetups';
|
|
case OutcomeReason.duplicateActiveProposal:
|
|
return 'DuplicateActiveProposal';
|
|
case OutcomeReason.dividendGate:
|
|
return 'DividendGate';
|
|
case OutcomeReason.unknown:
|
|
return 'Unknown';
|
|
}
|
|
}
|
|
|
|
String get label {
|
|
switch (this) {
|
|
case OutcomeReason.approved:
|
|
return 'Freigegeben';
|
|
case OutcomeReason.belowScoreThreshold:
|
|
return 'Score zu niedrig';
|
|
case OutcomeReason.earningsLockout:
|
|
return 'Earnings-Sperre';
|
|
case OutcomeReason.simulationVeto:
|
|
return 'Simulation-Veto';
|
|
case OutcomeReason.aiRejected:
|
|
return 'KI abgelehnt';
|
|
case OutcomeReason.noTechnicalSetups:
|
|
return 'Kein Setup';
|
|
case OutcomeReason.duplicateActiveProposal:
|
|
return 'Bereits aktiver Vorschlag';
|
|
case OutcomeReason.dividendGate:
|
|
return 'Dividend-Sperre';
|
|
case OutcomeReason.unknown:
|
|
return 'Unbekannt';
|
|
}
|
|
}
|
|
|
|
/// Color-coding for the history-list badge, reusing only colors already
|
|
/// established elsewhere in the app (`AppTheme.primaryEmerald`/`accentRed` plus
|
|
/// the `Colors.amber`/`Colors.purpleAccent` already used by
|
|
/// `EvaluationScoreBreakdownSheet`) rather than introducing a new palette.
|
|
Color get color {
|
|
switch (this) {
|
|
case OutcomeReason.approved:
|
|
return AppTheme.primaryEmerald;
|
|
case OutcomeReason.aiRejected:
|
|
case OutcomeReason.simulationVeto:
|
|
return AppTheme.accentRed;
|
|
case OutcomeReason.belowScoreThreshold:
|
|
case OutcomeReason.earningsLockout:
|
|
case OutcomeReason.duplicateActiveProposal:
|
|
case OutcomeReason.dividendGate:
|
|
return Colors.amber;
|
|
case OutcomeReason.noTechnicalSetups:
|
|
case OutcomeReason.unknown:
|
|
return AppTheme.textMuted;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Mirrors `FinlyticCore.Dtos.Trading.TriggerSource`.
|
|
enum TriggerSource {
|
|
unknown,
|
|
automatic,
|
|
manual;
|
|
|
|
static TriggerSource fromJson(String? raw) {
|
|
switch (raw) {
|
|
case 'Automatic':
|
|
return TriggerSource.automatic;
|
|
case 'Manual':
|
|
return TriggerSource.manual;
|
|
case 'Unknown':
|
|
default:
|
|
return TriggerSource.unknown;
|
|
}
|
|
}
|
|
|
|
String toApiValue() {
|
|
switch (this) {
|
|
case TriggerSource.automatic:
|
|
return 'Automatic';
|
|
case TriggerSource.manual:
|
|
return 'Manual';
|
|
case TriggerSource.unknown:
|
|
return 'Unknown';
|
|
}
|
|
}
|
|
|
|
String get label {
|
|
switch (this) {
|
|
case TriggerSource.automatic:
|
|
return 'Automatisch';
|
|
case TriggerSource.manual:
|
|
return 'Manuell';
|
|
case TriggerSource.unknown:
|
|
return 'Unbekannt';
|
|
}
|
|
}
|
|
|
|
Color get color {
|
|
switch (this) {
|
|
case TriggerSource.automatic:
|
|
return AppTheme.accentCyan;
|
|
case TriggerSource.manual:
|
|
return Colors.purpleAccent;
|
|
case TriggerSource.unknown:
|
|
return AppTheme.textMuted;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Mirrors `FinlyticCore.Dtos.TechnicalAnalysis.UniverseSource` - which recurring
|
|
/// FinlyticTechnicals selection mechanism added the ISIN to the continuously
|
|
/// scanned universe before this evaluation ran. `null` on the Dart side (not
|
|
/// modeled as its own enum value here) means the evaluation happened outside
|
|
/// that universe entirely (e.g. a manual "Analyze now" call).
|
|
enum UniverseSource {
|
|
sentimentSpike,
|
|
userFavorite,
|
|
discovery;
|
|
|
|
static UniverseSource? fromJson(String? raw) {
|
|
switch (raw) {
|
|
case 'SentimentSpike':
|
|
return UniverseSource.sentimentSpike;
|
|
case 'UserFavorite':
|
|
return UniverseSource.userFavorite;
|
|
case 'Discovery':
|
|
return UniverseSource.discovery;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
String get label {
|
|
switch (this) {
|
|
case UniverseSource.sentimentSpike:
|
|
return 'Sentiment-Spike';
|
|
case UniverseSource.userFavorite:
|
|
return 'Nutzer-Favorit';
|
|
case UniverseSource.discovery:
|
|
return 'Discovery-Liste';
|
|
}
|
|
}
|
|
}
|