Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts). Signed-off-by: lions dev Team
This commit is contained in:
63
lib/features/backup/data/models/backup_config_model.dart
Normal file
63
lib/features/backup/data/models/backup_config_model.dart
Normal file
@@ -0,0 +1,63 @@
|
||||
/// Modèle de configuration des sauvegardes
|
||||
/// Correspond à BackupConfigResponse du backend
|
||||
library backup_config_model;
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'backup_config_model.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class BackupConfigModel extends Equatable {
|
||||
final bool? autoBackupEnabled;
|
||||
final String? frequency; // HOURLY, DAILY, WEEKLY
|
||||
final String? retention;
|
||||
final int? retentionDays;
|
||||
final String? backupTime;
|
||||
final bool? includeDatabase;
|
||||
final bool? includeFiles;
|
||||
final bool? includeConfiguration;
|
||||
final DateTime? lastBackup;
|
||||
final DateTime? nextScheduledBackup;
|
||||
final int? totalBackups;
|
||||
final int? totalSizeBytes;
|
||||
final String? totalSizeFormatted;
|
||||
|
||||
const BackupConfigModel({
|
||||
this.autoBackupEnabled,
|
||||
this.frequency,
|
||||
this.retention,
|
||||
this.retentionDays,
|
||||
this.backupTime,
|
||||
this.includeDatabase,
|
||||
this.includeFiles,
|
||||
this.includeConfiguration,
|
||||
this.lastBackup,
|
||||
this.nextScheduledBackup,
|
||||
this.totalBackups,
|
||||
this.totalSizeBytes,
|
||||
this.totalSizeFormatted,
|
||||
});
|
||||
|
||||
factory BackupConfigModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$BackupConfigModelFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$BackupConfigModelToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
autoBackupEnabled,
|
||||
frequency,
|
||||
retention,
|
||||
retentionDays,
|
||||
backupTime,
|
||||
includeDatabase,
|
||||
includeFiles,
|
||||
includeConfiguration,
|
||||
lastBackup,
|
||||
nextScheduledBackup,
|
||||
totalBackups,
|
||||
totalSizeBytes,
|
||||
totalSizeFormatted,
|
||||
];
|
||||
}
|
||||
45
lib/features/backup/data/models/backup_config_model.g.dart
Normal file
45
lib/features/backup/data/models/backup_config_model.g.dart
Normal file
@@ -0,0 +1,45 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'backup_config_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
BackupConfigModel _$BackupConfigModelFromJson(Map<String, dynamic> json) =>
|
||||
BackupConfigModel(
|
||||
autoBackupEnabled: json['autoBackupEnabled'] as bool?,
|
||||
frequency: json['frequency'] as String?,
|
||||
retention: json['retention'] as String?,
|
||||
retentionDays: (json['retentionDays'] as num?)?.toInt(),
|
||||
backupTime: json['backupTime'] as String?,
|
||||
includeDatabase: json['includeDatabase'] as bool?,
|
||||
includeFiles: json['includeFiles'] as bool?,
|
||||
includeConfiguration: json['includeConfiguration'] as bool?,
|
||||
lastBackup: json['lastBackup'] == null
|
||||
? null
|
||||
: DateTime.parse(json['lastBackup'] as String),
|
||||
nextScheduledBackup: json['nextScheduledBackup'] == null
|
||||
? null
|
||||
: DateTime.parse(json['nextScheduledBackup'] as String),
|
||||
totalBackups: (json['totalBackups'] as num?)?.toInt(),
|
||||
totalSizeBytes: (json['totalSizeBytes'] as num?)?.toInt(),
|
||||
totalSizeFormatted: json['totalSizeFormatted'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$BackupConfigModelToJson(BackupConfigModel instance) =>
|
||||
<String, dynamic>{
|
||||
'autoBackupEnabled': instance.autoBackupEnabled,
|
||||
'frequency': instance.frequency,
|
||||
'retention': instance.retention,
|
||||
'retentionDays': instance.retentionDays,
|
||||
'backupTime': instance.backupTime,
|
||||
'includeDatabase': instance.includeDatabase,
|
||||
'includeFiles': instance.includeFiles,
|
||||
'includeConfiguration': instance.includeConfiguration,
|
||||
'lastBackup': instance.lastBackup?.toIso8601String(),
|
||||
'nextScheduledBackup': instance.nextScheduledBackup?.toIso8601String(),
|
||||
'totalBackups': instance.totalBackups,
|
||||
'totalSizeBytes': instance.totalSizeBytes,
|
||||
'totalSizeFormatted': instance.totalSizeFormatted,
|
||||
};
|
||||
69
lib/features/backup/data/models/backup_model.dart
Normal file
69
lib/features/backup/data/models/backup_model.dart
Normal file
@@ -0,0 +1,69 @@
|
||||
/// Modèle de sauvegarde
|
||||
/// Correspond à BackupResponse du backend
|
||||
library backup_model;
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'backup_model.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class BackupModel extends Equatable {
|
||||
final String? id;
|
||||
final String? name;
|
||||
final String? description;
|
||||
final String? type; // AUTO, MANUAL, RESTORE_POINT
|
||||
final int? sizeBytes;
|
||||
final String? sizeFormatted;
|
||||
final String? status; // PENDING, IN_PROGRESS, COMPLETED, FAILED
|
||||
final DateTime? createdAt;
|
||||
final DateTime? completedAt;
|
||||
final String? createdBy;
|
||||
final bool? includesDatabase;
|
||||
final bool? includesFiles;
|
||||
final bool? includesConfiguration;
|
||||
final String? filePath;
|
||||
final String? errorMessage;
|
||||
|
||||
const BackupModel({
|
||||
this.id,
|
||||
this.name,
|
||||
this.description,
|
||||
this.type,
|
||||
this.sizeBytes,
|
||||
this.sizeFormatted,
|
||||
this.status,
|
||||
this.createdAt,
|
||||
this.completedAt,
|
||||
this.createdBy,
|
||||
this.includesDatabase,
|
||||
this.includesFiles,
|
||||
this.includesConfiguration,
|
||||
this.filePath,
|
||||
this.errorMessage,
|
||||
});
|
||||
|
||||
factory BackupModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$BackupModelFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$BackupModelToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
type,
|
||||
sizeBytes,
|
||||
sizeFormatted,
|
||||
status,
|
||||
createdAt,
|
||||
completedAt,
|
||||
createdBy,
|
||||
includesDatabase,
|
||||
includesFiles,
|
||||
includesConfiguration,
|
||||
filePath,
|
||||
errorMessage,
|
||||
];
|
||||
}
|
||||
48
lib/features/backup/data/models/backup_model.g.dart
Normal file
48
lib/features/backup/data/models/backup_model.g.dart
Normal file
@@ -0,0 +1,48 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'backup_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
BackupModel _$BackupModelFromJson(Map<String, dynamic> json) => BackupModel(
|
||||
id: json['id'] as String?,
|
||||
name: json['name'] as String?,
|
||||
description: json['description'] as String?,
|
||||
type: json['type'] as String?,
|
||||
sizeBytes: (json['sizeBytes'] as num?)?.toInt(),
|
||||
sizeFormatted: json['sizeFormatted'] as String?,
|
||||
status: json['status'] as String?,
|
||||
createdAt: json['createdAt'] == null
|
||||
? null
|
||||
: DateTime.parse(json['createdAt'] as String),
|
||||
completedAt: json['completedAt'] == null
|
||||
? null
|
||||
: DateTime.parse(json['completedAt'] as String),
|
||||
createdBy: json['createdBy'] as String?,
|
||||
includesDatabase: json['includesDatabase'] as bool?,
|
||||
includesFiles: json['includesFiles'] as bool?,
|
||||
includesConfiguration: json['includesConfiguration'] as bool?,
|
||||
filePath: json['filePath'] as String?,
|
||||
errorMessage: json['errorMessage'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$BackupModelToJson(BackupModel instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'description': instance.description,
|
||||
'type': instance.type,
|
||||
'sizeBytes': instance.sizeBytes,
|
||||
'sizeFormatted': instance.sizeFormatted,
|
||||
'status': instance.status,
|
||||
'createdAt': instance.createdAt?.toIso8601String(),
|
||||
'completedAt': instance.completedAt?.toIso8601String(),
|
||||
'createdBy': instance.createdBy,
|
||||
'includesDatabase': instance.includesDatabase,
|
||||
'includesFiles': instance.includesFiles,
|
||||
'includesConfiguration': instance.includesConfiguration,
|
||||
'filePath': instance.filePath,
|
||||
'errorMessage': instance.errorMessage,
|
||||
};
|
||||
131
lib/features/backup/data/repositories/backup_repository.dart
Normal file
131
lib/features/backup/data/repositories/backup_repository.dart
Normal file
@@ -0,0 +1,131 @@
|
||||
/// Repository pour la gestion des sauvegardes
|
||||
/// Interface avec l'API backend BackupResource
|
||||
library backup_repository;
|
||||
|
||||
import 'package:injectable/injectable.dart';
|
||||
import 'package:unionflow_mobile_apps/core/network/api_client.dart';
|
||||
import '../models/backup_model.dart';
|
||||
import '../models/backup_config_model.dart';
|
||||
|
||||
abstract class BackupRepository {
|
||||
Future<List<BackupModel>> getAll();
|
||||
Future<BackupModel> getById(String id);
|
||||
Future<BackupModel> create(String name, {String? description});
|
||||
Future<void> restore(String backupId, {bool createRestorePoint = true});
|
||||
Future<void> delete(String id);
|
||||
Future<BackupConfigModel> getConfig();
|
||||
Future<BackupConfigModel> updateConfig(Map<String, dynamic> config);
|
||||
Future<BackupModel> createRestorePoint();
|
||||
}
|
||||
|
||||
@LazySingleton(as: BackupRepository)
|
||||
class BackupRepositoryImpl implements BackupRepository {
|
||||
final ApiClient _apiClient;
|
||||
static const String _base = '/api/backups';
|
||||
|
||||
BackupRepositoryImpl(this._apiClient);
|
||||
|
||||
List<BackupModel> _parseListResponse(dynamic data) {
|
||||
if (data is List) {
|
||||
return data
|
||||
.map((e) => BackupModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
}
|
||||
if (data is Map && data.containsKey('content')) {
|
||||
final content = data['content'] as List<dynamic>? ?? [];
|
||||
return content
|
||||
.map((e) => BackupModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<BackupModel>> getAll() async {
|
||||
final response = await _apiClient.get(_base);
|
||||
if (response.statusCode == 200) {
|
||||
return _parseListResponse(response.data);
|
||||
}
|
||||
throw Exception('Erreur ${response.statusCode}');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BackupModel> getById(String id) async {
|
||||
final response = await _apiClient.get('$_base/$id');
|
||||
if (response.statusCode == 200) {
|
||||
return BackupModel.fromJson(response.data as Map<String, dynamic>);
|
||||
}
|
||||
throw Exception('Erreur ${response.statusCode}');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BackupModel> create(String name, {String? description}) async {
|
||||
final response = await _apiClient.post(
|
||||
_base,
|
||||
data: {
|
||||
'name': name,
|
||||
'description': description,
|
||||
'type': 'MANUAL',
|
||||
'includeDatabase': true,
|
||||
'includeFiles': true,
|
||||
'includeConfiguration': true,
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 201 || response.statusCode == 200) {
|
||||
return BackupModel.fromJson(response.data as Map<String, dynamic>);
|
||||
}
|
||||
throw Exception('Erreur ${response.statusCode}');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> restore(String backupId, {bool createRestorePoint = true}) async {
|
||||
final response = await _apiClient.post(
|
||||
'$_base/restore',
|
||||
data: {
|
||||
'backupId': backupId,
|
||||
'restoreDatabase': true,
|
||||
'restoreFiles': true,
|
||||
'restoreConfiguration': true,
|
||||
'createRestorePoint': createRestorePoint,
|
||||
},
|
||||
);
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Erreur ${response.statusCode}');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> delete(String id) async {
|
||||
final response = await _apiClient.delete('$_base/$id');
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Erreur ${response.statusCode}');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BackupConfigModel> getConfig() async {
|
||||
final response = await _apiClient.get('$_base/config');
|
||||
if (response.statusCode == 200) {
|
||||
return BackupConfigModel.fromJson(response.data as Map<String, dynamic>);
|
||||
}
|
||||
throw Exception('Erreur ${response.statusCode}');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BackupConfigModel> updateConfig(Map<String, dynamic> config) async {
|
||||
final response = await _apiClient.put('$_base/config', data: config);
|
||||
if (response.statusCode == 200) {
|
||||
return BackupConfigModel.fromJson(response.data as Map<String, dynamic>);
|
||||
}
|
||||
throw Exception('Erreur ${response.statusCode}');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BackupModel> createRestorePoint() async {
|
||||
final response = await _apiClient.post('$_base/restore-point');
|
||||
if (response.statusCode == 201 || response.statusCode == 200) {
|
||||
return BackupModel.fromJson(response.data as Map<String, dynamic>);
|
||||
}
|
||||
throw Exception('Erreur ${response.statusCode}');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user