refactor
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
import 'package:backend_dart/infrastructure/data/prisma_database.dart';
|
||||
import 'package:riverpod/riverpod.dart';
|
||||
|
||||
final databaseProvider = Provider<PrismaDatabase>((ref) {
|
||||
// Hier die Datenbankverbindung initialisieren
|
||||
final database = PrismaDatabase();
|
||||
return database;
|
||||
});
|
||||
+2703
File diff suppressed because it is too large
Load Diff
+531
@@ -0,0 +1,531 @@
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'model.dart' as _i1;
|
||||
import 'prisma.dart' as _i2;
|
||||
|
||||
class ProjectTaskDbo {
|
||||
const ProjectTaskDbo({
|
||||
this.id,
|
||||
this.name,
|
||||
this.description,
|
||||
this.projectId,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.project,
|
||||
});
|
||||
|
||||
factory ProjectTaskDbo.fromJson(Map json) => ProjectTaskDbo(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
description: json['description'],
|
||||
projectId: json['projectId'],
|
||||
createdAt: switch (json['createdAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['createdAt']
|
||||
},
|
||||
updatedAt: switch (json['updatedAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['updatedAt']
|
||||
},
|
||||
project: json['project'] is Map
|
||||
? _i1.ProjectDbo.fromJson(json['project'])
|
||||
: null,
|
||||
);
|
||||
|
||||
final String? id;
|
||||
|
||||
final String? name;
|
||||
|
||||
final String? description;
|
||||
|
||||
final String? projectId;
|
||||
|
||||
final DateTime? createdAt;
|
||||
|
||||
final DateTime? updatedAt;
|
||||
|
||||
final _i1.ProjectDbo? project;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'projectId': projectId,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
'project': project?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class TimeEntryDbo {
|
||||
const TimeEntryDbo({
|
||||
this.id,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.description,
|
||||
this.userId,
|
||||
this.projectId,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.user,
|
||||
this.project,
|
||||
});
|
||||
|
||||
factory TimeEntryDbo.fromJson(Map json) => TimeEntryDbo(
|
||||
id: json['id'],
|
||||
startTime: switch (json['startTime']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['startTime']
|
||||
},
|
||||
endTime: switch (json['endTime']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['endTime']
|
||||
},
|
||||
description: json['description'],
|
||||
userId: json['userId'],
|
||||
projectId: json['projectId'],
|
||||
createdAt: switch (json['createdAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['createdAt']
|
||||
},
|
||||
updatedAt: switch (json['updatedAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['updatedAt']
|
||||
},
|
||||
user: json['user'] is Map ? _i1.UserDbo.fromJson(json['user']) : null,
|
||||
project: json['project'] is Map
|
||||
? _i1.ProjectDbo.fromJson(json['project'])
|
||||
: null,
|
||||
);
|
||||
|
||||
final String? id;
|
||||
|
||||
final DateTime? startTime;
|
||||
|
||||
final DateTime? endTime;
|
||||
|
||||
final String? description;
|
||||
|
||||
final String? userId;
|
||||
|
||||
final String? projectId;
|
||||
|
||||
final DateTime? createdAt;
|
||||
|
||||
final DateTime? updatedAt;
|
||||
|
||||
final _i1.UserDbo? user;
|
||||
|
||||
final _i1.ProjectDbo? project;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'startTime': startTime?.toIso8601String(),
|
||||
'endTime': endTime?.toIso8601String(),
|
||||
'description': description,
|
||||
'userId': userId,
|
||||
'projectId': projectId,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
'user': user?.toJson(),
|
||||
'project': project?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class ProjectDbo {
|
||||
const ProjectDbo({
|
||||
this.id,
|
||||
this.name,
|
||||
this.description,
|
||||
this.clientId,
|
||||
this.userId,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.tasks,
|
||||
this.timeEntries,
|
||||
this.user,
|
||||
this.$count,
|
||||
});
|
||||
|
||||
factory ProjectDbo.fromJson(Map json) => ProjectDbo(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
description: json['description'],
|
||||
clientId: json['clientId'],
|
||||
userId: json['userId'],
|
||||
createdAt: switch (json['createdAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['createdAt']
|
||||
},
|
||||
updatedAt: switch (json['updatedAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['updatedAt']
|
||||
},
|
||||
tasks: (json['tasks'] as Iterable?)
|
||||
?.map((json) => _i1.ProjectTaskDbo.fromJson(json)),
|
||||
timeEntries: (json['timeEntries'] as Iterable?)
|
||||
?.map((json) => _i1.TimeEntryDbo.fromJson(json)),
|
||||
user: json['user'] is Map ? _i1.UserDbo.fromJson(json['user']) : null,
|
||||
$count: json['_count'] is Map
|
||||
? _i2.ProjectDboCountOutputType.fromJson(json['_count'])
|
||||
: null,
|
||||
);
|
||||
|
||||
final String? id;
|
||||
|
||||
final String? name;
|
||||
|
||||
final String? description;
|
||||
|
||||
final String? clientId;
|
||||
|
||||
final String? userId;
|
||||
|
||||
final DateTime? createdAt;
|
||||
|
||||
final DateTime? updatedAt;
|
||||
|
||||
final Iterable<_i1.ProjectTaskDbo>? tasks;
|
||||
|
||||
final Iterable<_i1.TimeEntryDbo>? timeEntries;
|
||||
|
||||
final _i1.UserDbo? user;
|
||||
|
||||
final _i2.ProjectDboCountOutputType? $count;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'clientId': clientId,
|
||||
'userId': userId,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
'tasks': tasks?.map((e) => e.toJson()),
|
||||
'timeEntries': timeEntries?.map((e) => e.toJson()),
|
||||
'user': user?.toJson(),
|
||||
'_count': $count?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class UserDbo {
|
||||
const UserDbo({
|
||||
this.id,
|
||||
this.name,
|
||||
this.email,
|
||||
this.password,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.projects,
|
||||
this.timeEntries,
|
||||
this.$count,
|
||||
});
|
||||
|
||||
factory UserDbo.fromJson(Map json) => UserDbo(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
email: json['email'],
|
||||
password: json['password'],
|
||||
createdAt: switch (json['createdAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['createdAt']
|
||||
},
|
||||
updatedAt: switch (json['updatedAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['updatedAt']
|
||||
},
|
||||
projects: (json['projects'] as Iterable?)
|
||||
?.map((json) => _i1.ProjectDbo.fromJson(json)),
|
||||
timeEntries: (json['timeEntries'] as Iterable?)
|
||||
?.map((json) => _i1.TimeEntryDbo.fromJson(json)),
|
||||
$count: json['_count'] is Map
|
||||
? _i2.UserDboCountOutputType.fromJson(json['_count'])
|
||||
: null,
|
||||
);
|
||||
|
||||
final String? id;
|
||||
|
||||
final String? name;
|
||||
|
||||
final String? email;
|
||||
|
||||
final String? password;
|
||||
|
||||
final DateTime? createdAt;
|
||||
|
||||
final DateTime? updatedAt;
|
||||
|
||||
final Iterable<_i1.ProjectDbo>? projects;
|
||||
|
||||
final Iterable<_i1.TimeEntryDbo>? timeEntries;
|
||||
|
||||
final _i2.UserDboCountOutputType? $count;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'email': email,
|
||||
'password': password,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
'projects': projects?.map((e) => e.toJson()),
|
||||
'timeEntries': timeEntries?.map((e) => e.toJson()),
|
||||
'_count': $count?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class CreateManyUserDboAndReturnOutputType {
|
||||
const CreateManyUserDboAndReturnOutputType({
|
||||
this.id,
|
||||
this.name,
|
||||
this.email,
|
||||
this.password,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
});
|
||||
|
||||
factory CreateManyUserDboAndReturnOutputType.fromJson(Map json) =>
|
||||
CreateManyUserDboAndReturnOutputType(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
email: json['email'],
|
||||
password: json['password'],
|
||||
createdAt: switch (json['createdAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['createdAt']
|
||||
},
|
||||
updatedAt: switch (json['updatedAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['updatedAt']
|
||||
},
|
||||
);
|
||||
|
||||
final String? id;
|
||||
|
||||
final String? name;
|
||||
|
||||
final String? email;
|
||||
|
||||
final String? password;
|
||||
|
||||
final DateTime? createdAt;
|
||||
|
||||
final DateTime? updatedAt;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'email': email,
|
||||
'password': password,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
class CreateManyProjectDboAndReturnOutputType {
|
||||
const CreateManyProjectDboAndReturnOutputType({
|
||||
this.id,
|
||||
this.name,
|
||||
this.description,
|
||||
this.clientId,
|
||||
this.userId,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.user,
|
||||
});
|
||||
|
||||
factory CreateManyProjectDboAndReturnOutputType.fromJson(Map json) =>
|
||||
CreateManyProjectDboAndReturnOutputType(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
description: json['description'],
|
||||
clientId: json['clientId'],
|
||||
userId: json['userId'],
|
||||
createdAt: switch (json['createdAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['createdAt']
|
||||
},
|
||||
updatedAt: switch (json['updatedAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['updatedAt']
|
||||
},
|
||||
user: json['user'] is Map ? _i1.UserDbo.fromJson(json['user']) : null,
|
||||
);
|
||||
|
||||
final String? id;
|
||||
|
||||
final String? name;
|
||||
|
||||
final String? description;
|
||||
|
||||
final String? clientId;
|
||||
|
||||
final String? userId;
|
||||
|
||||
final DateTime? createdAt;
|
||||
|
||||
final DateTime? updatedAt;
|
||||
|
||||
final _i1.UserDbo? user;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'clientId': clientId,
|
||||
'userId': userId,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
'user': user?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class CreateManyTimeEntryDboAndReturnOutputType {
|
||||
const CreateManyTimeEntryDboAndReturnOutputType({
|
||||
this.id,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.description,
|
||||
this.userId,
|
||||
this.projectId,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.user,
|
||||
this.project,
|
||||
});
|
||||
|
||||
factory CreateManyTimeEntryDboAndReturnOutputType.fromJson(Map json) =>
|
||||
CreateManyTimeEntryDboAndReturnOutputType(
|
||||
id: json['id'],
|
||||
startTime: switch (json['startTime']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['startTime']
|
||||
},
|
||||
endTime: switch (json['endTime']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['endTime']
|
||||
},
|
||||
description: json['description'],
|
||||
userId: json['userId'],
|
||||
projectId: json['projectId'],
|
||||
createdAt: switch (json['createdAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['createdAt']
|
||||
},
|
||||
updatedAt: switch (json['updatedAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['updatedAt']
|
||||
},
|
||||
user: json['user'] is Map ? _i1.UserDbo.fromJson(json['user']) : null,
|
||||
project: json['project'] is Map
|
||||
? _i1.ProjectDbo.fromJson(json['project'])
|
||||
: null,
|
||||
);
|
||||
|
||||
final String? id;
|
||||
|
||||
final DateTime? startTime;
|
||||
|
||||
final DateTime? endTime;
|
||||
|
||||
final String? description;
|
||||
|
||||
final String? userId;
|
||||
|
||||
final String? projectId;
|
||||
|
||||
final DateTime? createdAt;
|
||||
|
||||
final DateTime? updatedAt;
|
||||
|
||||
final _i1.UserDbo? user;
|
||||
|
||||
final _i1.ProjectDbo? project;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'startTime': startTime?.toIso8601String(),
|
||||
'endTime': endTime?.toIso8601String(),
|
||||
'description': description,
|
||||
'userId': userId,
|
||||
'projectId': projectId,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
'user': user?.toJson(),
|
||||
'project': project?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class CreateManyProjectTaskDboAndReturnOutputType {
|
||||
const CreateManyProjectTaskDboAndReturnOutputType({
|
||||
this.id,
|
||||
this.name,
|
||||
this.description,
|
||||
this.projectId,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.project,
|
||||
});
|
||||
|
||||
factory CreateManyProjectTaskDboAndReturnOutputType.fromJson(Map json) =>
|
||||
CreateManyProjectTaskDboAndReturnOutputType(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
description: json['description'],
|
||||
projectId: json['projectId'],
|
||||
createdAt: switch (json['createdAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['createdAt']
|
||||
},
|
||||
updatedAt: switch (json['updatedAt']) {
|
||||
DateTime value => value,
|
||||
String value => DateTime.parse(value),
|
||||
_ => json['updatedAt']
|
||||
},
|
||||
project: json['project'] is Map
|
||||
? _i1.ProjectDbo.fromJson(json['project'])
|
||||
: null,
|
||||
);
|
||||
|
||||
final String? id;
|
||||
|
||||
final String? name;
|
||||
|
||||
final String? description;
|
||||
|
||||
final String? projectId;
|
||||
|
||||
final DateTime? createdAt;
|
||||
|
||||
final DateTime? updatedAt;
|
||||
|
||||
final _i1.ProjectDbo? project;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'projectId': projectId,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
'project': project?.toJson(),
|
||||
};
|
||||
}
|
||||
+10566
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
||||
import 'package:backend_dart/common/extensions.dart';
|
||||
import 'package:backend_dart/domain/entities/project.dart';
|
||||
import 'package:backend_dart/domain/errors/error.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/model.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/prisma.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:orm/orm.dart';
|
||||
|
||||
class ProjectDboMapper {
|
||||
TaskEither<IError, Project> fromDbo(ProjectDbo dbo) {
|
||||
return TaskEither.of(Project(
|
||||
id: dbo.id!,
|
||||
name: dbo.name!,
|
||||
description: dbo.description,
|
||||
clientId: dbo.clientId,
|
||||
userId: dbo.userId!,
|
||||
createdAt: dbo.createdAt!,
|
||||
updatedAt: dbo.updatedAt!,
|
||||
));
|
||||
}
|
||||
|
||||
TaskEither<IError, List<Project>> listFrom(Iterable<ProjectDbo> dbos) {
|
||||
return TaskEither.traverseList(dbos.toList(), fromDbo);
|
||||
}
|
||||
|
||||
TaskEither<IError, ProjectDboCreateInput> fromCreatetoDbo(
|
||||
ProjectCreate project) {
|
||||
return TaskEither.of(ProjectDboCreateInput(
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
description: project.description.let(PrismaUnion.$1),
|
||||
clientId: project.clientId.let(PrismaUnion.$1),
|
||||
user: UserDboCreateNestedOneWithoutProjectsInput(
|
||||
connect: UserDboWhereUniqueInput(id: project.userId),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
TaskEither<IError, ProjectDboUpdateInput> fromUpdateToDbo(
|
||||
ProjectUpdate project) {
|
||||
return TaskEither.of(ProjectDboUpdateInput(
|
||||
id: PrismaUnion.$1(project.id),
|
||||
name: project.name.let(PrismaUnion.$1),
|
||||
description: project.description.let(PrismaUnion.$1),
|
||||
clientId: project.clientId.let(PrismaUnion.$1),
|
||||
user: project.userId.let(
|
||||
(userId) => UserDboUpdateOneRequiredWithoutProjectsNestedInput(
|
||||
connect: UserDboWhereUniqueInput(id: userId),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import 'package:backend_dart/common/extensions.dart';
|
||||
import 'package:backend_dart/domain/entities/project_task.dart';
|
||||
import 'package:backend_dart/domain/errors/error.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/model.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/prisma.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:orm/orm.dart';
|
||||
|
||||
class ProjectTaskDboMapper {
|
||||
TaskEither<IError, ProjectTask> from(ProjectTaskDbo target) =>
|
||||
TaskEither.of(ProjectTask(
|
||||
id: target.id!,
|
||||
name: target.name!,
|
||||
description: target.description,
|
||||
projectId: target.projectId!,
|
||||
createdAt: target.createdAt!,
|
||||
updatedAt: target.updatedAt!,
|
||||
));
|
||||
|
||||
TaskEither<IError, List<ProjectTask>> listFrom(
|
||||
Iterable<ProjectTaskDbo> targets) {
|
||||
return TaskEither.traverseList(targets.toList(), from);
|
||||
}
|
||||
|
||||
TaskEither<IError, ProjectTaskDboCreateInput> fromCreateTo(
|
||||
ProjectTaskCreate origin) =>
|
||||
TaskEither.of(ProjectTaskDboCreateInput(
|
||||
id: origin.id,
|
||||
name: origin.name,
|
||||
description: origin.description.let(PrismaUnion.$1),
|
||||
project: ProjectDboCreateNestedOneWithoutTasksInput(
|
||||
connect: ProjectDboWhereUniqueInput(
|
||||
id: origin.projectId,
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
TaskEither<IError, ProjectTaskDboUpdateInput> fromUpdateTo(
|
||||
ProjectTaskUpdate origin) =>
|
||||
TaskEither.of(ProjectTaskDboUpdateInput(
|
||||
id: PrismaUnion.$1(origin.id),
|
||||
name: origin.name?.let(PrismaUnion.$1),
|
||||
description: origin.description?.let(PrismaUnion.$1),
|
||||
project: origin.projectId?.let(
|
||||
(projectId) => ProjectDboUpdateOneRequiredWithoutTasksNestedInput(
|
||||
connect: ProjectDboWhereUniqueInput(
|
||||
id: projectId,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import 'package:backend_dart/common/extensions.dart';
|
||||
import 'package:backend_dart/domain/entities/time_entry.dart';
|
||||
import 'package:backend_dart/domain/errors/error.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/model.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/prisma.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:orm/orm.dart';
|
||||
|
||||
class TimeEntryDboMapper {
|
||||
TaskEither<IError, TimeEntry> from(TimeEntryDbo target) => TaskEither.of(
|
||||
TimeEntry(
|
||||
id: target.id!,
|
||||
startTime: target.startTime!,
|
||||
endTime: target.endTime,
|
||||
description: target.description,
|
||||
userId: target.userId!,
|
||||
projectId: target.projectId!,
|
||||
createdAt: target.createdAt!,
|
||||
updatedAt: target.updatedAt!,
|
||||
),
|
||||
);
|
||||
|
||||
TaskEither<IError, List<TimeEntry>> listFrom(Iterable<TimeEntryDbo> targets) {
|
||||
return TaskEither.traverseList(targets.toList(), from);
|
||||
}
|
||||
|
||||
TaskEither<IError, TimeEntryDboCreateInput> fromCreateTo(
|
||||
TimeEntryCreate origin) =>
|
||||
TaskEither.of(TimeEntryDboCreateInput(
|
||||
id: origin.id,
|
||||
startTime: origin.startTime,
|
||||
endTime: origin.endTime.let(PrismaUnion.$1),
|
||||
description: origin.description.let(PrismaUnion.$1),
|
||||
user: UserDboCreateNestedOneWithoutTimeEntriesInput(
|
||||
connect: UserDboWhereUniqueInput(
|
||||
id: origin.userId,
|
||||
),
|
||||
),
|
||||
project: ProjectDboCreateNestedOneWithoutTimeEntriesInput(
|
||||
connect: ProjectDboWhereUniqueInput(
|
||||
id: origin.projectId,
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
TaskEither<IError, TimeEntryDboUpdateInput> fromUpdateTo(
|
||||
TimeEntryUpdate origin) =>
|
||||
TaskEither.of(TimeEntryDboUpdateInput(
|
||||
id: PrismaUnion.$1(origin.id),
|
||||
startTime: origin.startTime?.let(PrismaUnion.$1),
|
||||
endTime: origin.endTime?.let(PrismaUnion.$1),
|
||||
description: origin.description?.let(PrismaUnion.$1),
|
||||
user: origin.userId?.let(
|
||||
(userId) => UserDboUpdateOneRequiredWithoutTimeEntriesNestedInput(
|
||||
connect: UserDboWhereUniqueInput(
|
||||
id: userId,
|
||||
),
|
||||
),
|
||||
),
|
||||
project: origin.projectId?.let(
|
||||
(projectId) =>
|
||||
ProjectDboUpdateOneRequiredWithoutTimeEntriesNestedInput(
|
||||
connect: ProjectDboWhereUniqueInput(
|
||||
id: projectId,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import 'package:backend_dart/common/extensions.dart';
|
||||
import 'package:backend_dart/common/secure_hash.dart';
|
||||
import 'package:backend_dart/domain/entities/user.dart';
|
||||
import 'package:backend_dart/domain/errors/error.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/model.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/prisma.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:orm/orm.dart';
|
||||
|
||||
class UserDboMapper {
|
||||
TaskEither<IError, User> from(UserDbo target) => TaskEither.of(User(
|
||||
id: target.id!,
|
||||
name: target.name!,
|
||||
email: target.email!,
|
||||
passwordHash: target.password,
|
||||
createdAt: target.createdAt,
|
||||
updatedAt: target.updatedAt,
|
||||
));
|
||||
|
||||
TaskEither<IError, List<User>> listFrom(Iterable<UserDbo> targets) {
|
||||
return TaskEither.traverseList(targets.toList(), from);
|
||||
}
|
||||
|
||||
TaskEither<IError, UserDboUpdateInput> fromUpdateTo(UserUpdate origin) =>
|
||||
TaskEither.of(UserDboUpdateInput(
|
||||
id: PrismaUnion.$1(origin.id),
|
||||
name: origin.name.let(PrismaUnion.$1),
|
||||
email: origin.email.let(PrismaUnion.$1),
|
||||
password: origin.password.let(generateSecureHash).let(PrismaUnion.$1),
|
||||
));
|
||||
|
||||
TaskEither<IError, UserDboCreateInput> fromCreateTo(UserCreate origin) =>
|
||||
TaskEither.of(UserDboCreateInput(
|
||||
id: origin.id,
|
||||
name: origin.name,
|
||||
email: origin.email,
|
||||
password: generateSecureHash(origin.password),
|
||||
));
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import 'package:backend_dart/domain/data/database.dart';
|
||||
import 'package:backend_dart/domain/data/project_data_source.dart';
|
||||
import 'package:backend_dart/domain/data/project_task_data_source.dart';
|
||||
import 'package:backend_dart/domain/data/time_entry_data_source.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/client.dart';
|
||||
import 'package:backend_dart/infrastructure/data/prisma_project_data_source.dart';
|
||||
import 'package:backend_dart/infrastructure/data/prisma_project_task_data_source.dart';
|
||||
import 'package:backend_dart/infrastructure/data/prisma_time_entry_data_source.dart';
|
||||
import 'package:backend_dart/infrastructure/data/prisma_user_data_source.dart';
|
||||
|
||||
class PrismaDatabase implements IDatabase {
|
||||
final prisma = PrismaClient();
|
||||
late final PrismaUserDataSource _users;
|
||||
late final TimeEntryDataSource _timeEntries;
|
||||
late final ProjectTaskDataSource _tasks;
|
||||
late final ProjectDataSource _projects;
|
||||
|
||||
PrismaDatabase() {
|
||||
_users = PrismaUserDataSource(prisma);
|
||||
_timeEntries = PrismaTimeEntryDataSource(prisma);
|
||||
_tasks = PrismaProjectTaskDataSource(prisma);
|
||||
_projects = PrismaProjectDataSource(prisma);
|
||||
print('Database initialized');
|
||||
}
|
||||
|
||||
@override
|
||||
get users => _users;
|
||||
@override
|
||||
get timeEntries => _timeEntries;
|
||||
@override
|
||||
get tasks => _tasks;
|
||||
@override
|
||||
get projects => _projects;
|
||||
@override
|
||||
Future<void> close() {
|
||||
return Future.value();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
import 'package:backend_dart/common/error_on_null.dart';
|
||||
import 'package:backend_dart/domain/data/project_data_source.dart';
|
||||
import 'package:backend_dart/domain/entities/project.dart';
|
||||
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||
import 'package:backend_dart/domain/errors/error.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/client.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/model.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/prisma.dart';
|
||||
import 'package:backend_dart/infrastructure/data/mapper/project_dbo_mapper.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:orm/orm.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class PrismaProjectDataSource implements ProjectDataSource {
|
||||
final PrismaClient prisma;
|
||||
final ProjectDboMapper mapper = ProjectDboMapper();
|
||||
|
||||
PrismaProjectDataSource(this.prisma);
|
||||
|
||||
@override
|
||||
TaskEither<IError, Project> create(ProjectCreate project) {
|
||||
return mapper
|
||||
.fromCreatetoDbo(project)
|
||||
.flatMap((projectDbo) => TaskEither.tryCatch(
|
||||
() async {
|
||||
return await prisma.projectDbo.create(
|
||||
data: PrismaUnion.$1(projectDbo),
|
||||
);
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to create project: ${error.toString()}',
|
||||
),
|
||||
))
|
||||
.flatMap(mapper.fromDbo);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, Project> findById(String id) {
|
||||
return TaskEither<IError, ProjectDbo?>.tryCatch(
|
||||
() async {
|
||||
final project = await prisma.projectDbo
|
||||
.findUnique(where: ProjectDboWhereUniqueInput(id: id));
|
||||
return project;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to find project by ID: ${error.toString()}',
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(AppError.notFound('Project with ID $id not found')))
|
||||
.flatMap(mapper.fromDbo);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, List<Project>> findByUserId(String userId) {
|
||||
return TaskEither<IError, Iterable<ProjectDbo>>.tryCatch(
|
||||
() async {
|
||||
final projects = await prisma.projectDbo.findMany(
|
||||
where: ProjectDboWhereInput(
|
||||
userId: PrismaUnion.$1(StringFilter(
|
||||
equals: PrismaUnion.$1(userId),
|
||||
))),
|
||||
);
|
||||
return projects;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to find projects by user ID: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.listFrom);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, Project> update(ProjectUpdate project) {
|
||||
return mapper
|
||||
.fromUpdateToDbo(project)
|
||||
.flatMap(
|
||||
(projectDbo) => TaskEither.tryCatch(
|
||||
() async {
|
||||
return await prisma.projectDbo.update(
|
||||
data: PrismaUnion.$1(projectDbo),
|
||||
where: ProjectDboWhereUniqueInput(id: project.id),
|
||||
);
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to update project: ${error.toString()}',
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(
|
||||
AppError.notFound(
|
||||
'Project with ID ${project.id} not found',
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(mapper.fromDbo);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, Project> delete(String id) {
|
||||
return TaskEither<IError, ProjectDbo?>.tryCatch(
|
||||
() async {
|
||||
return await prisma.projectDbo
|
||||
.delete(where: ProjectDboWhereUniqueInput(id: id));
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to delete project: ${error.toString()}',
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(
|
||||
AppError.notFound(
|
||||
'Project with ID $id not found',
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(mapper.fromDbo);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, List<Project>> findAll() {
|
||||
return TaskEither<IError, Iterable<ProjectDbo>>.tryCatch(
|
||||
() async => await prisma.projectDbo.findMany(),
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to fetch all projects: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.listFrom);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, String> generateId() {
|
||||
return TaskEither.tryCatch(
|
||||
() async {
|
||||
var uuid = Uuid();
|
||||
do {
|
||||
final id = uuid.v4();
|
||||
final project = await prisma.projectDbo.findUnique(
|
||||
where: ProjectDboWhereUniqueInput(id: id),
|
||||
);
|
||||
if (project == null) return id;
|
||||
} while (true);
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to generate ID: ${error.toString()}',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
import 'package:backend_dart/common/error_on_null.dart';
|
||||
import 'package:backend_dart/domain/data/project_task_data_source.dart';
|
||||
import 'package:backend_dart/domain/entities/project_task.dart';
|
||||
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||
import 'package:backend_dart/domain/errors/error.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/client.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/model.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/prisma.dart';
|
||||
import 'package:backend_dart/infrastructure/data/mapper/project_task_dbo_mapper.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:orm/orm.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class PrismaProjectTaskDataSource implements ProjectTaskDataSource {
|
||||
final PrismaClient prisma;
|
||||
final ProjectTaskDboMapper mapper = ProjectTaskDboMapper();
|
||||
|
||||
PrismaProjectTaskDataSource(this.prisma);
|
||||
|
||||
@override
|
||||
TaskEither<IError, ProjectTask> create(ProjectTaskCreate task) =>
|
||||
mapper.fromCreateTo(task).flatMap(
|
||||
(taskDbo) => TaskEither<IError, ProjectTaskDbo>.tryCatch(
|
||||
() async {
|
||||
final createdTask = await prisma.projectTaskDbo.create(
|
||||
data: PrismaUnion.$1(taskDbo),
|
||||
);
|
||||
return createdTask;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to create project task: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.from),
|
||||
);
|
||||
|
||||
@override
|
||||
TaskEither<IError, ProjectTask> findById(String id) {
|
||||
return TaskEither<IError, ProjectTaskDbo?>.tryCatch(
|
||||
() async {
|
||||
final task = await prisma.projectTaskDbo
|
||||
.findUnique(where: ProjectTaskDboWhereUniqueInput(id: id));
|
||||
return task;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to find project task by ID: ${error.toString()}',
|
||||
),
|
||||
)
|
||||
.flatMap(errorOnNull(AppError.notFound(
|
||||
"Project task with id $id not found",
|
||||
)))
|
||||
.flatMap(mapper.from);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, List<ProjectTask>> findByProjectId(String projectId) {
|
||||
return TaskEither<IError, Iterable<ProjectTaskDbo>>.tryCatch(
|
||||
() async => await prisma.projectTaskDbo.findMany(
|
||||
where: ProjectTaskDboWhereInput(projectId: PrismaUnion.$2(projectId)),
|
||||
),
|
||||
(error, _) => AppError.databaseError(
|
||||
message:
|
||||
'Failed to fetch tasks for project $projectId: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.listFrom);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, ProjectTask> update(ProjectTaskUpdate task) => mapper
|
||||
.fromUpdateTo(task)
|
||||
.flatMap(
|
||||
(taskDbo) => TaskEither.tryCatch(
|
||||
() async {
|
||||
final updatedTask = await prisma.projectTaskDbo.update(
|
||||
data: PrismaUnion.$1(taskDbo),
|
||||
where: ProjectTaskDboWhereUniqueInput(id: task.id),
|
||||
);
|
||||
return updatedTask;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to update project task: ${error.toString()}',
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(AppError.notFound("Project task not found")),
|
||||
)
|
||||
.flatMap(mapper.from);
|
||||
|
||||
@override
|
||||
TaskEither<IError, ProjectTask> delete(String id) {
|
||||
return TaskEither<IError, ProjectTaskDbo?>.tryCatch(
|
||||
() async {
|
||||
return await prisma.projectTaskDbo.delete(
|
||||
where: ProjectTaskDboWhereUniqueInput(id: id),
|
||||
);
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to delete project task: ${error.toString()}',
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(
|
||||
AppError.notFound(
|
||||
'Project task with ID $id not found',
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(mapper.from);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, List<ProjectTask>> findAll() {
|
||||
return TaskEither<IError, Iterable<ProjectTaskDbo>>.tryCatch(
|
||||
() async => await prisma.projectTaskDbo.findMany(),
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to fetch all project tasks: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.listFrom);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, String> generateId() {
|
||||
return TaskEither.tryCatch(
|
||||
() async {
|
||||
var uuid = Uuid();
|
||||
do {
|
||||
final id = uuid.v4();
|
||||
final task = await prisma.projectTaskDbo.findUnique(
|
||||
where: ProjectTaskDboWhereUniqueInput(id: id),
|
||||
);
|
||||
if (task == null) return id;
|
||||
} while (true);
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to generate ID: ${error.toString()}',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
import 'package:backend_dart/common/error_on_null.dart';
|
||||
import 'package:backend_dart/domain/data/time_entry_data_source.dart';
|
||||
import 'package:backend_dart/domain/entities/time_entry.dart';
|
||||
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||
import 'package:backend_dart/domain/errors/error.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/client.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/model.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/prisma.dart';
|
||||
import 'package:backend_dart/infrastructure/data/mapper/time_entry_dbo_mapper.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:orm/orm.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class PrismaTimeEntryDataSource implements TimeEntryDataSource {
|
||||
final PrismaClient prisma;
|
||||
final TimeEntryDboMapper mapper = TimeEntryDboMapper();
|
||||
|
||||
PrismaTimeEntryDataSource(this.prisma);
|
||||
|
||||
@override
|
||||
TaskEither<IError, TimeEntry> create(TimeEntryCreate timeEntry) =>
|
||||
mapper.fromCreateTo(timeEntry).flatMap(
|
||||
(timeEntryDbo) => TaskEither<IError, TimeEntryDbo>.tryCatch(
|
||||
() async {
|
||||
final createdEntry = await prisma.timeEntryDbo.create(
|
||||
data: PrismaUnion.$1(timeEntryDbo),
|
||||
);
|
||||
return createdEntry;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to create time entry: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.from),
|
||||
);
|
||||
|
||||
@override
|
||||
TaskEither<IError, TimeEntry> findById(String id) {
|
||||
return TaskEither<IError, TimeEntryDbo?>.tryCatch(
|
||||
() async {
|
||||
final timeEntry = await prisma.timeEntryDbo
|
||||
.findUnique(where: TimeEntryDboWhereUniqueInput(id: id));
|
||||
return timeEntry;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to find time entry by ID: ${error.toString()}',
|
||||
),
|
||||
)
|
||||
.flatMap(errorOnNull(AppError.notFound(
|
||||
"Time entry with id $id not found",
|
||||
)))
|
||||
.flatMap(mapper.from);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, List<TimeEntry>> findByUserId(String userId) {
|
||||
return TaskEither<IError, Iterable<TimeEntryDbo>>.tryCatch(
|
||||
() async => await prisma.timeEntryDbo.findMany(
|
||||
where: TimeEntryDboWhereInput(userId: PrismaUnion.$2(userId)),
|
||||
),
|
||||
(error, _) => AppError.databaseError(
|
||||
message:
|
||||
'Failed to fetch time entries for user $userId: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.listFrom);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, List<TimeEntry>> findByProjectId(String projectId) {
|
||||
return TaskEither<IError, Iterable<TimeEntryDbo>>.tryCatch(
|
||||
() async => await prisma.timeEntryDbo.findMany(
|
||||
where: TimeEntryDboWhereInput(projectId: PrismaUnion.$2(projectId)),
|
||||
),
|
||||
(error, _) => AppError.databaseError(
|
||||
message:
|
||||
'Failed to fetch time entries for project $projectId: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.listFrom);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, TimeEntry> update(TimeEntryUpdate timeEntry) => mapper
|
||||
.fromUpdateTo(timeEntry)
|
||||
.flatMap(
|
||||
(timeEntryDbo) => TaskEither.tryCatch(
|
||||
() async {
|
||||
final updatedEntry = await prisma.timeEntryDbo.update(
|
||||
data: PrismaUnion.$1(timeEntryDbo),
|
||||
where: TimeEntryDboWhereUniqueInput(id: timeEntry.id),
|
||||
);
|
||||
return updatedEntry;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to update time entry: ${error.toString()}',
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(AppError.notFound("Time entry not found")),
|
||||
)
|
||||
.flatMap(mapper.from);
|
||||
|
||||
@override
|
||||
TaskEither<IError, TimeEntry> delete(String id) {
|
||||
return TaskEither<IError, TimeEntryDbo?>.tryCatch(
|
||||
() async {
|
||||
return await prisma.timeEntryDbo.delete(
|
||||
where: TimeEntryDboWhereUniqueInput(id: id),
|
||||
);
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to delete time entry: ${error.toString()}',
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(AppError.notFound(
|
||||
"Time entry with id $id not found",
|
||||
)),
|
||||
)
|
||||
.flatMap(mapper.from);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, List<TimeEntry>> findAll() {
|
||||
return TaskEither<IError, Iterable<TimeEntryDbo>>.tryCatch(
|
||||
() async => await prisma.timeEntryDbo.findMany(),
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to fetch all time entries: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.listFrom);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, String> generateId() {
|
||||
return TaskEither.tryCatch(
|
||||
() async {
|
||||
var uuid = Uuid();
|
||||
do {
|
||||
final id = uuid.v4();
|
||||
final entry = await prisma.timeEntryDbo.findUnique(
|
||||
where: TimeEntryDboWhereUniqueInput(id: id),
|
||||
);
|
||||
if (entry == null) return id;
|
||||
} while (true);
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to generate ID: ${error.toString()}',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
import 'package:backend_dart/common/error_on_null.dart';
|
||||
import 'package:backend_dart/domain/data/user_data_source.dart';
|
||||
import 'package:backend_dart/domain/entities/user.dart';
|
||||
import 'package:backend_dart/domain/errors/app_error.dart';
|
||||
import 'package:backend_dart/domain/errors/error.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/model.dart';
|
||||
import 'package:backend_dart/infrastructure/data/db/prisma.dart';
|
||||
import 'package:backend_dart/infrastructure/data/mapper/user_dbo_mapper.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:orm/orm.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import 'db/client.dart';
|
||||
|
||||
class PrismaUserDataSource implements UserDataSource {
|
||||
final PrismaClient prisma;
|
||||
final UserDboMapper mapper = UserDboMapper();
|
||||
PrismaUserDataSource(this.prisma);
|
||||
|
||||
@override
|
||||
TaskEither<IError, User> create(UserCreate user) => mapper
|
||||
.fromCreateTo(user)
|
||||
.flatMap((userDbo) => TaskEither<IError, UserDbo>.tryCatch(
|
||||
() async {
|
||||
final createdUser = await prisma.userDbo.create(
|
||||
data: PrismaUnion.$1(userDbo),
|
||||
);
|
||||
return createdUser;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to create user: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.from));
|
||||
|
||||
@override
|
||||
TaskEither<IError, User> findByEmail(String email) {
|
||||
return TaskEither<IError, UserDbo?>.tryCatch(
|
||||
() async {
|
||||
final user = await prisma.userDbo
|
||||
.findUnique(where: UserDboWhereUniqueInput(email: email));
|
||||
if (user == null) return null;
|
||||
return user;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to find user by email: ${error.toString()}',
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(
|
||||
AppError.notFound(
|
||||
'User with email $email found',
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(mapper.from);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, User> findById(String id) {
|
||||
return TaskEither<IError, UserDbo?>.tryCatch(
|
||||
() async {
|
||||
final user = await prisma.userDbo
|
||||
.findUnique(where: UserDboWhereUniqueInput(id: id));
|
||||
return user;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to find user by ID: ${error.toString()}',
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(
|
||||
AppError.notFound(
|
||||
"User with id $id not found",
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(mapper.from);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, User> update(UserUpdate user) {
|
||||
return mapper
|
||||
.fromUpdateTo(user)
|
||||
.flatMap(
|
||||
(userDbo) => TaskEither.tryCatch(
|
||||
() async {
|
||||
// Führe das Update durch
|
||||
if (userDbo.id == null) {
|
||||
throw Exception('User ID is required');
|
||||
}
|
||||
|
||||
final updatedUser = await prisma.userDbo.update(
|
||||
data: PrismaUnion.$1(userDbo),
|
||||
where: UserDboWhereUniqueInput(id: user.id),
|
||||
);
|
||||
|
||||
return updatedUser;
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to update user: ${error.toString()}',
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(
|
||||
AppError.notFound(
|
||||
'User not found',
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(mapper.from);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, User> delete(String id) {
|
||||
return TaskEither<IError, UserDbo?>.tryCatch(
|
||||
() async {
|
||||
return await prisma.userDbo
|
||||
.delete(where: UserDboWhereUniqueInput(id: id));
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to delete user: ${error.toString()}',
|
||||
),
|
||||
)
|
||||
.flatMap(
|
||||
errorOnNull(
|
||||
AppError.notFound(
|
||||
'User not found',
|
||||
),
|
||||
),
|
||||
)
|
||||
.flatMap(mapper.from);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, List<User>> findAll() {
|
||||
return TaskEither<IError, Iterable<UserDbo>>.tryCatch(
|
||||
() async => await prisma.userDbo.findMany(),
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to fetch all users: ${error.toString()}',
|
||||
),
|
||||
).flatMap(mapper.listFrom);
|
||||
}
|
||||
|
||||
@override
|
||||
TaskEither<IError, String> generateId() {
|
||||
return TaskEither.tryCatch(
|
||||
() async {
|
||||
var uuid = Uuid();
|
||||
do {
|
||||
final id = uuid.v4();
|
||||
final user = await prisma.userDbo.findUnique(
|
||||
where: UserDboWhereUniqueInput(id: id),
|
||||
);
|
||||
if (user == null) return id;
|
||||
} while (true);
|
||||
},
|
||||
(error, _) => AppError.databaseError(
|
||||
message: 'Failed to generate ID: ${error.toString()}',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user