refactor: Update DTOs to use string type for IDs and enhance API documentation for activity and user handlers

This commit is contained in:
Jean Jacques Avril 2025-03-10 21:43:45 +00:00
parent 558ee70c21
commit 58173b436c
9 changed files with 46 additions and 100 deletions

View File

@ -19,6 +19,7 @@ func NewActivityHandler() *ActivityHandler {
} }
// GetActivities handles GET /activities // GetActivities handles GET /activities
//
// @Summary Get all activities // @Summary Get all activities
// @Description Get a list of all activities // @Description Get a list of all activities
// @Tags activities // @Tags activities
@ -47,6 +48,7 @@ func (h *ActivityHandler) GetActivities(c *gin.Context) {
} }
// GetActivityByID handles GET /activities/:id // GetActivityByID handles GET /activities/:id
//
// @Summary Get activity by ID // @Summary Get activity by ID
// @Description Get an activity by its ID // @Description Get an activity by its ID
// @Tags activities // @Tags activities
@ -88,6 +90,7 @@ func (h *ActivityHandler) GetActivityByID(c *gin.Context) {
} }
// CreateActivity handles POST /activities // CreateActivity handles POST /activities
//
// @Summary Create a new activity // @Summary Create a new activity
// @Description Create a new activity // @Description Create a new activity
// @Tags activities // @Tags activities
@ -125,6 +128,7 @@ func (h *ActivityHandler) CreateActivity(c *gin.Context) {
} }
// UpdateActivity handles PUT /activities/:id // UpdateActivity handles PUT /activities/:id
//
// @Summary Update an activity // @Summary Update an activity
// @Description Update an existing activity // @Description Update an existing activity
// @Tags activities // @Tags activities
@ -156,7 +160,7 @@ func (h *ActivityHandler) UpdateActivity(c *gin.Context) {
} }
// Set ID from URL // Set ID from URL
activityUpdateDTO.ID = id activityUpdateDTO.ID = id.String()
// Convert DTO to model // Convert DTO to model
activityUpdate := convertUpdateActivityDTOToModel(activityUpdateDTO) activityUpdate := convertUpdateActivityDTOToModel(activityUpdateDTO)
@ -180,6 +184,7 @@ func (h *ActivityHandler) UpdateActivity(c *gin.Context) {
} }
// DeleteActivity handles DELETE /activities/:id // DeleteActivity handles DELETE /activities/:id
//
// @Summary Delete an activity // @Summary Delete an activity
// @Description Delete an activity by its ID // @Description Delete an activity by its ID
// @Tags activities // @Tags activities
@ -215,7 +220,7 @@ func (h *ActivityHandler) DeleteActivity(c *gin.Context) {
func convertActivityToDTO(activity *models.Activity) dto.ActivityDto { func convertActivityToDTO(activity *models.Activity) dto.ActivityDto {
return dto.ActivityDto{ return dto.ActivityDto{
ID: activity.ID, ID: activity.ID.String(),
CreatedAt: activity.CreatedAt, CreatedAt: activity.CreatedAt,
UpdatedAt: activity.UpdatedAt, UpdatedAt: activity.UpdatedAt,
Name: activity.Name, Name: activity.Name,
@ -231,8 +236,9 @@ func convertCreateActivityDTOToModel(dto dto.ActivityCreateDto) models.ActivityC
} }
func convertUpdateActivityDTOToModel(dto dto.ActivityUpdateDto) models.ActivityUpdate { func convertUpdateActivityDTOToModel(dto dto.ActivityUpdateDto) models.ActivityUpdate {
id, _ := ulid.Parse(dto.ID)
update := models.ActivityUpdate{ update := models.ActivityUpdate{
ID: dto.ID, ID: id,
} }
if dto.Name != nil { if dto.Name != nil {

View File

@ -20,6 +20,7 @@ func NewUserHandler() *UserHandler {
} }
// GetUsers handles GET /users // GetUsers handles GET /users
//
// @Summary Get all users // @Summary Get all users
// @Description Get a list of all users // @Description Get a list of all users
// @Tags users // @Tags users
@ -48,6 +49,7 @@ func (h *UserHandler) GetUsers(c *gin.Context) {
} }
// GetUserByID handles GET /users/:id // GetUserByID handles GET /users/:id
//
// @Summary Get user by ID // @Summary Get user by ID
// @Description Get a user by their ID // @Description Get a user by their ID
// @Tags users // @Tags users
@ -89,6 +91,7 @@ func (h *UserHandler) GetUserByID(c *gin.Context) {
} }
// CreateUser handles POST /users // CreateUser handles POST /users
//
// @Summary Create a new user // @Summary Create a new user
// @Description Create a new user // @Description Create a new user
// @Tags users // @Tags users
@ -126,6 +129,7 @@ func (h *UserHandler) CreateUser(c *gin.Context) {
} }
// UpdateUser handles PUT /users/:id // UpdateUser handles PUT /users/:id
//
// @Summary Update a user // @Summary Update a user
// @Description Update an existing user // @Description Update an existing user
// @Tags users // @Tags users
@ -157,7 +161,7 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
} }
// Set ID from URL // Set ID from URL
userUpdateDTO.ID = id userUpdateDTO.ID = id.String()
// Convert DTO to model // Convert DTO to model
userUpdate := convertUpdateDTOToModel(userUpdateDTO) userUpdate := convertUpdateDTOToModel(userUpdateDTO)
@ -181,6 +185,7 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
} }
// DeleteUser handles DELETE /users/:id // DeleteUser handles DELETE /users/:id
//
// @Summary Delete a user // @Summary Delete a user
// @Description Delete a user by their ID // @Description Delete a user by their ID
// @Tags users // @Tags users
@ -213,6 +218,7 @@ func (h *UserHandler) DeleteUser(c *gin.Context) {
} }
// Login handles POST /auth/login // Login handles POST /auth/login
//
// @Summary Login // @Summary Login
// @Description Authenticate a user and get a JWT token // @Description Authenticate a user and get a JWT token
// @Tags auth // @Tags auth
@ -256,6 +262,7 @@ func (h *UserHandler) Login(c *gin.Context) {
} }
// GetCurrentUser handles GET /auth/me // GetCurrentUser handles GET /auth/me
//
// @Summary Get current user // @Summary Get current user
// @Description Get the currently authenticated user // @Description Get the currently authenticated user
// @Tags auth // @Tags auth
@ -296,7 +303,7 @@ func (h *UserHandler) GetCurrentUser(c *gin.Context) {
func convertUserToDTO(user *models.User) dto.UserDto { func convertUserToDTO(user *models.User) dto.UserDto {
return dto.UserDto{ return dto.UserDto{
ID: user.ID, ID: user.ID.String(),
CreatedAt: user.CreatedAt, CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt, UpdatedAt: user.UpdatedAt,
Email: user.Email, Email: user.Email,
@ -320,8 +327,9 @@ func convertCreateDTOToModel(dto dto.UserCreateDto) models.UserCreate {
} }
func convertUpdateDTOToModel(dto dto.UserUpdateDto) models.UserUpdate { func convertUpdateDTOToModel(dto dto.UserUpdateDto) models.UserUpdate {
id, _ := ulid.Parse(dto.ID)
update := models.UserUpdate{ update := models.UserUpdate{
ID: dto.ID, ID: id,
} }
if dto.Email != nil { if dto.Email != nil {

View File

@ -2,62 +2,6 @@ package utils
// This file contains type definitions for Swagger documentation // 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 // LoginRequest is a Swagger representation of LoginDto
type LoginRequest struct { type LoginRequest struct {
Email string `json:"email" example:"user@example.com"` Email string `json:"email" example:"user@example.com"`
@ -66,6 +10,6 @@ type LoginRequest struct {
// TokenResponse is a Swagger representation of TokenDto // TokenResponse is a Swagger representation of TokenDto
type TokenResponse struct { type TokenResponse struct {
Token string `json:"token" example:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."` Token string `json:"token" example:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."`
User UserResponse `json:"user"` User dto.UserDto `json:"user"`
} }

View File

@ -2,15 +2,13 @@ package dto
import ( import (
"time" "time"
"github.com/oklog/ulid/v2"
) )
type ActivityDto struct { type ActivityDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"` UpdatedAt time.Time `json:"updatedAt"`
LastEditorID ulid.ULID `json:"lastEditorID"` LastEditorID string `json:"lastEditorID"`
Name string `json:"name"` Name string `json:"name"`
BillingRate float64 `json:"billingRate"` BillingRate float64 `json:"billingRate"`
} }
@ -21,10 +19,10 @@ type ActivityCreateDto struct {
} }
type ActivityUpdateDto struct { type ActivityUpdateDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt *time.Time `json:"createdAt"` CreatedAt *time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt"` UpdatedAt *time.Time `json:"updatedAt"`
LastEditorID *ulid.ULID `json:"lastEditorID"` LastEditorID *string `json:"lastEditorID"`
Name *string `json:"name"` Name *string `json:"name"`
BillingRate *float64 `json:"billingRate"` BillingRate *float64 `json:"billingRate"`
} }

View File

@ -2,15 +2,13 @@ package dto
import ( import (
"time" "time"
"github.com/oklog/ulid/v2"
) )
type CompanyDto struct { type CompanyDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"` UpdatedAt time.Time `json:"updatedAt"`
LastEditorID ulid.ULID `json:"lastEditorID"` LastEditorID string `json:"lastEditorID"`
Name string `json:"name"` Name string `json:"name"`
} }
@ -19,9 +17,9 @@ type CompanyCreateDto struct {
} }
type CompanyUpdateDto struct { type CompanyUpdateDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt *time.Time `json:"createdAt"` CreatedAt *time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt"` UpdatedAt *time.Time `json:"updatedAt"`
LastEditorID *ulid.ULID `json:"lastEditorID"` LastEditorID *string `json:"lastEditorID"`
Name *string `json:"name"` Name *string `json:"name"`
} }

View File

@ -2,15 +2,13 @@ package dto
import ( import (
"time" "time"
"github.com/oklog/ulid/v2"
) )
type CustomerDto struct { type CustomerDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"` UpdatedAt time.Time `json:"updatedAt"`
LastEditorID ulid.ULID `json:"lastEditorID"` LastEditorID string `json:"lastEditorID"`
Name string `json:"name"` Name string `json:"name"`
CompanyID int `json:"companyId"` CompanyID int `json:"companyId"`
} }
@ -21,10 +19,10 @@ type CustomerCreateDto struct {
} }
type CustomerUpdateDto struct { type CustomerUpdateDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt *time.Time `json:"createdAt"` CreatedAt *time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt"` UpdatedAt *time.Time `json:"updatedAt"`
LastEditorID *ulid.ULID `json:"lastEditorID"` LastEditorID *string `json:"lastEditorID"`
Name *string `json:"name"` Name *string `json:"name"`
CompanyID *int `json:"companyId"` CompanyID *int `json:"companyId"`
} }

View File

@ -2,15 +2,13 @@ package dto
import ( import (
"time" "time"
"github.com/oklog/ulid/v2"
) )
type ProjectDto struct { type ProjectDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"` UpdatedAt time.Time `json:"updatedAt"`
LastEditorID ulid.ULID `json:"lastEditorID"` LastEditorID string `json:"lastEditorID"`
Name string `json:"name"` Name string `json:"name"`
CustomerID int `json:"customerId"` CustomerID int `json:"customerId"`
} }
@ -21,10 +19,10 @@ type ProjectCreateDto struct {
} }
type ProjectUpdateDto struct { type ProjectUpdateDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt *time.Time `json:"createdAt"` CreatedAt *time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt"` UpdatedAt *time.Time `json:"updatedAt"`
LastEditorID *ulid.ULID `json:"lastEditorID"` LastEditorID *string `json:"lastEditorID"`
Name *string `json:"name"` Name *string `json:"name"`
CustomerID *int `json:"customerId"` CustomerID *int `json:"customerId"`
} }

