completed go backend
This commit is contained in:
@@ -6,7 +6,7 @@ import (
|
||||
E "github.com/IBM/fp-go/either"
|
||||
)
|
||||
|
||||
// curried delegiert eine Methode mit Kontext und gibt eine Funktion zurück.
|
||||
// curried is a helper function to simplify currying by taking a context and returning a function.
|
||||
func curried[T any, R any](ctx context.Context, fn func(context.Context, T) E.Either[error, R]) func(T) E.Either[error, R] {
|
||||
return func(input T) E.Either[error, R] {
|
||||
return fn(ctx, input)
|
||||
|
||||
@@ -20,28 +20,28 @@ func NewProjectRepository(dataSource data.ProjectDataSource) repository.ProjectR
|
||||
}
|
||||
|
||||
// Create delegates the creation of a project to the data source.
|
||||
func (r *ProjectRepositoryImpl) Create(ctx context.Context, project entities.ProjectCreate) E.Either[error, entities.Project] {
|
||||
return r.dataSource.Create(ctx, project)
|
||||
func (r *ProjectRepositoryImpl) Create(ctx context.Context) func(project entities.ProjectCreate) E.Either[error, entities.Project] {
|
||||
return curried(ctx, r.dataSource.Create)
|
||||
}
|
||||
|
||||
// FindByID delegates fetching a project by ID to the data source.
|
||||
func (r *ProjectRepositoryImpl) FindByID(ctx context.Context, id string) E.Either[error, entities.Project] {
|
||||
return r.dataSource.FindByID(ctx, id)
|
||||
func (r *ProjectRepositoryImpl) FindByID(ctx context.Context) func(id string) E.Either[error, entities.Project] {
|
||||
return curried(ctx, r.dataSource.FindByID)
|
||||
}
|
||||
|
||||
// FindByUserID delegates fetching all projects for a user to the data source.
|
||||
func (r *ProjectRepositoryImpl) FindByUserID(ctx context.Context, userID string) E.Either[error, []entities.Project] {
|
||||
return r.dataSource.FindByUserID(ctx, userID)
|
||||
// FindByUserID delegates fetching projects by user ID to the data source.
|
||||
func (r *ProjectRepositoryImpl) FindByUserID(ctx context.Context) func(userID string) E.Either[error, []entities.Project] {
|
||||
return curried(ctx, r.dataSource.FindByUserID)
|
||||
}
|
||||
|
||||
// Update delegates updating a project to the data source.
|
||||
func (r *ProjectRepositoryImpl) Update(ctx context.Context, project entities.ProjectUpdate) E.Either[error, entities.Project] {
|
||||
return r.dataSource.Update(ctx, project)
|
||||
func (r *ProjectRepositoryImpl) Update(ctx context.Context) func(project entities.ProjectUpdate) E.Either[error, entities.Project] {
|
||||
return curried(ctx, r.dataSource.Update)
|
||||
}
|
||||
|
||||
// Delete delegates deleting a project to the data source.
|
||||
func (r *ProjectRepositoryImpl) Delete(ctx context.Context, id string) E.Either[error, entities.Project] {
|
||||
return r.dataSource.Delete(ctx, id)
|
||||
func (r *ProjectRepositoryImpl) Delete(ctx context.Context) func(id string) E.Either[error, entities.Project] {
|
||||
return curried(ctx, r.dataSource.Delete)
|
||||
}
|
||||
|
||||
// FindAll delegates fetching all projects to the data source.
|
||||
|
||||
@@ -13,33 +13,35 @@ import (
|
||||
type ProjectTaskRepositoryImpl struct {
|
||||
dataSource data.ProjectTaskDataSource
|
||||
}
|
||||
|
||||
// NewProjectTaskRepository creates a new instance of ProjectTaskRepositoryImpl.
|
||||
func NewProjectTaskRepository(dataSource data.ProjectTaskDataSource) repository.ProjectTaskRepository {
|
||||
return &ProjectTaskRepositoryImpl{dataSource: dataSource}
|
||||
}
|
||||
// FindByProjectID implements repository.ProjectTaskRepository.
|
||||
func (r *ProjectTaskRepositoryImpl) FindByProjectID(ctx context.Context, projectID string) E.Either[error, []entities.ProjectTask] {
|
||||
return r.dataSource.FindByProjectID(ctx, projectID)
|
||||
}
|
||||
|
||||
// Create delegates the creation of a project task to the data source.
|
||||
func (r *ProjectTaskRepositoryImpl) Create(ctx context.Context, task entities.ProjectTaskCreate) E.Either[error, entities.ProjectTask] {
|
||||
return r.dataSource.Create(ctx, task)
|
||||
func (r *ProjectTaskRepositoryImpl) Create(ctx context.Context) func(task entities.ProjectTaskCreate) E.Either[error, entities.ProjectTask] {
|
||||
return curried(ctx, r.dataSource.Create)
|
||||
}
|
||||
|
||||
// FindByID delegates fetching a project task by ID to the data source.
|
||||
func (r *ProjectTaskRepositoryImpl) FindByID(ctx context.Context, id string) E.Either[error, entities.ProjectTask] {
|
||||
return r.dataSource.FindByID(ctx, id)
|
||||
func (r *ProjectTaskRepositoryImpl) FindByID(ctx context.Context) func(id string) E.Either[error, entities.ProjectTask] {
|
||||
return curried(ctx, r.dataSource.FindByID)
|
||||
}
|
||||
|
||||
// FindByProjectID delegates fetching project tasks by project ID to the data source.
|
||||
func (r *ProjectTaskRepositoryImpl) FindByProjectID(ctx context.Context) func(projectID string) E.Either[error, []entities.ProjectTask] {
|
||||
return curried(ctx, r.dataSource.FindByProjectID)
|
||||
}
|
||||
|
||||
// Update delegates updating a project task to the data source.
|
||||
func (r *ProjectTaskRepositoryImpl) Update(ctx context.Context, task entities.ProjectTaskUpdate) E.Either[error, entities.ProjectTask] {
|
||||
return r.dataSource.Update(ctx, task)
|
||||
func (r *ProjectTaskRepositoryImpl) Update(ctx context.Context) func(task entities.ProjectTaskUpdate) E.Either[error, entities.ProjectTask] {
|
||||
return curried(ctx, r.dataSource.Update)
|
||||
}
|
||||
|
||||
// Delete delegates deleting a project task to the data source.
|
||||
func (r *ProjectTaskRepositoryImpl) Delete(ctx context.Context, id string) E.Either[error, entities.ProjectTask] {
|
||||
return r.dataSource.Delete(ctx, id)
|
||||
func (r *ProjectTaskRepositoryImpl) Delete(ctx context.Context) func(id string) E.Either[error, entities.ProjectTask] {
|
||||
return curried(ctx, r.dataSource.Delete)
|
||||
}
|
||||
|
||||
// FindAll delegates fetching all project tasks to the data source.
|
||||
|
||||
@@ -19,37 +19,37 @@ func NewTimeEntryRepository(dataSource data.TimeEntryDataSource) repository.Time
|
||||
return &TimeEntryRepositoryImpl{dataSource: dataSource}
|
||||
}
|
||||
|
||||
// FindByProjectID implements repository.TimeEntryRepository.
|
||||
func (r *TimeEntryRepositoryImpl) FindByProjectID(ctx context.Context, projectID string) E.Either[error, []entities.TimeEntry] {
|
||||
return r.dataSource.FindByProjectID(ctx, projectID)
|
||||
// Create delegates the creation of a TimeEntry to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) Create(ctx context.Context) func(entry entities.TimeEntryCreate) E.Either[error, entities.TimeEntry] {
|
||||
return curried(ctx, r.dataSource.Create)
|
||||
}
|
||||
|
||||
// FindByUserID implements repository.TimeEntryRepository.
|
||||
func (r *TimeEntryRepositoryImpl) FindByUserID(ctx context.Context, userID string) E.Either[error, []entities.TimeEntry] {
|
||||
return r.dataSource.FindByUserID(ctx, userID)
|
||||
// FindByID delegates fetching a TimeEntry by ID to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) FindByID(ctx context.Context) func(id string) E.Either[error, entities.TimeEntry] {
|
||||
return curried(ctx, r.dataSource.FindByID)
|
||||
}
|
||||
|
||||
// Create delegates the creation of a time entry to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) Create(ctx context.Context, entry entities.TimeEntryCreate) E.Either[error, entities.TimeEntry] {
|
||||
return r.dataSource.Create(ctx, entry)
|
||||
// FindByUserID delegates fetching TimeEntries by UserID to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) FindByUserID(ctx context.Context) func(userID string) E.Either[error, []entities.TimeEntry] {
|
||||
return curried(ctx, r.dataSource.FindByUserID)
|
||||
}
|
||||
|
||||
// FindByID delegates fetching a time entry by ID to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) FindByID(ctx context.Context, id string) E.Either[error, entities.TimeEntry] {
|
||||
return r.dataSource.FindByID(ctx, id)
|
||||
// FindByProjectID delegates fetching TimeEntries by ProjectID to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) FindByProjectID(ctx context.Context) func(projectID string) E.Either[error, []entities.TimeEntry] {
|
||||
return curried(ctx, r.dataSource.FindByProjectID)
|
||||
}
|
||||
|
||||
// Update delegates updating a time entry to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) Update(ctx context.Context, entry entities.TimeEntryUpdate) E.Either[error, entities.TimeEntry] {
|
||||
return r.dataSource.Update(ctx, entry)
|
||||
// Update delegates updating a TimeEntry to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) Update(ctx context.Context) func(entry entities.TimeEntryUpdate) E.Either[error, entities.TimeEntry] {
|
||||
return curried(ctx, r.dataSource.Update)
|
||||
}
|
||||
|
||||
// Delete delegates deleting a time entry to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) Delete(ctx context.Context, id string) E.Either[error, entities.TimeEntry] {
|
||||
return r.dataSource.Delete(ctx, id)
|
||||
// Delete delegates deleting a TimeEntry to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) Delete(ctx context.Context) func(id string) E.Either[error, entities.TimeEntry] {
|
||||
return curried(ctx, r.dataSource.Delete)
|
||||
}
|
||||
|
||||
// FindAll delegates fetching all time entries to the data source.
|
||||
// FindAll delegates fetching all TimeEntries to the data source.
|
||||
func (r *TimeEntryRepositoryImpl) FindAll(ctx context.Context) E.Either[error, []entities.TimeEntry] {
|
||||
return r.dataSource.FindAll(ctx)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package repository
|
||||
import (
|
||||
"actatempus_backend/internal/domain/data"
|
||||
"actatempus_backend/internal/domain/entities"
|
||||
"actatempus_backend/internal/domain/repository"
|
||||
"context"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
@@ -13,32 +14,37 @@ type UserRepositoryImpl struct {
|
||||
dataSource data.UserDataSource
|
||||
}
|
||||
|
||||
// Create delegiert die Erstellung eines Benutzers an die Datenquelle.
|
||||
// NewUserRepository creates a new instance of UserRepositoryImpl.
|
||||
func NewUserRepository(dataSource data.UserDataSource) repository.UserRepository {
|
||||
return &UserRepositoryImpl{dataSource: dataSource}
|
||||
}
|
||||
|
||||
// Create delegates the creation of a user to the data source.
|
||||
func (r *UserRepositoryImpl) Create(ctx context.Context) func(user entities.UserCreate) E.Either[error, entities.User] {
|
||||
return curried(ctx, r.dataSource.Create)
|
||||
}
|
||||
|
||||
// FindByID delegiert das Abrufen eines Benutzers nach ID an die Datenquelle.
|
||||
// FindByID delegates fetching a user by ID to the data source.
|
||||
func (r *UserRepositoryImpl) FindByID(ctx context.Context) func(id string) E.Either[error, entities.User] {
|
||||
return curried(ctx, r.dataSource.FindByID)
|
||||
}
|
||||
|
||||
// FindByEmail delegiert das Abrufen eines Benutzers nach E-Mail an die Datenquelle.
|
||||
// FindByEmail delegates fetching a user by email to the data source.
|
||||
func (r *UserRepositoryImpl) FindByEmail(ctx context.Context) func(email string) E.Either[error, entities.User] {
|
||||
return curried(ctx, r.dataSource.FindByEmail)
|
||||
}
|
||||
|
||||
// Update delegiert das Aktualisieren eines Benutzers an die Datenquelle.
|
||||
// Update delegates updating a user to the data source.
|
||||
func (r *UserRepositoryImpl) Update(ctx context.Context) func(user entities.UserUpdate) E.Either[error, entities.User] {
|
||||
return curried(ctx, r.dataSource.Update)
|
||||
}
|
||||
|
||||
// Delete delegiert das Löschen eines Benutzers an die Datenquelle.
|
||||
// Delete delegates deleting a user to the data source.
|
||||
func (r *UserRepositoryImpl) Delete(ctx context.Context) func(id string) E.Either[error, entities.User] {
|
||||
return curried(ctx, r.dataSource.Delete)
|
||||
}
|
||||
|
||||
// FindAll delegiert das Abrufen aller Benutzer an die Datenquelle.
|
||||
// FindAll delegates fetching all users to the data source.
|
||||
func (r *UserRepositoryImpl) FindAll(ctx context.Context) E.Either[error, []entities.User] {
|
||||
return r.dataSource.FindAll(ctx)
|
||||
}
|
||||
|
||||
@@ -1,21 +1,37 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"actatempus_backend/internal/domain/app_error"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// HandleError handles errors by formatting them as JSON.
|
||||
func HandleError(c *gin.Context) func(error) any {
|
||||
return func(err error) any {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return nil
|
||||
// Check if the error is of type *AppError
|
||||
if appErr, ok := err.(*app_error.AppError); ok {
|
||||
// Use the AppError fields for the JSON response
|
||||
c.JSON(appErr.Status, gin.H{
|
||||
"code": appErr.Code,
|
||||
"message": appErr.Message,
|
||||
"details": appErr.Err.Error(), // Original error if available
|
||||
})
|
||||
} else {
|
||||
// Fallback for non-AppError errors
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func HandleSuccess[T any](c *gin.Context, statusCode int) func(T) any {
|
||||
return func(data T) any {
|
||||
c.JSON(statusCode, data)
|
||||
return nil
|
||||
c.JSON(statusCode, data)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"actatempus_backend/internal/application/services/dto"
|
||||
mappers "actatempus_backend/internal/application/services/mapper"
|
||||
"actatempus_backend/internal/domain/repository"
|
||||
"net/http"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ProjectService handles project-related HTTP requests.
|
||||
type ProjectService struct {
|
||||
repository repository.ProjectRepository
|
||||
}
|
||||
|
||||
// NewProjectService creates a new instance of ProjectService.
|
||||
func NewProjectService(repo repository.ProjectRepository) *ProjectService {
|
||||
return &ProjectService{repository: repo}
|
||||
}
|
||||
|
||||
// RegisterRoutes registers the project-related routes with Gin.
|
||||
func (s *ProjectService) RegisterRoutes(router *gin.RouterGroup) {
|
||||
router.POST("/", s.CreateProject)
|
||||
router.GET("/:id", s.GetProjectByID)
|
||||
router.GET("/", s.GetAllProjects)
|
||||
router.PUT("/:id", s.UpdateProject)
|
||||
router.DELETE("/:id", s.DeleteProject)
|
||||
}
|
||||
|
||||
// CreateProject handles the creation of a new project.
|
||||
func (s *ProjectService) CreateProject(c *gin.Context) {
|
||||
var projectCreateDTO dto.ProjectCreateDTO
|
||||
if err := c.ShouldBindJSON(&projectCreateDTO); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
F.Pipe3(
|
||||
mappers.MapCreateDTOToProject(projectCreateDTO),
|
||||
s.repository.Create(c.Request.Context()),
|
||||
E.Map[error](mappers.MapProjectToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.ProjectDTO](c, http.StatusCreated),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// GetProjectByID handles fetching a project by its ID.
|
||||
func (s *ProjectService) GetProjectByID(c *gin.Context) {
|
||||
F.Pipe3(
|
||||
c.Param("id"),
|
||||
s.repository.FindByID(c.Request.Context()),
|
||||
E.Map[error](mappers.MapProjectToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.ProjectDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// GetAllProjects handles fetching all projects.
|
||||
func (s *ProjectService) GetAllProjects(c *gin.Context) {
|
||||
F.Pipe2(
|
||||
s.repository.FindAll(c.Request.Context()),
|
||||
E.Map[error](A.Map(mappers.MapProjectToDTO)),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[[]dto.ProjectDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// UpdateProject handles updating an existing project.
|
||||
func (s *ProjectService) UpdateProject(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var projectUpdateDTO dto.ProjectUpdateDTO
|
||||
|
||||
if err := c.ShouldBindJSON(&projectUpdateDTO); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
F.Pipe3(
|
||||
mappers.MapUpdateDTOToProject(projectUpdateDTO, id),
|
||||
s.repository.Update(c.Request.Context()),
|
||||
E.Map[error](mappers.MapProjectToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.ProjectDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// DeleteProject handles deleting a project by its ID.
|
||||
func (s *ProjectService) DeleteProject(c *gin.Context) {
|
||||
F.Pipe3(
|
||||
c.Param("id"),
|
||||
s.repository.Delete(c.Request.Context()),
|
||||
E.Map[error](mappers.MapProjectToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.ProjectDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"actatempus_backend/internal/application/services/dto"
|
||||
mappers "actatempus_backend/internal/application/services/mapper"
|
||||
"actatempus_backend/internal/domain/repository"
|
||||
"net/http"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ProjectTaskService handles project task-related HTTP requests.
|
||||
type ProjectTaskService struct {
|
||||
repository repository.ProjectTaskRepository
|
||||
}
|
||||
|
||||
// NewProjectTaskService creates a new instance of ProjectTaskService.
|
||||
func NewProjectTaskService(repo repository.ProjectTaskRepository) *ProjectTaskService {
|
||||
return &ProjectTaskService{repository: repo}
|
||||
}
|
||||
|
||||
// RegisterRoutes registers the project task-related routes with Gin.
|
||||
func (s *ProjectTaskService) RegisterRoutes(router *gin.RouterGroup) {
|
||||
router.POST("/", s.CreateTask)
|
||||
router.GET("/:id", s.GetTaskByID)
|
||||
router.GET("/", s.GetAllTasks)
|
||||
router.GET("/project/:projectID", s.GetTasksByProjectID)
|
||||
router.PUT("/:id", s.UpdateTask)
|
||||
router.DELETE("/:id", s.DeleteTask)
|
||||
}
|
||||
|
||||
// CreateTask handles the creation of a new project task.
|
||||
func (s *ProjectTaskService) CreateTask(c *gin.Context) {
|
||||
var taskCreateDTO dto.ProjectTaskCreateDTO
|
||||
if err := c.ShouldBindJSON(&taskCreateDTO); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
F.Pipe3(
|
||||
mappers.MapCreateDTOToProjectTask(taskCreateDTO),
|
||||
s.repository.Create(c.Request.Context()),
|
||||
E.Map[error](mappers.MapProjectTaskToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.ProjectTaskDTO](c, http.StatusCreated),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// GetTaskByID handles fetching a project task by its ID.
|
||||
func (s *ProjectTaskService) GetTaskByID(c *gin.Context) {
|
||||
F.Pipe3(
|
||||
c.Param("id"),
|
||||
s.repository.FindByID(c.Request.Context()),
|
||||
E.Map[error](mappers.MapProjectTaskToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.ProjectTaskDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// GetTasksByProjectID handles fetching project tasks by project ID.
|
||||
func (s *ProjectTaskService) GetTasksByProjectID(c *gin.Context) {
|
||||
F.Pipe3(
|
||||
c.Param("projectID"),
|
||||
s.repository.FindByProjectID(c.Request.Context()),
|
||||
E.Map[error](A.Map(mappers.MapProjectTaskToDTO)),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[[]dto.ProjectTaskDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// GetAllTasks handles fetching all project tasks.
|
||||
func (s *ProjectTaskService) GetAllTasks(c *gin.Context) {
|
||||
F.Pipe2(
|
||||
s.repository.FindAll(c.Request.Context()),
|
||||
E.Map[error](A.Map(mappers.MapProjectTaskToDTO)),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[[]dto.ProjectTaskDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// UpdateTask handles updating an existing project task.
|
||||
func (s *ProjectTaskService) UpdateTask(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var taskUpdateDTO dto.ProjectTaskUpdateDTO
|
||||
|
||||
if err := c.ShouldBindJSON(&taskUpdateDTO); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
F.Pipe3(
|
||||
mappers.MapUpdateDTOToProjectTask(taskUpdateDTO, id),
|
||||
s.repository.Update(c.Request.Context()),
|
||||
E.Map[error](mappers.MapProjectTaskToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.ProjectTaskDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// DeleteTask handles deleting a project task by its ID and returns the deleted object.
|
||||
func (s *ProjectTaskService) DeleteTask(c *gin.Context) {
|
||||
F.Pipe3(
|
||||
c.Param("id"),
|
||||
s.repository.Delete(c.Request.Context()),
|
||||
E.Map[error](mappers.MapProjectTaskToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.ProjectTaskDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"actatempus_backend/internal/application/services/dto"
|
||||
mappers "actatempus_backend/internal/application/services/mapper"
|
||||
"actatempus_backend/internal/domain/repository"
|
||||
"net/http"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// TimeEntryService handles time entry-related HTTP requests.
|
||||
type TimeEntryService struct {
|
||||
repository repository.TimeEntryRepository
|
||||
}
|
||||
|
||||
// NewTimeEntryService creates a new instance of TimeEntryService.
|
||||
func NewTimeEntryService(repo repository.TimeEntryRepository) *TimeEntryService {
|
||||
return &TimeEntryService{repository: repo}
|
||||
}
|
||||
|
||||
// RegisterRoutes registers the time entry-related routes with Gin.
|
||||
func (s *TimeEntryService) RegisterRoutes(router *gin.RouterGroup) {
|
||||
router.POST("/", s.CreateTimeEntry)
|
||||
router.GET("/:id", s.GetTimeEntryByID)
|
||||
router.GET("/", s.GetAllTimeEntries)
|
||||
router.GET("/user/:userID", s.GetTimeEntriesByUserID)
|
||||
router.GET("/project/:projectID", s.GetTimeEntriesByProjectID)
|
||||
router.PUT("/:id", s.UpdateTimeEntry)
|
||||
router.DELETE("/:id", s.DeleteTimeEntry)
|
||||
}
|
||||
|
||||
// CreateTimeEntry handles the creation of a new time entry.
|
||||
func (s *TimeEntryService) CreateTimeEntry(c *gin.Context) {
|
||||
var timeEntryCreateDTO dto.TimeEntryCreateDTO
|
||||
if err := c.ShouldBindJSON(&timeEntryCreateDTO); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
F.Pipe3(
|
||||
mappers.MapCreateDTOToTimeEntry(timeEntryCreateDTO),
|
||||
s.repository.Create(c.Request.Context()),
|
||||
E.Map[error](mappers.MapTimeEntryToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.TimeEntryDTO](c, http.StatusCreated),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// GetTimeEntryByID handles fetching a time entry by its ID.
|
||||
func (s *TimeEntryService) GetTimeEntryByID(c *gin.Context) {
|
||||
F.Pipe3(
|
||||
c.Param("id"),
|
||||
s.repository.FindByID(c.Request.Context()),
|
||||
E.Map[error](mappers.MapTimeEntryToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.TimeEntryDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// GetTimeEntriesByUserID handles fetching time entries by user ID.
|
||||
func (s *TimeEntryService) GetTimeEntriesByUserID(c *gin.Context) {
|
||||
F.Pipe3(
|
||||
c.Param("userID"),
|
||||
s.repository.FindByUserID(c.Request.Context()),
|
||||
E.Map[error](A.Map(mappers.MapTimeEntryToDTO)),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[[]dto.TimeEntryDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// GetTimeEntriesByProjectID handles fetching time entries by project ID.
|
||||
func (s *TimeEntryService) GetTimeEntriesByProjectID(c *gin.Context) {
|
||||
F.Pipe3(
|
||||
c.Param("projectID"),
|
||||
s.repository.FindByProjectID(c.Request.Context()),
|
||||
E.Map[error](A.Map(mappers.MapTimeEntryToDTO)),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[[]dto.TimeEntryDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// GetAllTimeEntries handles fetching all time entries.
|
||||
func (s *TimeEntryService) GetAllTimeEntries(c *gin.Context) {
|
||||
F.Pipe2(
|
||||
s.repository.FindAll(c.Request.Context()),
|
||||
E.Map[error](A.Map(mappers.MapTimeEntryToDTO)),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[[]dto.TimeEntryDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// UpdateTimeEntry handles updating an existing time entry.
|
||||
func (s *TimeEntryService) UpdateTimeEntry(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var timeEntryUpdateDTO dto.TimeEntryUpdateDTO
|
||||
|
||||
if err := c.ShouldBindJSON(&timeEntryUpdateDTO); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
F.Pipe3(
|
||||
mappers.MapUpdateDTOToTimeEntry(timeEntryUpdateDTO, id),
|
||||
s.repository.Update(c.Request.Context()),
|
||||
E.Map[error](mappers.MapTimeEntryToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.TimeEntryDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// DeleteTimeEntry handles deleting a time entry by its ID and returns the deleted object.
|
||||
func (s *TimeEntryService) DeleteTimeEntry(c *gin.Context) {
|
||||
F.Pipe3(
|
||||
c.Param("id"),
|
||||
s.repository.Delete(c.Request.Context()),
|
||||
E.Map[error](mappers.MapTimeEntryToDTO),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.TimeEntryDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user