package handlers import ( "context" "github.com/gin-gonic/gin" "github.com/timetracker/backend/internal/api/dto" "github.com/timetracker/backend/internal/api/responses" "github.com/timetracker/backend/internal/api/utils" "github.com/timetracker/backend/internal/models" "github.com/timetracker/backend/internal/types" ) // CompanyHandler handles company-related API endpoints type CompanyHandler struct{} // NewCompanyHandler creates a new CompanyHandler func NewCompanyHandler() *CompanyHandler { return &CompanyHandler{} } // GetCompanies handles GET /companies // // @Summary Get all companies // @Description Get a list of all companies // @Tags companies // @Accept json // @Produce json // @Security BearerAuth // @Success 200 {object} utils.Response{data=[]dto.CompanyDto} // @Failure 401 {object} utils.Response{error=utils.ErrorInfo} // @Failure 500 {object} utils.Response{error=utils.ErrorInfo} // @Router /companies [get] func (h *CompanyHandler) GetCompanies(c *gin.Context) { utils.HandleGetAll(c, models.GetAllCompanies, convertCompanyToDTO, "companies") } // GetCompanyByID handles GET /companies/:id // // @Summary Get company by ID // @Description Get a company by its ID // @Tags companies // @Accept json // @Produce json // @Security BearerAuth // @Param id path string true "Company ID" // @Success 200 {object} utils.Response{data=dto.CompanyDto} // @Failure 400 {object} utils.Response{error=utils.ErrorInfo} // @Failure 401 {object} utils.Response{error=utils.ErrorInfo} // @Failure 404 {object} utils.Response{error=utils.ErrorInfo} // @Failure 500 {object} utils.Response{error=utils.ErrorInfo} // @Router /companies/{id} [get] func (h *CompanyHandler) GetCompanyByID(c *gin.Context) { utils.HandleGetByID(c, models.GetCompanyByID, convertCompanyToDTO, "company") } // CreateCompany handles POST /companies // // @Summary Create a new company // @Description Create a new company // @Tags companies // @Accept json // @Produce json // @Security BearerAuth // @Param company body dto.CompanyCreateDto true "Company data" // @Success 201 {object} utils.Response{data=dto.CompanyDto} // @Failure 400 {object} utils.Response{error=utils.ErrorInfo} // @Failure 401 {object} utils.Response{error=utils.ErrorInfo} // @Failure 500 {object} utils.Response{error=utils.ErrorInfo} // @Router /companies [post] func (h *CompanyHandler) CreateCompany(c *gin.Context) { utils.HandleCreate(c, createCompanyWrapper, convertCompanyToDTO, "company") } // UpdateCompany handles PUT /companies/:id // // @Summary Update a company // @Description Update an existing company // @Tags companies // @Accept json // @Produce json // @Security BearerAuth // @Param id path string true "Company ID" // @Param company body dto.CompanyUpdateDto true "Company data" // @Success 200 {object} utils.Response{data=dto.CompanyDto} // @Failure 400 {object} utils.Response{error=utils.ErrorInfo} // @Failure 401 {object} utils.Response{error=utils.ErrorInfo} // @Failure 404 {object} utils.Response{error=utils.ErrorInfo} // @Failure 500 {object} utils.Response{error=utils.ErrorInfo} // @Router /companies/{id} [put] func (h *CompanyHandler) UpdateCompany(c *gin.Context) { utils.HandleUpdate(c, models.UpdateCompany, convertCompanyToDTO, prepareCompanyUpdate, "company") } // DeleteCompany handles DELETE /companies/:id // // @Summary Delete a company // @Description Delete a company by its ID // @Tags companies // @Accept json // @Produce json // @Security BearerAuth // @Param id path string true "Company ID" // @Success 204 {object} utils.Response // @Failure 400 {object} utils.Response{error=utils.ErrorInfo} // @Failure 401 {object} utils.Response{error=utils.ErrorInfo} // @Failure 500 {object} utils.Response{error=utils.ErrorInfo} // @Router /companies/{id} [delete] func (h *CompanyHandler) DeleteCompany(c *gin.Context) { utils.HandleDelete(c, models.DeleteCompany, "company") } // Helper functions for DTO conversion func convertCompanyToDTO(company *models.Company) dto.CompanyDto { return dto.CompanyDto{ ID: company.ID.String(), CreatedAt: company.CreatedAt, UpdatedAt: company.UpdatedAt, Name: company.Name, } } func convertCreateCompanyDTOToModel(dto dto.CompanyCreateDto) models.CompanyCreate { return models.CompanyCreate{ Name: dto.Name, } } func convertUpdateCompanyDTOToModel(dto dto.CompanyUpdateDto, id types.ULID) models.CompanyUpdate { update := models.CompanyUpdate{ ID: id, } if dto.Name != nil { update.Name = dto.Name } return update } // prepareCompanyUpdate prepares the company update object by parsing the ID, binding the JSON, and converting the DTO to a model func prepareCompanyUpdate(c *gin.Context) (models.CompanyUpdate, error) { // Parse ID from URL id, err := utils.ParseID(c, "id") if err != nil { responses.BadRequestResponse(c, "Invalid company ID format") return models.CompanyUpdate{}, err } // Parse request body var companyUpdateDTO dto.CompanyUpdateDto if err := utils.BindJSON(c, &companyUpdateDTO); err != nil { responses.BadRequestResponse(c, err.Error()) return models.CompanyUpdate{}, err } // Convert DTO to model return convertUpdateCompanyDTOToModel(companyUpdateDTO, id), nil } // createCompanyWrapper is a wrapper function for models.CreateCompany that takes a DTO as input func createCompanyWrapper(ctx context.Context, createDTO dto.CompanyCreateDto) (*models.Company, error) { // Convert DTO to model companyCreate := convertCreateCompanyDTOToModel(createDTO) // Call the original function return models.CreateCompany(ctx, companyCreate) }