cyberhybridhub/server/lib/trading/backfill_sync_item.dart
2026-05-31 11:17:12 -05:00

60 lines
1.7 KiB
Dart

import 'market_history_four_hour_slot.dart';
/// One Alpaca backfill request bucket: a UTC 4-hour slot and its symbols.
class BackfillSyncItem {
const BackfillSyncItem({
required this.slotStart,
required this.symbols,
});
final DateTime slotStart;
final List<String> symbols;
Map<String, dynamic> toJson() => <String, dynamic>{
'slotStart': MarketHistoryFourHourSlot.slotStartWire(slotStart),
'symbols': symbols,
};
static BackfillSyncItem? tryFromJson(dynamic raw) {
if (raw is! Map<String, dynamic>) {
return null;
}
final String? slotStartRaw = raw['slotStart'] as String?;
if (slotStartRaw == null) {
return null;
}
final DateTime? slotStart = DateTime.tryParse(slotStartRaw)?.toUtc();
if (slotStart == null) {
return null;
}
final List<dynamic> symbolRaw =
raw['symbols'] as List<dynamic>? ?? <dynamic>[];
final List<String> symbols = symbolRaw
.map((dynamic value) => value.toString())
.where((String value) => value.isNotEmpty)
.toList(growable: false);
return BackfillSyncItem(slotStart: slotStart, symbols: symbols);
}
static List<BackfillSyncItem> listFromJson(dynamic raw) {
if (raw == null) {
return <BackfillSyncItem>[];
}
if (raw is! List<dynamic>) {
return <BackfillSyncItem>[];
}
final List<BackfillSyncItem> items = <BackfillSyncItem>[];
for (final dynamic entry in raw) {
final BackfillSyncItem? item = tryFromJson(entry);
if (item != null) {
items.add(item);
}
}
return items;
}
static List<Map<String, dynamic>> encodeList(List<BackfillSyncItem> items) {
return items.map((BackfillSyncItem item) => item.toJson()).toList();
}
}