From 58173b436c36d8d24bf057f40b408e913f7b0cf3 Mon Sep 17 00:00:00 2001 From: Jean Jacques Avril Date: Mon, 10 Mar 2025 21:43:45 +0000 Subject: [PATCH] refactor: Update DTOs to use string type for IDs and enhance API documentation for activity and user handlers --- .../internal/api/handlers/activity_handler.go | 12 +++- backend/internal/api/handlers/user_handler.go | 14 ++++- backend/internal/api/utils/swagger.go | 60 +------------------ backend/internal/dtos/activity_dto.go | 10 ++-- backend/internal/dtos/company_dto.go | 10 ++-- backend/internal/dtos/customer_dto.go | 10 ++-- backend/internal/dtos/project_dto.go | 10 ++-- backend/internal/dtos/timeentry_dto.go | 10 ++-- backend/internal/dtos/user_dto.go | 10 ++-- 9 files changed, 46 insertions(+), 100 deletions(-) diff --git a/backend/internal/api/handlers/activity_handler.go b/backend/internal/api/handlers/activity_handler.go index 07e4171..a30e220 100644 --- a/backend/internal/api/handlers/activity_handler.go +++ b/backend/internal/api/handlers/activity_handler.go @@ -19,6 +19,7 @@ func NewActivityHandler() *ActivityHandler { } // GetActivities handles GET /activities +// // @Summary Get all activities // @Description Get a list of all activities // @Tags activities @@ -47,6 +48,7 @@ func (h *ActivityHandler) GetActivities(c *gin.Context) { } // GetActivityByID handles GET /activities/:id +// // @Summary Get activity by ID // @Description Get an activity by its ID // @Tags activities @@ -88,6 +90,7 @@ func (h *ActivityHandler) GetActivityByID(c *gin.Context) { } // CreateActivity handles POST /activities +// // @Summary Create a new activity // @Description Create a new activity // @Tags activities @@ -125,6 +128,7 @@ func (h *ActivityHandler) CreateActivity(c *gin.Context) { } // UpdateActivity handles PUT /activities/:id +// // @Summary Update an activity // @Description Update an existing activity // @Tags activities @@ -156,7 +160,7 @@ func (h *ActivityHandler) UpdateActivity(c *gin.Context) { } // Set ID from URL - activityUpdateDTO.ID = id + activityUpdateDTO.ID = id.String() // Convert DTO to model activityUpdate := convertUpdateActivityDTOToModel(activityUpdateDTO) @@ -180,6 +184,7 @@ func (h *ActivityHandler) UpdateActivity(c *gin.Context) { } // DeleteActivity handles DELETE /activities/:id +// // @Summary Delete an activity // @Description Delete an activity by its ID // @Tags activities @@ -215,7 +220,7 @@ func (h *ActivityHandler) DeleteActivity(c *gin.Context) { func convertActivityToDTO(activity *models.Activity) dto.ActivityDto { return dto.ActivityDto{ - ID: activity.ID, + ID: activity.ID.String(), CreatedAt: activity.CreatedAt, UpdatedAt: activity.UpdatedAt, Name: activity.Name, @@ -231,8 +236,9 @@ func convertCreateActivityDTOToModel(dto dto.ActivityCreateDto) models.ActivityC } func convertUpdateActivityDTOToModel(dto dto.ActivityUpdateDto) models.ActivityUpdate { + id, _ := ulid.Parse(dto.ID) update := models.ActivityUpdate{ - ID: dto.ID, + ID: id, } if dto.Name != nil { diff --git a/backend/internal/api/handlers/user_handler.go b/backend/internal/api/handlers/user_handler.go index a1acc35..2647543 100644 --- a/backend/internal/api/handlers/user_handler.go +++ b/backend/internal/api/handlers/user_handler.go @@ -20,6 +20,7 @@ func NewUserHandler() *UserHandler { } // GetUsers handles GET /users +// // @Summary Get all users // @Description Get a list of all users // @Tags users @@ -48,6 +49,7 @@ func (h *UserHandler) GetUsers(c *gin.Context) { } // GetUserByID handles GET /users/:id +// // @Summary Get user by ID // @Description Get a user by their ID // @Tags users @@ -89,6 +91,7 @@ func (h *UserHandler) GetUserByID(c *gin.Context) { } // CreateUser handles POST /users +// // @Summary Create a new user // @Description Create a new user // @Tags users @@ -126,6 +129,7 @@ func (h *UserHandler) CreateUser(c *gin.Context) { } // UpdateUser handles PUT /users/:id +// // @Summary Update a user // @Description Update an existing user // @Tags users @@ -157,7 +161,7 @@ func (h *UserHandler) UpdateUser(c *gin.Context) { } // Set ID from URL - userUpdateDTO.ID = id + userUpdateDTO.ID = id.String() // Convert DTO to model userUpdate := convertUpdateDTOToModel(userUpdateDTO) @@ -181,6 +185,7 @@ func (h *UserHandler) UpdateUser(c *gin.Context) { } // DeleteUser handles DELETE /users/:id +// // @Summary Delete a user // @Description Delete a user by their ID // @Tags users @@ -213,6 +218,7 @@ func (h *UserHandler) DeleteUser(c *gin.Context) { } // Login handles POST /auth/login +// // @Summary Login // @Description Authenticate a user and get a JWT token // @Tags auth @@ -256,6 +262,7 @@ func (h *UserHandler) Login(c *gin.Context) { } // GetCurrentUser handles GET /auth/me +// // @Summary Get current user // @Description Get the currently authenticated user // @Tags auth @@ -296,7 +303,7 @@ func (h *UserHandler) GetCurrentUser(c *gin.Context) { func convertUserToDTO(user *models.User) dto.UserDto { return dto.UserDto{ - ID: user.ID, + ID: user.ID.String(), CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, Email: user.Email, @@ -320,8 +327,9 @@ func convertCreateDTOToModel(dto dto.UserCreateDto) models.UserCreate { } func convertUpdateDTOToModel(dto dto.UserUpdateDto) models.UserUpdate { + id, _ := ulid.Parse(dto.ID) update := models.UserUpdate{ - ID: dto.ID, + ID: id, } if dto.Email != nil { diff --git a/backend/internal/api/utils/swagger.go b/backend/internal/api/utils/swagger.go index d9a721c..2c11699 100644 --- a/backend/internal/api/utils/swagger.go +++ b/backend/internal/api/utils/swagger.go @@ -2,62 +2,6 @@ package utils // This file contains type definitions for Swagger documentation -// SwaggerULID is a string representation of ULID for Swagger -type SwaggerULID string - -// SwaggerTime is a string representation of time.Time for Swagger -type SwaggerTime string - -// ActivityResponse is a Swagger representation of ActivityDto -type ActivityResponse struct { - ID SwaggerULID `json:"id" example:"01H1VECTJQXS1RVWJT6QG3QJCJ"` - CreatedAt SwaggerTime `json:"createdAt" example:"2023-01-01T12:00:00Z"` - UpdatedAt SwaggerTime `json:"updatedAt" example:"2023-01-01T12:00:00Z"` - Name string `json:"name" example:"Development"` - BillingRate float64 `json:"billingRate" example:"100.0"` -} - -// UserResponse is a Swagger representation of UserDto -type UserResponse struct { - ID SwaggerULID `json:"id" example:"01H1VECTJQXS1RVWJT6QG3QJCJ"` - CreatedAt SwaggerTime `json:"createdAt" example:"2023-01-01T12:00:00Z"` - UpdatedAt SwaggerTime `json:"updatedAt" example:"2023-01-01T12:00:00Z"` - Email string `json:"email" example:"user@example.com"` - Role string `json:"role" example:"admin"` - CompanyID int `json:"companyId" example:"1"` - HourlyRate float64 `json:"hourlyRate" example:"50.0"` -} - -// ActivityCreateRequest is a Swagger representation of ActivityCreateDto -type ActivityCreateRequest struct { - Name string `json:"name" example:"Development"` - BillingRate float64 `json:"billingRate" example:"100.0"` -} - -// ActivityUpdateRequest is a Swagger representation of ActivityUpdateDto -type ActivityUpdateRequest struct { - Name *string `json:"name,omitempty" example:"Development"` - BillingRate *float64 `json:"billingRate,omitempty" example:"100.0"` -} - -// UserCreateRequest is a Swagger representation of UserCreateDto -type UserCreateRequest struct { - Email string `json:"email" example:"user@example.com"` - Password string `json:"password" example:"SecurePassword123!"` - Role string `json:"role" example:"admin"` - CompanyID int `json:"companyId" example:"1"` - HourlyRate float64 `json:"hourlyRate" example:"50.0"` -} - -// UserUpdateRequest is a Swagger representation of UserUpdateDto -type UserUpdateRequest struct { - Email *string `json:"email,omitempty" example:"user@example.com"` - Password *string `json:"password,omitempty" example:"SecurePassword123!"` - Role *string `json:"role,omitempty" example:"admin"` - CompanyID *int `json:"companyId,omitempty" example:"1"` - HourlyRate *float64 `json:"hourlyRate,omitempty" example:"50.0"` -} - // LoginRequest is a Swagger representation of LoginDto type LoginRequest struct { Email string `json:"email" example:"user@example.com"` @@ -66,6 +10,6 @@ type LoginRequest struct { // TokenResponse is a Swagger representation of TokenDto type TokenResponse struct { - Token string `json:"token" example:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."` - User UserResponse `json:"user"` + Token string `json:"token" example:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."` + User dto.UserDto `json:"user"` } diff --git a/backend/internal/dtos/activity_dto.go b/backend/internal/dtos/activity_dto.go index c743991..93c0be2 100644 --- a/backend/internal/dtos/activity_dto.go +++ b/backend/internal/dtos/activity_dto.go @@ -2,15 +2,13 @@ package dto import ( "time" - - "github.com/oklog/ulid/v2" ) type ActivityDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` - LastEditorID ulid.ULID `json:"lastEditorID"` + LastEditorID string `json:"lastEditorID"` Name string `json:"name"` BillingRate float64 `json:"billingRate"` } @@ -21,10 +19,10 @@ type ActivityCreateDto struct { } type ActivityUpdateDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt *time.Time `json:"createdAt"` UpdatedAt *time.Time `json:"updatedAt"` - LastEditorID *ulid.ULID `json:"lastEditorID"` + LastEditorID *string `json:"lastEditorID"` Name *string `json:"name"` BillingRate *float64 `json:"billingRate"` } diff --git a/backend/internal/dtos/company_dto.go b/backend/internal/dtos/company_dto.go index 28f9991..6dea5a1 100644 --- a/backend/internal/dtos/company_dto.go +++ b/backend/internal/dtos/company_dto.go @@ -2,15 +2,13 @@ package dto import ( "time" - - "github.com/oklog/ulid/v2" ) type CompanyDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` - LastEditorID ulid.ULID `json:"lastEditorID"` + LastEditorID string `json:"lastEditorID"` Name string `json:"name"` } @@ -19,9 +17,9 @@ type CompanyCreateDto struct { } type CompanyUpdateDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt *time.Time `json:"createdAt"` UpdatedAt *time.Time `json:"updatedAt"` - LastEditorID *ulid.ULID `json:"lastEditorID"` + LastEditorID *string `json:"lastEditorID"` Name *string `json:"name"` } diff --git a/backend/internal/dtos/customer_dto.go b/backend/internal/dtos/customer_dto.go index 958d907..6fd5686 100644 --- a/backend/internal/dtos/customer_dto.go +++ b/backend/internal/dtos/customer_dto.go @@ -2,15 +2,13 @@ package dto import ( "time" - - "github.com/oklog/ulid/v2" ) type CustomerDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` - LastEditorID ulid.ULID `json:"lastEditorID"` + LastEditorID string `json:"lastEditorID"` Name string `json:"name"` CompanyID int `json:"companyId"` } @@ -21,10 +19,10 @@ type CustomerCreateDto struct { } type CustomerUpdateDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt *time.Time `json:"createdAt"` UpdatedAt *time.Time `json:"updatedAt"` - LastEditorID *ulid.ULID `json:"lastEditorID"` + LastEditorID *string `json:"lastEditorID"` Name *string `json:"name"` CompanyID *int `json:"companyId"` } diff --git a/backend/internal/dtos/project_dto.go b/backend/internal/dtos/project_dto.go index 30805a6..820dc79 100644 --- a/backend/internal/dtos/project_dto.go +++ b/backend/internal/dtos/project_dto.go @@ -2,15 +2,13 @@ package dto import ( "time" - - "github.com/oklog/ulid/v2" ) type ProjectDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` - LastEditorID ulid.ULID `json:"lastEditorID"` + LastEditorID string `json:"lastEditorID"` Name string `json:"name"` CustomerID int `json:"customerId"` } @@ -21,10 +19,10 @@ type ProjectCreateDto struct { } type ProjectUpdateDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt *time.Time `json:"createdAt"` UpdatedAt *time.Time `json:"updatedAt"` - LastEditorID *ulid.ULID `json:"lastEditorID"` + LastEditorID *string `json:"lastEditorID"` Name *string `json:"name"` CustomerID *int `json:"customerId"` } diff --git a/backend/internal/dtos/timeentry_dto.go b/backend/internal/dtos/timeentry_dto.go index 3d780e0..2497ce8 100644 --- a/backend/internal/dtos/timeentry_dto.go +++ b/backend/internal/dtos/timeentry_dto.go @@ -2,15 +2,13 @@ package dto import ( "time" - - "github.com/oklog/ulid/v2" ) type TimeEntryDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` - LastEditorID ulid.ULID `json:"lastEditorID"` + LastEditorID string `json:"lastEditorID"` UserID int `json:"userId"` ProjectID int `json:"projectId"` ActivityID int `json:"activityId"` @@ -31,10 +29,10 @@ type TimeEntryCreateDto struct { } type TimeEntryUpdateDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt *time.Time `json:"createdAt"` UpdatedAt *time.Time `json:"updatedAt"` - LastEditorID *ulid.ULID `json:"lastEditorID"` + LastEditorID *string `json:"lastEditorID"` UserID *int `json:"userId"` ProjectID *int `json:"projectId"` ActivityID *int `json:"activityId"` diff --git a/backend/internal/dtos/user_dto.go b/backend/internal/dtos/user_dto.go index aeba5cc..4327a5e 100644 --- a/backend/internal/dtos/user_dto.go +++ b/backend/internal/dtos/user_dto.go @@ -2,15 +2,13 @@ package dto import ( "time" - - "github.com/oklog/ulid/v2" ) type UserDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` - LastEditorID ulid.ULID `json:"lastEditorID"` + LastEditorID string `json:"lastEditorID"` Email string `json:"email"` Role string `json:"role"` CompanyID int `json:"companyId"` @@ -26,10 +24,10 @@ type UserCreateDto struct { } type UserUpdateDto struct { - ID ulid.ULID `json:"id"` + ID string `json:"id"` CreatedAt *time.Time `json:"createdAt"` UpdatedAt *time.Time `json:"updatedAt"` - LastEditorID *ulid.ULID `json:"lastEditorID"` + LastEditorID *string `json:"lastEditorID"` Email *string `json:"email"` Password *string `json:"password"` Role *string `json:"role"`