completed go backend

This commit is contained in:
2025-01-03 16:18:25 +00:00
parent f151fa7eae
commit aca98554d0
24 changed files with 610 additions and 150 deletions
@@ -13,10 +13,9 @@ func handleDBError(err error, notFoundMessage string) error {
return app_error.NewInternalError(err)
}
func NullableField[T any](getter func() (T, bool)) *T {
if value, ok := getter(); ok {
return &value
}
return nil
}
}
@@ -38,7 +38,6 @@ func mapPrismaProjectToDomain(project db.ProjectDboModel) entities.Project {
}
}
func mapPrismaProjectsToDomain(projects []db.ProjectDboModel) []entities.Project {
domainProjects := make([]entities.Project, len(projects))
for i, project := range projects {
@@ -49,14 +48,14 @@ func mapPrismaProjectsToDomain(projects []db.ProjectDboModel) []entities.Project
func mapPrismaTimeEntryToDomain(timeEntry db.TimeEntryDboModel) entities.TimeEntry {
return entities.TimeEntry{
ID: timeEntry.ID,
ProjectID: timeEntry.ProjectID,
UserID: timeEntry.UserID,
StartTime: timeEntry.StartTime,
EndTime: NullableField(timeEntry.EndTime),
ID: timeEntry.ID,
ProjectID: timeEntry.ProjectID,
UserID: timeEntry.UserID,
StartTime: timeEntry.StartTime,
EndTime: NullableField(timeEntry.EndTime),
Description: NullableField(timeEntry.Description),
CreatedAt: timeEntry.CreatedAt,
UpdatedAt: timeEntry.UpdatedAt,
CreatedAt: timeEntry.CreatedAt,
UpdatedAt: timeEntry.UpdatedAt,
}
}
@@ -70,12 +69,12 @@ func mapPrismaTimeEntriesToDomain(timeEntries []db.TimeEntryDboModel) []entities
func mapPrismaProjectTaskToDomain(projectTask db.ProjectTaskDboModel) entities.ProjectTask {
return entities.ProjectTask{
ID: projectTask.ID,
ProjectID: projectTask.ProjectID,
Name: projectTask.Name,
ID: projectTask.ID,
ProjectID: projectTask.ProjectID,
Name: projectTask.Name,
Description: NullableField(projectTask.Description),
CreatedAt: projectTask.CreatedAt,
UpdatedAt: projectTask.UpdatedAt,
CreatedAt: projectTask.CreatedAt,
UpdatedAt: projectTask.UpdatedAt,
}
}
@@ -85,4 +84,4 @@ func mapPrismaProjectTasksToDomain(projectTasks []db.ProjectTaskDboModel) []enti
domainProjectTasks[i] = mapPrismaProjectTaskToDomain(projectTask)
}
return domainProjectTasks
}
}
@@ -62,5 +62,5 @@ func (db *PrismaDatabase) Projects() data.ProjectDataSource {
// Close releases the Prisma client connection.
func (db *PrismaDatabase) Close(ctx context.Context) error {
log.Println("Closing database connection")
return db.client.Disconnect();
return db.client.Disconnect()
}
@@ -25,17 +25,16 @@ func (ds *PrismaProjectDataSource) Create(ctx context.Context, project entities.
db.ProjectDbo.User.Link(
db.UserDbo.ID.Equals(project.UserID),
),
db.ProjectDbo.UserID.Set(project.UserID),
db.ProjectDbo.Description.SetIfPresent(project.Description),
db.ProjectDbo.ClientID.SetIfPresent(project.ClientID),
).Exec(ctx)
if err != nil {
return E.Left[entities.Project,error](app_error.NewInternalError(err))
return E.Left[entities.Project, error](app_error.NewInternalError(err))
}
if createdProject == nil {
return E.Left[entities.Project,error](app_error.NewInternalError(fmt.Errorf("Could not create project")))
return E.Left[entities.Project, error](app_error.NewInternalError(fmt.Errorf("Could not create project")))
}
return E.Right[error](mapPrismaProjectToDomain(*createdProject))
@@ -52,7 +51,7 @@ func (ds *PrismaProjectDataSource) FindByID(ctx context.Context, id string) E.Ei
}
if project == nil {
return E.Left[entities.Project,error](app_error.NewNotFoundError(fmt.Sprintf("Project with ID %s not found", id)))
return E.Left[entities.Project, error](app_error.NewNotFoundError(fmt.Sprintf("Project with ID %s not found", id)))
}
return E.Right[error](mapPrismaProjectToDomain(*project))
@@ -77,7 +76,7 @@ func (ds *PrismaProjectDataSource) Update(ctx context.Context, project entities.
}
if updatedProject == nil {
return E.Left[entities.Project,error](app_error.NewNotFoundError(fmt.Sprintf("Project with ID %s not found", project.ID)))
return E.Left[entities.Project, error](app_error.NewNotFoundError(fmt.Sprintf("Project with ID %s not found", project.ID)))
}
return E.Right[error](mapPrismaProjectToDomain(*updatedProject))
@@ -94,7 +93,7 @@ func (ds *PrismaProjectDataSource) Delete(ctx context.Context, id string) E.Eith
}
if deleted == nil {
return E.Left[entities.Project,error](app_error.NewNotFoundError(fmt.Sprintf("Project with ID %s not found", id)))
return E.Left[entities.Project, error](app_error.NewNotFoundError(fmt.Sprintf("Project with ID %s not found", id)))
}
return E.Right[error](mapPrismaProjectToDomain(*deleted))
@@ -120,4 +119,4 @@ func (ds *PrismaProjectDataSource) FindByUserID(ctx context.Context, userID stri
}
return E.Right[error](mapPrismaProjectsToDomain(projects))
}
}
@@ -29,11 +29,11 @@ func (ds *PrismaProjectTaskDataSource) Create(ctx context.Context, task entities
).Exec(ctx)
if err != nil {
return E.Left[entities.ProjectTask,error](handleDBError(err, fmt.Sprintf("Could not create project task")))
return E.Left[entities.ProjectTask, error](handleDBError(err, fmt.Sprintf("Could not create project task")))
}
if createdTask == nil {
return E.Left[entities.ProjectTask,error](app_error.NewInternalError(fmt.Errorf("Could not create project task")))
return E.Left[entities.ProjectTask, error](app_error.NewInternalError(fmt.Errorf("Could not create project task")))
}
return E.Right[error](mapPrismaProjectTaskToDomain(*createdTask))
@@ -50,7 +50,7 @@ func (ds *PrismaProjectTaskDataSource) FindByID(ctx context.Context, id string)
}
if task == nil {
return E.Left[entities.ProjectTask,error](app_error.NewNotFoundError(fmt.Sprintf("ProjectTask with ID %s not found", id)))
return E.Left[entities.ProjectTask, error](app_error.NewNotFoundError(fmt.Sprintf("ProjectTask with ID %s not found", id)))
}
return E.Right[error](mapPrismaProjectTaskToDomain(*task))
@@ -73,7 +73,7 @@ func (ds *PrismaProjectTaskDataSource) Update(ctx context.Context, task entities
}
if updatedTask == nil {
return E.Left[entities.ProjectTask,error](app_error.NewNotFoundError(fmt.Sprintf("ProjectTask with ID %s not found", task.ID)))
return E.Left[entities.ProjectTask, error](app_error.NewNotFoundError(fmt.Sprintf("ProjectTask with ID %s not found", task.ID)))
}
return E.Right[error](mapPrismaProjectTaskToDomain(*updatedTask))
@@ -90,7 +90,7 @@ func (ds *PrismaProjectTaskDataSource) Delete(ctx context.Context, id string) E.
}
if deletedTask == nil {
return E.Left[entities.ProjectTask,error](app_error.NewNotFoundError(fmt.Sprintf("ProjectTask with ID %s not found", id)))
return E.Left[entities.ProjectTask, error](app_error.NewNotFoundError(fmt.Sprintf("ProjectTask with ID %s not found", id)))
}
return E.Right[error](mapPrismaProjectTaskToDomain(*deletedTask))
@@ -116,4 +116,4 @@ func (ds *PrismaProjectTaskDataSource) FindByProjectID(ctx context.Context, proj
}
return E.Right[error](mapPrismaProjectTasksToDomain(tasks))
}
}
@@ -24,20 +24,19 @@ func (ds *PrismaTimeEntryDataSource) Create(ctx context.Context, entry entities.
db.TimeEntryDbo.StartTime.Set(entry.StartTime),
db.TimeEntryDbo.User.Link(
db.UserDbo.ID.Equals(entry.UserID),
), db.TimeEntryDbo.Project.Link(
), db.TimeEntryDbo.Project.Link(
db.ProjectDbo.ID.Equals(entry.ProjectID),
),
db.TimeEntryDbo.EndTime.SetIfPresent(entry.EndTime),
db.TimeEntryDbo.Description.SetIfPresent(entry.Description),
).Exec(ctx)
if err != nil {
return E.Left[entities.TimeEntry,error](app_error.NewInternalError(err))
return E.Left[entities.TimeEntry, error](app_error.NewInternalError(err))
}
if createdEntry == nil {
return E.Left[entities.TimeEntry,error](app_error.NewInternalError(fmt.Errorf("Could not create time entry")))
return E.Left[entities.TimeEntry, error](app_error.NewInternalError(fmt.Errorf("Could not create time entry")))
}
return E.Right[error](mapPrismaTimeEntryToDomain(*createdEntry))
@@ -54,7 +53,7 @@ func (ds *PrismaTimeEntryDataSource) FindByID(ctx context.Context, id string) E.
}
if entry == nil {
return E.Left[entities.TimeEntry,error](app_error.NewNotFoundError(fmt.Sprintf("TimeEntry with ID %s not found", id)))
return E.Left[entities.TimeEntry, error](app_error.NewNotFoundError(fmt.Sprintf("TimeEntry with ID %s not found", id)))
}
return E.Right[error](mapPrismaTimeEntryToDomain(*entry))
@@ -77,11 +76,11 @@ func (ds *PrismaTimeEntryDataSource) Update(ctx context.Context, entry entities.
).Exec(ctx)
if err != nil {
return E.Left[entities.TimeEntry,error](handleDBError(err, fmt.Sprintf("Could not update time entry with ID %s", entry.ID)))
return E.Left[entities.TimeEntry, error](handleDBError(err, fmt.Sprintf("Could not update time entry with ID %s", entry.ID)))
}
if updatedEntry == nil {
return E.Left[entities.TimeEntry,error](app_error.NewNotFoundError(fmt.Sprintf("TimeEntry with ID %s not found", entry.ID)))
return E.Left[entities.TimeEntry, error](app_error.NewNotFoundError(fmt.Sprintf("TimeEntry with ID %s not found", entry.ID)))
}
return E.Right[error](mapPrismaTimeEntryToDomain(*updatedEntry))
@@ -98,7 +97,7 @@ func (ds *PrismaTimeEntryDataSource) Delete(ctx context.Context, id string) E.Ei
}
if deletedEntry == nil {
return E.Left[entities.TimeEntry,error](app_error.NewNotFoundError(fmt.Sprintf("TimeEntry with ID %s not found", id)))
return E.Left[entities.TimeEntry, error](app_error.NewNotFoundError(fmt.Sprintf("TimeEntry with ID %s not found", id)))
}
return E.Right[error](mapPrismaTimeEntryToDomain(*deletedEntry))
@@ -126,7 +125,6 @@ func (ds *PrismaTimeEntryDataSource) FindByUserID(ctx context.Context, userID st
return E.Right[error](mapPrismaTimeEntriesToDomain(entries))
}
// FindByProjectID retrieves all TimeEntries by ProjectID
func (ds *PrismaTimeEntryDataSource) FindByProjectID(ctx context.Context, projectID string) E.Either[error, []entities.TimeEntry] {
entries, err := ds.client.TimeEntryDbo.FindMany(
@@ -137,4 +135,4 @@ func (ds *PrismaTimeEntryDataSource) FindByProjectID(ctx context.Context, projec
}
return E.Right[error](mapPrismaTimeEntriesToDomain(entries))
}
}
@@ -18,7 +18,7 @@ func NewPrismaUserDataSource(client *db.PrismaClient) *PrismaUserDataSource {
return &PrismaUserDataSource{client: client}
}
func (ds *PrismaUserDataSource) Create(ctx context.Context, user entities.UserCreate) E.Either[error,entities.User] {
func (ds *PrismaUserDataSource) Create(ctx context.Context, user entities.UserCreate) E.Either[error, entities.User] {
createdUser, err := ds.client.UserDbo.CreateOne(
db.UserDbo.Name.Set(user.Name),
db.UserDbo.Email.Set(user.Email),
@@ -26,48 +26,48 @@ func (ds *PrismaUserDataSource) Create(ctx context.Context, user entities.UserCr
).Exec(ctx)
if err != nil {
return E.Left[entities.User,error](app_error.NewInternalError(err))
return E.Left[entities.User, error](app_error.NewInternalError(err))
}
if createdUser == nil {
return E.Left[entities.User,error](app_error.NewInternalError(fmt.Errorf("Could not create user")))
return E.Left[entities.User, error](app_error.NewInternalError(fmt.Errorf("Could not create user")))
}
return E.Right[error](mapPrismaUserToDomain(*createdUser))
}
func (ds *PrismaUserDataSource) FindByID(ctx context.Context, id string) E.Either[error,entities.User] {
func (ds *PrismaUserDataSource) FindByID(ctx context.Context, id string) E.Either[error, entities.User] {
user, err := ds.client.UserDbo.FindUnique(
db.UserDbo.ID.Equals(id),
).Exec(ctx)
if err != nil {
return E.Left[entities.User,error](handleDBError(err, fmt.Sprintf("Query for user with ID %s failed", id)))
return E.Left[entities.User, error](handleDBError(err, fmt.Sprintf("Query for user with ID %s failed", id)))
}
if user == nil {
return E.Left[entities.User,error](app_error.NewNotFoundError(fmt.Sprintf("User with ID %s not found", id)))
return E.Left[entities.User, error](app_error.NewNotFoundError(fmt.Sprintf("User with ID %s not found", id)))
}
return E.Right[error](mapPrismaUserToDomain(*user))
}
func (ds *PrismaUserDataSource) FindByEmail(ctx context.Context, email string) E.Either[error,entities.User]{
func (ds *PrismaUserDataSource) FindByEmail(ctx context.Context, email string) E.Either[error, entities.User] {
user, err := ds.client.UserDbo.FindUnique(
db.UserDbo.Email.Equals(email),
).Exec(ctx)
if err != nil {
return E.Left[entities.User,error](handleDBError(err, fmt.Sprintf("Query for user with email %s failed", email)))
return E.Left[entities.User, error](handleDBError(err, fmt.Sprintf("Query for user with email %s failed", email)))
}
if user == nil {
return E.Left[entities.User,error](app_error.NewNotFoundError(fmt.Sprintf("User with email %s not found", email)))
return E.Left[entities.User, error](app_error.NewNotFoundError(fmt.Sprintf("User with email %s not found", email)))
}
return E.Right[error](mapPrismaUserToDomain(*user))
}
func (ds *PrismaUserDataSource) Update(ctx context.Context, user entities.UserUpdate) E.Either[error,entities.User] {
func (ds *PrismaUserDataSource) Update(ctx context.Context, user entities.UserUpdate) E.Either[error, entities.User] {
updatedUser, err := ds.client.UserDbo.FindUnique(
db.UserDbo.ID.Equals(user.ID),
@@ -78,37 +78,36 @@ func (ds *PrismaUserDataSource) Update(ctx context.Context, user entities.UserUp
).Exec(ctx)
if err != nil {
return E.Left[entities.User,error](handleDBError(err, fmt.Sprintf("Could not update user with ID %s", user.ID)))
return E.Left[entities.User, error](handleDBError(err, fmt.Sprintf("Could not update user with ID %s", user.ID)))
}
if updatedUser == nil {
return E.Left[entities.User,error](app_error.NewNotFoundError(fmt.Sprintf("User with ID %s not found", user.ID)))
return E.Left[entities.User, error](app_error.NewNotFoundError(fmt.Sprintf("User with ID %s not found", user.ID)))
}
return E.Right[error](mapPrismaUserToDomain(*updatedUser))
}
func (ds *PrismaUserDataSource) Delete(ctx context.Context, id string) E.Either[error,entities.User] {
func (ds *PrismaUserDataSource) Delete(ctx context.Context, id string) E.Either[error, entities.User] {
deleted, err := ds.client.UserDbo.FindUnique(
db.UserDbo.ID.Equals(id),
).Delete().Exec(ctx)
if err != nil {
return E.Left[entities.User,error](handleDBError(err, fmt.Sprintf("Could not delete user with ID %s", id)))
return E.Left[entities.User, error](handleDBError(err, fmt.Sprintf("Could not delete user with ID %s", id)))
}
if deleted == nil {
return E.Left[entities.User,error](app_error.NewNotFoundError(fmt.Sprintf("User with ID %s not found", id)))
return E.Left[entities.User, error](app_error.NewNotFoundError(fmt.Sprintf("User with ID %s not found", id)))
}
return E.Right[error](mapPrismaUserToDomain(*deleted))
}
func (ds *PrismaUserDataSource) FindAll(ctx context.Context) E.Either[error,[]entities.User] {
func (ds *PrismaUserDataSource) FindAll(ctx context.Context) E.Either[error, []entities.User] {
users, err := ds.client.UserDbo.FindMany().Exec(ctx)
if err != nil {
return E.Left[[]entities.User,error](handleDBError(err, "Could not retrieve users"))
return E.Left[[]entities.User, error](handleDBError(err, "Could not retrieve users"))
}
return E.Right[error](mapPrismaUsersToDomain(users))