class Vehicle { final String id; final String make; final String model; final String color; final String licensePlate; final DateTime updatedAt; /// Soft-delete tombstone: null means active. Deleting sets this instead /// of removing the row, so the deletion itself can be merged/synced like /// any other change (newest `updatedAt` wins) instead of silently /// disappearing and later being resurrected by a device that hasn't seen /// the deletion yet. final DateTime? deletedAt; Vehicle({ required this.id, required this.make, required this.model, required this.color, required this.licensePlate, required this.updatedAt, this.deletedAt, }); String get displayName => '$color $make $model ($licensePlate)'; Vehicle copyWith({ String? make, String? model, String? color, String? licensePlate, DateTime? updatedAt, DateTime? deletedAt, }) { return Vehicle( id: id, make: make ?? this.make, model: model ?? this.model, color: color ?? this.color, licensePlate: licensePlate ?? this.licensePlate, updatedAt: updatedAt ?? this.updatedAt, deletedAt: deletedAt ?? this.deletedAt, ); } Map toMap() => { 'id': id, 'make': make, 'model': model, 'color': color, 'license_plate': licensePlate, 'updated_at': updatedAt.millisecondsSinceEpoch, 'deleted_at': deletedAt?.millisecondsSinceEpoch, }; factory Vehicle.fromMap(Map map) => Vehicle( id: map['id'] as String, make: map['make'] as String, model: map['model'] as String, color: map['color'] as String, licensePlate: map['license_plate'] as String, updatedAt: DateTime.fromMillisecondsSinceEpoch(map['updated_at'] as int, isUtc: true), deletedAt: map['deleted_at'] != null ? DateTime.fromMillisecondsSinceEpoch(map['deleted_at'] as int, isUtc: true) : null, ); }