View File

@ -2,15 +2,13 @@ package dto
import ( import (
"time" "time"
"github.com/oklog/ulid/v2"
) )
type TimeEntryDto struct { type TimeEntryDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"` UpdatedAt time.Time `json:"updatedAt"`
LastEditorID ulid.ULID `json:"lastEditorID"` LastEditorID string `json:"lastEditorID"`
UserID int `json:"userId"` UserID int `json:"userId"`
ProjectID int `json:"projectId"` ProjectID int `json:"projectId"`
ActivityID int `json:"activityId"` ActivityID int `json:"activityId"`
@ -31,10 +29,10 @@ type TimeEntryCreateDto struct {
} }
type TimeEntryUpdateDto struct { type TimeEntryUpdateDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt *time.Time `json:"createdAt"` CreatedAt *time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt"` UpdatedAt *time.Time `json:"updatedAt"`
LastEditorID *ulid.ULID `json:"lastEditorID"` LastEditorID *string `json:"lastEditorID"`
UserID *int `json:"userId"` UserID *int `json:"userId"`
ProjectID *int `json:"projectId"` ProjectID *int `json:"projectId"`
ActivityID *int `json:"activityId"` ActivityID *int `json:"activityId"`

View File

@ -2,15 +2,13 @@ package dto
import ( import (
"time" "time"
"github.com/oklog/ulid/v2"
) )
type UserDto struct { type UserDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"` UpdatedAt time.Time `json:"updatedAt"`
LastEditorID ulid.ULID `json:"lastEditorID"` LastEditorID string `json:"lastEditorID"`
Email string `json:"email"` Email string `json:"email"`
Role string `json:"role"` Role string `json:"role"`
CompanyID int `json:"companyId"` CompanyID int `json:"companyId"`
@ -26,10 +24,10 @@ type UserCreateDto struct {
} }
type UserUpdateDto struct { type UserUpdateDto struct {
ID ulid.ULID `json:"id"` ID string `json:"id"`
CreatedAt *time.Time `json:"createdAt"` CreatedAt *time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt"` UpdatedAt *time.Time `json:"updatedAt"`
LastEditorID *ulid.ULID `json:"lastEditorID"` LastEditorID *string `json:"lastEditorID"`
Email *string `json:"email"` Email *string `json:"email"`
Password *string `json:"password"` Password *string `json:"password"`
Role *string `json:"role"` Role *string `json:"role"`