class RemoteCommand { final String id; final String type; final String tabId; final int expectedVersion; final String paymentMethod; final String requestedBy; final DateTime createdAt; const RemoteCommand({ required this.id, required this.type, required this.tabId, required this.expectedVersion, required this.paymentMethod, required this.requestedBy, required this.createdAt, }); factory RemoteCommand.fromJson(Map json) { return RemoteCommand( id: json['id'] as String, type: json['type'] as String, tabId: json['tabId'] as String, expectedVersion: json['expectedVersion'] as int, paymentMethod: json['paymentMethod'] as String? ?? 'cash', requestedBy: json['requestedBy'] as String? ?? '', createdAt: DateTime.parse(json['createdAt'] as String), ); } bool get isExpired { final cutoff = DateTime.now().subtract(const Duration(hours: 24)); return createdAt.isBefore(cutoff); } } class SyncResponse { final List commands; final String? cursor; final List plannedTabNames; SyncResponse({ required this.commands, this.cursor, this.plannedTabNames = const [], }); factory SyncResponse.fromJson(Map json) { final commandsList = (json['commands'] as List?) ?.map((e) => RemoteCommand.fromJson(e as Map)) .toList() ?? []; return SyncResponse( commands: commandsList, cursor: json['cursor'] as String?, plannedTabNames: (json['plannedTabNames'] as List?) ?.map((e) => e as String) .toList() ?? [], ); } } class SnapshotTab { final String id; final String customerName; final int version; final int totalInCents; final int itemCount; const SnapshotTab({ required this.id, required this.customerName, required this.version, required this.totalInCents, required this.itemCount, }); Map toJson() => { 'id': id, 'customerName': customerName, 'version': version, 'totalInCents': totalInCents, 'itemCount': itemCount, }; } class SyncRequest { final String deviceId; final String? cursor; final List openTabs; const SyncRequest({ required this.deviceId, this.cursor, required this.openTabs, }); Map toJson() => { 'deviceId': deviceId, if (cursor != null) 'cursor': cursor, 'openTabs': openTabs.map((t) => t.toJson()).toList(), }; } class CommandAck { final String commandId; final String status; final String? result; const CommandAck({ required this.commandId, required this.status, this.result, }); Map toJson() => { 'commandId': commandId, 'status': status, if (result != null) 'result': result, }; } enum RemoteSyncEventType { tabClosedRemotely, syncCompleted, syncFailed, conflict, } class RemoteSyncEvent { final RemoteSyncEventType type; final String? tabCustomerName; final String? requestedBy; final String? message; const RemoteSyncEvent({ required this.type, this.tabCustomerName, this.requestedBy, this.message, }); }