diff --git a/internal/deployment/wire.go b/internal/deployment/wire.go index a0d24e9..bbc7be9 100644 --- a/internal/deployment/wire.go +++ b/internal/deployment/wire.go @@ -11,6 +11,7 @@ import ( "com.raunlo.checklist/internal/server" checklistV1 "com.raunlo.checklist/internal/server/v1/checklist" checklistItemV1 "com.raunlo.checklist/internal/server/v1/checklistItem" + checklistItemTemplateV1 "com.raunlo.checklist/internal/server/v1/checklistItemTemplate" wire "github.com/google/wire" ) @@ -32,10 +33,11 @@ func Init(configuration ApplicationConfiguration) Application { repository.CreateChecklistItemRepository, ), // checklist item template resource set - //wire.NewSet(controllerMapper.NewChecklistItemTemplateDtoMapper, - // controllers.CreateChecklistItemTemplateController, - // service.CreateChecklistItemTemplateService, - // repository.CreateChecklistItemTemplateRepository), + wire.NewSet( + checklistItemTemplateV1.NewChecklistItemTemplateController, + service.CreateChecklistItemTemplateService, + repository.CreateChecklistItemTemplateRepository, + ), //controllers.CreateUpdateOrderController, connection.NewDatabaseConnection, wire.FieldsOf(new(ApplicationConfiguration), "DatabaseConfiguration"), diff --git a/internal/repository/query/checklist_item_template.go b/internal/repository/query/checklist_item_template.go index c088ed6..4ef03e3 100644 --- a/internal/repository/query/checklist_item_template.go +++ b/internal/repository/query/checklist_item_template.go @@ -1,7 +1,11 @@ package query import ( + "context" + "errors" + "com.raunlo.checklist/internal/core/domain" + "github.com/jackc/pgx/v5" "github.com/raunlo/pgx-with-automapper/pool" ) @@ -11,8 +15,10 @@ type PersistChecklistItemTemplateQueryFunction struct { func (p *PersistChecklistItemTemplateQueryFunction) GetTransactionalQueryFunction() func(tx pool.TransactionWrapper) (domain.ChecklistItemTemplate, error) { return func(tx pool.TransactionWrapper) (domain.ChecklistItemTemplate, error) { - //TODO implement me - panic("implement me") + sql := `INSERT INTO TEMPLATE_ITEM(ID, NAME) VALUES(nextval('template_item_id'), @name) RETURNING ID` + row := tx.QueryRow(context.Background(), sql, pgx.NamedArgs{"name": "__template__"}) + err := row.Scan(&p.checklistItemTemplate.Id) + return p.checklistItemTemplate, err } } @@ -23,8 +29,9 @@ type UpdateChecklistItemTemplateQueryFunction struct { func (u *UpdateChecklistItemTemplateQueryFunction) GetTransactionalQueryFunction() func(tx pool.TransactionWrapper) (bool, error) { return func(tx pool.TransactionWrapper) (bool, error) { - //TODO implement me - panic("implement me") + sql := `UPDATE TEMPLATE_ITEM SET NAME = NAME WHERE ID = @id` + tag, err := tx.Exec(context.Background(), sql, pgx.NamedArgs{"id": u.checklistItemTemplate.Id}) + return tag.RowsAffected() == 1, err } } @@ -34,8 +41,18 @@ type DeleteChecklistItemTemplateByIdQueryFunction struct { func (d *DeleteChecklistItemTemplateByIdQueryFunction) GetTransactionalQueryFunction() func(tx pool.TransactionWrapper) (bool, error) { return func(tx pool.TransactionWrapper) (bool, error) { - //TODO implement me - panic("implement me") + _, err := tx.Exec(context.Background(), `DELETE FROM TEMPLATE_ITEM_ROW WHERE TEMPLATE_ITEM_ID = @id`, pgx.NamedArgs{"id": d.checklistItemTemplateId}) + if err != nil { + return false, err + } + tag, err := tx.Exec(context.Background(), `DELETE FROM TEMPLATE_ITEM WHERE ID = @id`, pgx.NamedArgs{"id": d.checklistItemTemplateId}) + if err != nil { + return false, err + } + if tag.RowsAffected() > 1 { + return false, errors.New("deleteChecklistItemTemplateById affected more than one row") + } + return tag.RowsAffected() == 1, nil } } @@ -46,8 +63,31 @@ type FindChecklistItemTemplateByIdQueryFunction struct { func (f FindChecklistItemTemplateByIdQueryFunction) GetQueryFunction() func(connection pool.Conn) (*domain.ChecklistItemTemplate, error) { return func(connection pool.Conn) (*domain.ChecklistItemTemplate, error) { - //TODO implement me - panic("implement me") + sql := `SELECT t.ID, r.ID FROM TEMPLATE_ITEM t LEFT JOIN TEMPLATE_ITEM_ROW r ON t.ID = r.TEMPLATE_ITEM_ID WHERE t.ID = @id` + rows, err := connection.Query(context.Background(), sql, pgx.NamedArgs{"id": f.checklistItemTemplateId}) + if err != nil { + return nil, err + } + defer rows.Close() + + var template *domain.ChecklistItemTemplate + for rows.Next() { + var tId uint + var rId *uint + if err := rows.Scan(&tId, &rId); err != nil { + return nil, err + } + if template == nil { + template = &domain.ChecklistItemTemplate{Id: tId} + } + if rId != nil { + template.Rows = append(template.Rows, domain.ChecklistItemTemplateRow{Id: *rId}) + } + } + if template == nil { + return nil, nil + } + return template, rows.Err() } } @@ -57,7 +97,36 @@ type GetAllChecklistItemTemplatesQueryFunction struct { func (g *GetAllChecklistItemTemplatesQueryFunction) GetQueryFunction() func(connection pool.Conn) ([]domain.ChecklistItemTemplate, error) { return func(connection pool.Conn) ([]domain.ChecklistItemTemplate, error) { - //TODO implement me - panic("implement me") + sql := `SELECT t.ID, r.ID FROM TEMPLATE_ITEM t LEFT JOIN TEMPLATE_ITEM_ROW r ON t.ID = r.TEMPLATE_ITEM_ID ORDER BY t.ID, r.ID` + rows, err := connection.Query(context.Background(), sql) + if err != nil { + return nil, err + } + defer rows.Close() + + templatesMap := map[uint]*domain.ChecklistItemTemplate{} + for rows.Next() { + var tId uint + var rId *uint + if err := rows.Scan(&tId, &rId); err != nil { + return nil, err + } + tpl := templatesMap[tId] + if tpl == nil { + tpl = &domain.ChecklistItemTemplate{Id: tId} + templatesMap[tId] = tpl + } + if rId != nil { + tpl.Rows = append(tpl.Rows, domain.ChecklistItemTemplateRow{Id: *rId}) + } + } + if err := rows.Err(); err != nil { + return nil, err + } + templates := make([]domain.ChecklistItemTemplate, 0, len(templatesMap)) + for _, t := range templatesMap { + templates = append(templates, *t) + } + return templates, nil } } diff --git a/internal/repository/query/checklist_item_template_row.go b/internal/repository/query/checklist_item_template_row.go index eedfba6..5b1d1a4 100644 --- a/internal/repository/query/checklist_item_template_row.go +++ b/internal/repository/query/checklist_item_template_row.go @@ -1,7 +1,11 @@ package query import ( + "context" + "fmt" + "com.raunlo.checklist/internal/core/domain" + "github.com/jackc/pgx/v5" "github.com/raunlo/pgx-with-automapper/pool" ) @@ -12,8 +16,32 @@ type PersistChecklistItemTemplateRowQueryFunction struct { func (p *PersistChecklistItemTemplateRowQueryFunction) GetTransactionalQueryFunction() func(tx pool.TransactionWrapper) ([]domain.ChecklistItemTemplateRow, error) { return func(tx pool.TransactionWrapper) ([]domain.ChecklistItemTemplateRow, error) { - //TODO implement me - panic("implement me") + if len(p.checklistItemTemplateRows) == 0 { + return []domain.ChecklistItemTemplateRow{}, nil + } + namedArgs := pgx.NamedArgs{} + query := "INSERT INTO TEMPLATE_ITEM_ROW(ID, TEMPLATE_ITEM_ID, NAME) VALUES " + + ids, err := (&GetSequenceValuesQuery{sequenceName: "template_item_row_id", numberOfValues: len(p.checklistItemTemplateRows)}).GetTransactionalQueryFunction()(tx) + if err != nil { + return nil, err + } + for i := range p.checklistItemTemplateRows { + rowPtr := &p.checklistItemTemplateRows[i] + rowPtr.Id = ids[i] + idParam := getIndexedSQLValueParamName(i, "rowId") + templateIdParam := getIndexedSQLValueParamName(i, "templateId") + nameParam := getIndexedSQLValueParamName(i, "rowName") + query += fmt.Sprintf("(@%s, @%s, @%s)", idParam, templateIdParam, nameParam) + if i != len(p.checklistItemTemplateRows)-1 { + query += ", " + } + namedArgs[idParam] = rowPtr.Id + namedArgs[templateIdParam] = p.checklistItemTemplateId + namedArgs[nameParam] = "__template_row__" + } + _, err = tx.Exec(context.Background(), query, namedArgs) + return p.checklistItemTemplateRows, err } } @@ -24,8 +52,37 @@ type UpdateChecklistItemTemplateRowsQueryFunction struct { } func (u *UpdateChecklistItemTemplateRowsQueryFunction) GetTransactionalQueryFunction() func(tx pool.TransactionWrapper) (bool, error) { + getQuery := func(index int, row domain.ChecklistItemTemplateRow) (string, pgx.NamedArgs) { + rowNameParam := getIndexedSQLValueParamName(index, "rowName") + templateIdParam := getIndexedSQLValueParamName(index, "templateId") + rowIdParam := getIndexedSQLValueParamName(index, "rowId") + sql := fmt.Sprintf(`UPDATE TEMPLATE_ITEM_ROW SET NAME = @%s WHERE ID = @%s AND TEMPLATE_ITEM_ID = @%s`, rowNameParam, rowIdParam, templateIdParam) + args := pgx.NamedArgs{ + rowNameParam: "__template_row__", + templateIdParam: u.checklistItemTemplateId, + rowIdParam: row.Id, + } + return sql, args + } return func(tx pool.TransactionWrapper) (bool, error) { - //TODO implement me - panic("implement me") + if len(u.checklistItemTemplateRows) == 0 { + return true, nil + } + batch := &pgx.Batch{} + for i, row := range u.checklistItemTemplateRows { + sql, args := getQuery(i, row) + batch.Queue(sql, args) + } + br := tx.SendBatch(context.Background(), batch) + defer br.Close() + rowsAffected := 0 + for i := 0; i < batch.Len(); i++ { + tag, err := br.Exec() + if err != nil { + return false, err + } + rowsAffected += int(tag.RowsAffected()) + } + return rowsAffected == batch.Len(), nil } } diff --git a/internal/repository/repository_factories.go b/internal/repository/repository_factories.go index 84748b2..2d34a20 100644 --- a/internal/repository/repository_factories.go +++ b/internal/repository/repository_factories.go @@ -17,6 +17,8 @@ func CreateChecklistItemRepository(conn pool.Conn) repository.IChecklistItemsRep } } -func CreateChecklistItemTemplateRepository() repository.IChecklistItemTemplateRepository { - return &checklistItemTemplateRepository{} +func CreateChecklistItemTemplateRepository(conn pool.Conn) repository.IChecklistItemTemplateRepository { + return &checklistItemTemplateRepository{ + connection: conn, + } } diff --git a/internal/server/factory.go b/internal/server/factory.go index 964627c..05ed876 100644 --- a/internal/server/factory.go +++ b/internal/server/factory.go @@ -4,6 +4,7 @@ import ( v1 "com.raunlo.checklist/internal/server/v1" checklistV1 "com.raunlo.checklist/internal/server/v1/checklist" checklistItemV1 "com.raunlo.checklist/internal/server/v1/checklistItem" + checklistItemTemplateV1 "com.raunlo.checklist/internal/server/v1/checklistItemTemplate" "github.com/gin-gonic/gin" ) @@ -11,25 +12,29 @@ type IRoutes interface { ConfigureRoutes() } type routes struct { - engine *gin.Engine - checklistController checklistV1.IChecklistController - checklistItemController checklistItemV1.IChecklistItemController + engine *gin.Engine + checklistController checklistV1.IChecklistController + checklistItemController checklistItemV1.IChecklistItemController + checklistItemTemplateController checklistItemTemplateV1.IChecklistItemTemplateController } func NewRoutes( engine *gin.Engine, checklistController checklistV1.IChecklistController, - checklistItemController checklistItemV1.IChecklistItemController) IRoutes { + checklistItemController checklistItemV1.IChecklistItemController, + checklistItemTemplateController checklistItemTemplateV1.IChecklistItemTemplateController) IRoutes { return &routes{ - engine: engine, - checklistController: checklistController, - checklistItemController: checklistItemController, + engine: engine, + checklistController: checklistController, + checklistItemController: checklistItemController, + checklistItemTemplateController: checklistItemTemplateController, } } func (server *routes) ConfigureRoutes() { v1.RegisterV1Endpoints(server.engine.Group("/"), server.checklistController, - server.checklistItemController) + server.checklistItemController, + server.checklistItemTemplateController) } diff --git a/internal/server/generator.go b/internal/server/generator.go index 99b48b0..d26401f 100644 --- a/internal/server/generator.go +++ b/internal/server/generator.go @@ -4,3 +4,4 @@ package server // v1 version API //go:generate go tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -o ./v1/checklist/server.gen.go -config ./v1/checklist/cfg.yaml ./../../openapi/api_v1.yaml //go:generate go tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -o ./v1/checklistItem/server.gen.go -config ./v1/checklistItem/cfg.yaml ./../../openapi/api_v1.yaml +//go:generate go tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -o ./v1/checklistItemTemplate/server.gen.go -config ./v1/checklistItemTemplate/cfg.yaml ./../../openapi/api_v1.yaml diff --git a/internal/server/v1/api_v1_factory.go b/internal/server/v1/api_v1_factory.go index 27f6a19..a0c3d0f 100644 --- a/internal/server/v1/api_v1_factory.go +++ b/internal/server/v1/api_v1_factory.go @@ -3,12 +3,15 @@ package v1 import ( "com.raunlo.checklist/internal/server/v1/checklist" "com.raunlo.checklist/internal/server/v1/checklistItem" + checklistItemTemplate "com.raunlo.checklist/internal/server/v1/checklistItemTemplate" "github.com/gin-gonic/gin" ) func RegisterV1Endpoints(gin *gin.RouterGroup, checklistController checklist.IChecklistController, - checklistItemController checklistItem.IChecklistItemController) { + checklistItemController checklistItem.IChecklistItemController, + checklistItemTemplateController checklistItemTemplate.IChecklistItemTemplateController) { checklist.RegisterHandlers(gin, checklist.NewStrictHandler(checklistController, nil)) checklistItem.RegisterHandlers(gin, checklistItem.NewStrictHandler(checklistItemController, nil)) + checklistItemTemplate.RegisterHandlers(gin, checklistItemTemplate.NewStrictHandler(checklistItemTemplateController, nil)) } diff --git a/internal/server/v1/checklistItem/server.gen.go b/internal/server/v1/checklistItem/server.gen.go index 22c4187..e0b7fee 100644 --- a/internal/server/v1/checklistItem/server.gen.go +++ b/internal/server/v1/checklistItem/server.gen.go @@ -757,9 +757,10 @@ type DeleteChecklistItemRowResponseObject interface { VisitDeleteChecklistItemRowResponse(w http.ResponseWriter) error } -type DeleteChecklistItemRow204Response struct{} +type DeleteChecklistItemRow204Response struct { +} -func (DeleteChecklistItemRow204Response) VisitDeleteChecklistItemRowResponse(w http.ResponseWriter) error { +func (response DeleteChecklistItemRow204Response) VisitDeleteChecklistItemRowResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } diff --git a/internal/server/v1/checklistItemTemplate/cfg.yaml b/internal/server/v1/checklistItemTemplate/cfg.yaml new file mode 100644 index 0000000..ff91df7 --- /dev/null +++ b/internal/server/v1/checklistItemTemplate/cfg.yaml @@ -0,0 +1,8 @@ +package: checklistItemTemplate +generate: + gin-server: true + models: true + strict-server: true +output-options: + include-tags: + - checklistItemTemplate diff --git a/internal/server/v1/checklistItemTemplate/checklist_item_template_controller_impl.go b/internal/server/v1/checklistItemTemplate/checklist_item_template_controller_impl.go new file mode 100644 index 0000000..401d4c2 --- /dev/null +++ b/internal/server/v1/checklistItemTemplate/checklist_item_template_controller_impl.go @@ -0,0 +1,79 @@ +package checklistItemTemplate + +import ( + "context" + "net/http" + + "com.raunlo.checklist/internal/core/service" +) + +type IChecklistItemTemplateController = StrictServerInterface + +type checklistItemTemplateController struct { + service service.IChecklistItemTemplateService + mapper IChecklistItemTemplateDtoMapper +} + +func (c *checklistItemTemplateController) GetAllChecklistItemTemplates(_ context.Context, _ GetAllChecklistItemTemplatesRequestObject) (GetAllChecklistItemTemplatesResponseObject, error) { + if templates, err := c.service.GetAllChecklistTemplates(); err != nil { + return GetAllChecklistItemTemplates500JSONResponse{Message: err.Error()}, nil + } else { + dto := c.mapper.MapDomainListToDtoList(templates) + return GetAllChecklistItemTemplates200JSONResponse(dto), nil + } +} + +func (c *checklistItemTemplateController) CreateChecklistItemTemplate(_ context.Context, request CreateChecklistItemTemplateRequestObject) (CreateChecklistItemTemplateResponseObject, error) { + domainObject := c.mapper.MapCreateRequestToDomain(*request.Body) + if template, err := c.service.SaveChecklistTemplate(domainObject); err != nil { + if err.ResponseCode() == http.StatusBadRequest { + return CreateChecklistItemTemplate400JSONResponse{Message: err.Error()}, nil + } + return CreateChecklistItemTemplate500JSONResponse{Message: err.Error()}, nil + } else { + dto := c.mapper.MapDomainToDto(template) + return CreateChecklistItemTemplate201JSONResponse(dto), nil + } +} + +func (c *checklistItemTemplateController) GetChecklistItemTemplateById(_ context.Context, request GetChecklistItemTemplateByIdRequestObject) (GetChecklistItemTemplateByIdResponseObject, error) { + if template, err := c.service.FindChecklistTemplateById(request.TemplateId); err != nil { + return GetChecklistItemTemplateById500JSONResponse{Message: err.Error()}, nil + } else if template == nil { + return GetChecklistItemTemplateById404JSONResponse{Message: "Checklist item template not found"}, nil + } else { + dto := c.mapper.MapDomainToDto(*template) + return GetChecklistItemTemplateById200JSONResponse(dto), nil + } +} + +func (c *checklistItemTemplateController) UpdateChecklistItemTemplateById(_ context.Context, request UpdateChecklistItemTemplateByIdRequestObject) (UpdateChecklistItemTemplateByIdResponseObject, error) { + domainObject := c.mapper.MapUpdateRequestToDomain(*request.Body) + domainObject.Id = request.TemplateId + if template, err := c.service.UpdateChecklistTemplate(domainObject); err != nil { + if err.ResponseCode() == http.StatusNotFound { + return UpdateChecklistItemTemplateById404JSONResponse{Message: err.Error()}, nil + } + return UpdateChecklistItemTemplateById500JSONResponse{Message: err.Error()}, nil + } else { + dto := c.mapper.MapDomainToDto(template) + return UpdateChecklistItemTemplateById200JSONResponse(dto), nil + } +} + +func (c *checklistItemTemplateController) DeleteChecklistItemTemplateById(_ context.Context, request DeleteChecklistItemTemplateByIdRequestObject) (DeleteChecklistItemTemplateByIdResponseObject, error) { + if err := c.service.DeleteChecklistTemplateById(request.TemplateId); err != nil { + if err.ResponseCode() == http.StatusNotFound { + return DeleteChecklistItemTemplateById404JSONResponse{Message: err.Error()}, nil + } + return DeleteChecklistItemTemplateById500JSONResponse{Message: err.Error()}, nil + } + return DeleteChecklistItemTemplateById204Response{}, nil +} + +func NewChecklistItemTemplateController(service service.IChecklistItemTemplateService) IChecklistItemTemplateController { + return &checklistItemTemplateController{ + service: service, + mapper: NewChecklistItemTemplateMapper(), + } +} diff --git a/internal/server/v1/checklistItemTemplate/checklist_item_template_dto_mapper.go b/internal/server/v1/checklistItemTemplate/checklist_item_template_dto_mapper.go new file mode 100644 index 0000000..934a232 --- /dev/null +++ b/internal/server/v1/checklistItemTemplate/checklist_item_template_dto_mapper.go @@ -0,0 +1,45 @@ +package checklistItemTemplate + +import ( + "com.raunlo.checklist/internal/core/domain" + "github.com/rendis/structsconv" +) + +type IChecklistItemTemplateDtoMapper interface { + MapDomainToDto(template domain.ChecklistItemTemplate) ChecklistItemTemplateResponse + MapCreateRequestToDomain(request CreateChecklistItemTemplateRequest) domain.ChecklistItemTemplate + MapUpdateRequestToDomain(request UpdateChecklistItemTemplateRequest) domain.ChecklistItemTemplate + MapDomainListToDtoList(templates []domain.ChecklistItemTemplate) []ChecklistItemTemplateResponse +} + +type checklistItemTemplateMapper struct{} + +func (m *checklistItemTemplateMapper) MapDomainToDto(template domain.ChecklistItemTemplate) ChecklistItemTemplateResponse { + dto := ChecklistItemTemplateResponse{} + structsconv.Map(&template, &dto) + return dto +} + +func (m *checklistItemTemplateMapper) MapCreateRequestToDomain(request CreateChecklistItemTemplateRequest) domain.ChecklistItemTemplate { + template := domain.ChecklistItemTemplate{} + structsconv.Map(&request, &template) + return template +} + +func (m *checklistItemTemplateMapper) MapUpdateRequestToDomain(request UpdateChecklistItemTemplateRequest) domain.ChecklistItemTemplate { + template := domain.ChecklistItemTemplate{} + structsconv.Map(&request, &template) + return template +} + +func (m *checklistItemTemplateMapper) MapDomainListToDtoList(templates []domain.ChecklistItemTemplate) []ChecklistItemTemplateResponse { + res := make([]ChecklistItemTemplateResponse, len(templates)) + for i, t := range templates { + res[i] = m.MapDomainToDto(t) + } + return res +} + +func NewChecklistItemTemplateMapper() IChecklistItemTemplateDtoMapper { + return &checklistItemTemplateMapper{} +} diff --git a/internal/server/v1/checklistItemTemplate/server.gen.go b/internal/server/v1/checklistItemTemplate/server.gen.go new file mode 100644 index 0000000..7862f40 --- /dev/null +++ b/internal/server/v1/checklistItemTemplate/server.gen.go @@ -0,0 +1,551 @@ +// Package checklistItemTemplate provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.4.1 DO NOT EDIT. +package checklistItemTemplate + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/oapi-codegen/runtime" + strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin" +) + +// ChecklistItemTemplateResponse defines model for ChecklistItemTemplateResponse. +type ChecklistItemTemplateResponse struct { + Id uint `json:"id"` + Rows []ChecklistItemTemplateRow `json:"rows"` +} + +// ChecklistItemTemplateRow defines model for ChecklistItemTemplateRow. +type ChecklistItemTemplateRow struct { + Id uint `json:"id"` +} + +// CreateChecklistItemTemplateRequest defines model for CreateChecklistItemTemplateRequest. +type CreateChecklistItemTemplateRequest struct { + Rows []ChecklistItemTemplateRow `json:"rows"` +} + +// Error defines model for Error. +type Error struct { + Message string `json:"message"` +} + +// UpdateChecklistItemTemplateRequest defines model for UpdateChecklistItemTemplateRequest. +type UpdateChecklistItemTemplateRequest struct { + Id uint `json:"id"` + Rows []ChecklistItemTemplateRow `json:"rows"` +} + +// CreateChecklistItemTemplateJSONRequestBody defines body for CreateChecklistItemTemplate for application/json ContentType. +type CreateChecklistItemTemplateJSONRequestBody = CreateChecklistItemTemplateRequest + +// UpdateChecklistItemTemplateByIdJSONRequestBody defines body for UpdateChecklistItemTemplateById for application/json ContentType. +type UpdateChecklistItemTemplateByIdJSONRequestBody = UpdateChecklistItemTemplateRequest + +// ServerInterface represents all server handlers. +type ServerInterface interface { + // Get all checklist item templates + // (GET /api/v1/checklist-item-templates) + GetAllChecklistItemTemplates(c *gin.Context) + // Create checklist item template + // (POST /api/v1/checklist-item-templates) + CreateChecklistItemTemplate(c *gin.Context) + // Delete checklist item template by ID + // (DELETE /api/v1/checklist-item-templates/{templateId}) + DeleteChecklistItemTemplateById(c *gin.Context, templateId uint) + // Get checklist item template by ID + // (GET /api/v1/checklist-item-templates/{templateId}) + GetChecklistItemTemplateById(c *gin.Context, templateId uint) + // Update checklist item template by ID + // (PUT /api/v1/checklist-item-templates/{templateId}) + UpdateChecklistItemTemplateById(c *gin.Context, templateId uint) +} + +// ServerInterfaceWrapper converts contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface + HandlerMiddlewares []MiddlewareFunc + ErrorHandler func(*gin.Context, error, int) +} + +type MiddlewareFunc func(c *gin.Context) + +// GetAllChecklistItemTemplates operation middleware +func (siw *ServerInterfaceWrapper) GetAllChecklistItemTemplates(c *gin.Context) { + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetAllChecklistItemTemplates(c) +} + +// CreateChecklistItemTemplate operation middleware +func (siw *ServerInterfaceWrapper) CreateChecklistItemTemplate(c *gin.Context) { + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.CreateChecklistItemTemplate(c) +} + +// DeleteChecklistItemTemplateById operation middleware +func (siw *ServerInterfaceWrapper) DeleteChecklistItemTemplateById(c *gin.Context) { + + var err error + + // ------------- Path parameter "templateId" ------------- + var templateId uint + + err = runtime.BindStyledParameterWithOptions("simple", "templateId", c.Param("templateId"), &templateId, runtime.BindStyledParameterOptions{Explode: false, Required: true}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter templateId: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.DeleteChecklistItemTemplateById(c, templateId) +} + +// GetChecklistItemTemplateById operation middleware +func (siw *ServerInterfaceWrapper) GetChecklistItemTemplateById(c *gin.Context) { + + var err error + + // ------------- Path parameter "templateId" ------------- + var templateId uint + + err = runtime.BindStyledParameterWithOptions("simple", "templateId", c.Param("templateId"), &templateId, runtime.BindStyledParameterOptions{Explode: false, Required: true}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter templateId: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetChecklistItemTemplateById(c, templateId) +} + +// UpdateChecklistItemTemplateById operation middleware +func (siw *ServerInterfaceWrapper) UpdateChecklistItemTemplateById(c *gin.Context) { + + var err error + + // ------------- Path parameter "templateId" ------------- + var templateId uint + + err = runtime.BindStyledParameterWithOptions("simple", "templateId", c.Param("templateId"), &templateId, runtime.BindStyledParameterOptions{Explode: false, Required: true}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter templateId: %w", err), http.StatusBadRequest) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.UpdateChecklistItemTemplateById(c, templateId) +} + +// GinServerOptions provides options for the Gin server. +type GinServerOptions struct { + BaseURL string + Middlewares []MiddlewareFunc + ErrorHandler func(*gin.Context, error, int) +} + +// RegisterHandlers creates http.Handler with routing matching OpenAPI spec. +func RegisterHandlers(router gin.IRouter, si ServerInterface) { + RegisterHandlersWithOptions(router, si, GinServerOptions{}) +} + +// RegisterHandlersWithOptions creates http.Handler with additional options +func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options GinServerOptions) { + errorHandler := options.ErrorHandler + if errorHandler == nil { + errorHandler = func(c *gin.Context, err error, statusCode int) { + c.JSON(statusCode, gin.H{"msg": err.Error()}) + } + } + + wrapper := ServerInterfaceWrapper{ + Handler: si, + HandlerMiddlewares: options.Middlewares, + ErrorHandler: errorHandler, + } + + router.GET(options.BaseURL+"/api/v1/checklist-item-templates", wrapper.GetAllChecklistItemTemplates) + router.POST(options.BaseURL+"/api/v1/checklist-item-templates", wrapper.CreateChecklistItemTemplate) + router.DELETE(options.BaseURL+"/api/v1/checklist-item-templates/:templateId", wrapper.DeleteChecklistItemTemplateById) + router.GET(options.BaseURL+"/api/v1/checklist-item-templates/:templateId", wrapper.GetChecklistItemTemplateById) + router.PUT(options.BaseURL+"/api/v1/checklist-item-templates/:templateId", wrapper.UpdateChecklistItemTemplateById) +} + +type GetAllChecklistItemTemplatesRequestObject struct { +} + +type GetAllChecklistItemTemplatesResponseObject interface { + VisitGetAllChecklistItemTemplatesResponse(w http.ResponseWriter) error +} + +type GetAllChecklistItemTemplates200JSONResponse []ChecklistItemTemplateResponse + +func (response GetAllChecklistItemTemplates200JSONResponse) VisitGetAllChecklistItemTemplatesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + + return json.NewEncoder(w).Encode(response) +} + +type GetAllChecklistItemTemplates500JSONResponse Error + +func (response GetAllChecklistItemTemplates500JSONResponse) VisitGetAllChecklistItemTemplatesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + +type CreateChecklistItemTemplateRequestObject struct { + Body *CreateChecklistItemTemplateJSONRequestBody +} + +type CreateChecklistItemTemplateResponseObject interface { + VisitCreateChecklistItemTemplateResponse(w http.ResponseWriter) error +} + +type CreateChecklistItemTemplate201JSONResponse ChecklistItemTemplateResponse + +func (response CreateChecklistItemTemplate201JSONResponse) VisitCreateChecklistItemTemplateResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + + return json.NewEncoder(w).Encode(response) +} + +type CreateChecklistItemTemplate400JSONResponse Error + +func (response CreateChecklistItemTemplate400JSONResponse) VisitCreateChecklistItemTemplateResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(400) + + return json.NewEncoder(w).Encode(response) +} + +type CreateChecklistItemTemplate500JSONResponse Error + +func (response CreateChecklistItemTemplate500JSONResponse) VisitCreateChecklistItemTemplateResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + +type DeleteChecklistItemTemplateByIdRequestObject struct { + TemplateId uint `json:"templateId"` +} + +type DeleteChecklistItemTemplateByIdResponseObject interface { + VisitDeleteChecklistItemTemplateByIdResponse(w http.ResponseWriter) error +} + +type DeleteChecklistItemTemplateById204Response struct { +} + +func (response DeleteChecklistItemTemplateById204Response) VisitDeleteChecklistItemTemplateByIdResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} + +type DeleteChecklistItemTemplateById404JSONResponse Error + +func (response DeleteChecklistItemTemplateById404JSONResponse) VisitDeleteChecklistItemTemplateByIdResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(404) + + return json.NewEncoder(w).Encode(response) +} + +type DeleteChecklistItemTemplateById500JSONResponse Error + +func (response DeleteChecklistItemTemplateById500JSONResponse) VisitDeleteChecklistItemTemplateByIdResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + +type GetChecklistItemTemplateByIdRequestObject struct { + TemplateId uint `json:"templateId"` +} + +type GetChecklistItemTemplateByIdResponseObject interface { + VisitGetChecklistItemTemplateByIdResponse(w http.ResponseWriter) error +} + +type GetChecklistItemTemplateById200JSONResponse ChecklistItemTemplateResponse + +func (response GetChecklistItemTemplateById200JSONResponse) VisitGetChecklistItemTemplateByIdResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + + return json.NewEncoder(w).Encode(response) +} + +type GetChecklistItemTemplateById404JSONResponse Error + +func (response GetChecklistItemTemplateById404JSONResponse) VisitGetChecklistItemTemplateByIdResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(404) + + return json.NewEncoder(w).Encode(response) +} + +type GetChecklistItemTemplateById500JSONResponse Error + +func (response GetChecklistItemTemplateById500JSONResponse) VisitGetChecklistItemTemplateByIdResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + +type UpdateChecklistItemTemplateByIdRequestObject struct { + TemplateId uint `json:"templateId"` + Body *UpdateChecklistItemTemplateByIdJSONRequestBody +} + +type UpdateChecklistItemTemplateByIdResponseObject interface { + VisitUpdateChecklistItemTemplateByIdResponse(w http.ResponseWriter) error +} + +type UpdateChecklistItemTemplateById200JSONResponse ChecklistItemTemplateResponse + +func (response UpdateChecklistItemTemplateById200JSONResponse) VisitUpdateChecklistItemTemplateByIdResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + + return json.NewEncoder(w).Encode(response) +} + +type UpdateChecklistItemTemplateById404JSONResponse Error + +func (response UpdateChecklistItemTemplateById404JSONResponse) VisitUpdateChecklistItemTemplateByIdResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(404) + + return json.NewEncoder(w).Encode(response) +} + +type UpdateChecklistItemTemplateById500JSONResponse Error + +func (response UpdateChecklistItemTemplateById500JSONResponse) VisitUpdateChecklistItemTemplateByIdResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + +// StrictServerInterface represents all server handlers. +type StrictServerInterface interface { + // Get all checklist item templates + // (GET /api/v1/checklist-item-templates) + GetAllChecklistItemTemplates(ctx context.Context, request GetAllChecklistItemTemplatesRequestObject) (GetAllChecklistItemTemplatesResponseObject, error) + // Create checklist item template + // (POST /api/v1/checklist-item-templates) + CreateChecklistItemTemplate(ctx context.Context, request CreateChecklistItemTemplateRequestObject) (CreateChecklistItemTemplateResponseObject, error) + // Delete checklist item template by ID + // (DELETE /api/v1/checklist-item-templates/{templateId}) + DeleteChecklistItemTemplateById(ctx context.Context, request DeleteChecklistItemTemplateByIdRequestObject) (DeleteChecklistItemTemplateByIdResponseObject, error) + // Get checklist item template by ID + // (GET /api/v1/checklist-item-templates/{templateId}) + GetChecklistItemTemplateById(ctx context.Context, request GetChecklistItemTemplateByIdRequestObject) (GetChecklistItemTemplateByIdResponseObject, error) + // Update checklist item template by ID + // (PUT /api/v1/checklist-item-templates/{templateId}) + UpdateChecklistItemTemplateById(ctx context.Context, request UpdateChecklistItemTemplateByIdRequestObject) (UpdateChecklistItemTemplateByIdResponseObject, error) +} + +type StrictHandlerFunc = strictgin.StrictGinHandlerFunc +type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc + +func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { + return &strictHandler{ssi: ssi, middlewares: middlewares} +} + +type strictHandler struct { + ssi StrictServerInterface + middlewares []StrictMiddlewareFunc +} + +// GetAllChecklistItemTemplates operation middleware +func (sh *strictHandler) GetAllChecklistItemTemplates(ctx *gin.Context) { + var request GetAllChecklistItemTemplatesRequestObject + + handler := func(ctx *gin.Context, request interface{}) (interface{}, error) { + return sh.ssi.GetAllChecklistItemTemplates(ctx, request.(GetAllChecklistItemTemplatesRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetAllChecklistItemTemplates") + } + + response, err := handler(ctx, request) + + if err != nil { + ctx.Error(err) + ctx.Status(http.StatusInternalServerError) + } else if validResponse, ok := response.(GetAllChecklistItemTemplatesResponseObject); ok { + if err := validResponse.VisitGetAllChecklistItemTemplatesResponse(ctx.Writer); err != nil { + ctx.Error(err) + } + } else if response != nil { + ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + } +} + +// CreateChecklistItemTemplate operation middleware +func (sh *strictHandler) CreateChecklistItemTemplate(ctx *gin.Context) { + var request CreateChecklistItemTemplateRequestObject + + var body CreateChecklistItemTemplateJSONRequestBody + if err := ctx.ShouldBindJSON(&body); err != nil { + ctx.Status(http.StatusBadRequest) + ctx.Error(err) + return + } + request.Body = &body + + handler := func(ctx *gin.Context, request interface{}) (interface{}, error) { + return sh.ssi.CreateChecklistItemTemplate(ctx, request.(CreateChecklistItemTemplateRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "CreateChecklistItemTemplate") + } + + response, err := handler(ctx, request) + + if err != nil { + ctx.Error(err) + ctx.Status(http.StatusInternalServerError) + } else if validResponse, ok := response.(CreateChecklistItemTemplateResponseObject); ok { + if err := validResponse.VisitCreateChecklistItemTemplateResponse(ctx.Writer); err != nil { + ctx.Error(err) + } + } else if response != nil { + ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + } +} + +// DeleteChecklistItemTemplateById operation middleware +func (sh *strictHandler) DeleteChecklistItemTemplateById(ctx *gin.Context, templateId uint) { + var request DeleteChecklistItemTemplateByIdRequestObject + + request.TemplateId = templateId + + handler := func(ctx *gin.Context, request interface{}) (interface{}, error) { + return sh.ssi.DeleteChecklistItemTemplateById(ctx, request.(DeleteChecklistItemTemplateByIdRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "DeleteChecklistItemTemplateById") + } + + response, err := handler(ctx, request) + + if err != nil { + ctx.Error(err) + ctx.Status(http.StatusInternalServerError) + } else if validResponse, ok := response.(DeleteChecklistItemTemplateByIdResponseObject); ok { + if err := validResponse.VisitDeleteChecklistItemTemplateByIdResponse(ctx.Writer); err != nil { + ctx.Error(err) + } + } else if response != nil { + ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetChecklistItemTemplateById operation middleware +func (sh *strictHandler) GetChecklistItemTemplateById(ctx *gin.Context, templateId uint) { + var request GetChecklistItemTemplateByIdRequestObject + + request.TemplateId = templateId + + handler := func(ctx *gin.Context, request interface{}) (interface{}, error) { + return sh.ssi.GetChecklistItemTemplateById(ctx, request.(GetChecklistItemTemplateByIdRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetChecklistItemTemplateById") + } + + response, err := handler(ctx, request) + + if err != nil { + ctx.Error(err) + ctx.Status(http.StatusInternalServerError) + } else if validResponse, ok := response.(GetChecklistItemTemplateByIdResponseObject); ok { + if err := validResponse.VisitGetChecklistItemTemplateByIdResponse(ctx.Writer); err != nil { + ctx.Error(err) + } + } else if response != nil { + ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + } +} + +// UpdateChecklistItemTemplateById operation middleware +func (sh *strictHandler) UpdateChecklistItemTemplateById(ctx *gin.Context, templateId uint) { + var request UpdateChecklistItemTemplateByIdRequestObject + + request.TemplateId = templateId + + var body UpdateChecklistItemTemplateByIdJSONRequestBody + if err := ctx.ShouldBindJSON(&body); err != nil { + ctx.Status(http.StatusBadRequest) + ctx.Error(err) + return + } + request.Body = &body + + handler := func(ctx *gin.Context, request interface{}) (interface{}, error) { + return sh.ssi.UpdateChecklistItemTemplateById(ctx, request.(UpdateChecklistItemTemplateByIdRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "UpdateChecklistItemTemplateById") + } + + response, err := handler(ctx, request) + + if err != nil { + ctx.Error(err) + ctx.Status(http.StatusInternalServerError) + } else if validResponse, ok := response.(UpdateChecklistItemTemplateByIdResponseObject); ok { + if err := validResponse.VisitUpdateChecklistItemTemplateByIdResponse(ctx.Writer); err != nil { + ctx.Error(err) + } + } else if response != nil { + ctx.Error(fmt.Errorf("unexpected response type: %T", response)) + } +} diff --git a/openapi/api_v1.yaml b/openapi/api_v1.yaml index 64ac26d..ce427cf 100644 --- a/openapi/api_v1.yaml +++ b/openapi/api_v1.yaml @@ -625,6 +625,162 @@ paths: + /api/v1/checklist-item-templates: + get: + summary: Get all checklist item templates + operationId: getAllChecklistItemTemplates + tags: + - checklistItemTemplate + responses: + '200': + description: A list of checklist item templates + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/ChecklistItemTemplateResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + post: + summary: Create checklist item template + operationId: createChecklistItemTemplate + tags: + - checklistItemTemplate + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateChecklistItemTemplateRequest' + responses: + '201': + description: Checklist item template created + content: + application/json: + schema: + $ref: '#/components/schemas/ChecklistItemTemplateResponse' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/v1/checklist-item-templates/{templateId}: + get: + summary: Get checklist item template by ID + operationId: getChecklistItemTemplateById + tags: + - checklistItemTemplate + parameters: + - name: templateId + in: path + required: true + schema: + type: number + x-go-type: uint + minimum: 1 + format: int64 + description: Checklist item template ID + responses: + '200': + description: A checklist item template + content: + application/json: + schema: + $ref: '#/components/schemas/ChecklistItemTemplateResponse' + '404': + description: Checklist item template not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + put: + summary: Update checklist item template by ID + operationId: updateChecklistItemTemplateById + tags: + - checklistItemTemplate + parameters: + - name: templateId + in: path + required: true + schema: + type: number + x-go-type: uint + minimum: 1 + format: int64 + description: Checklist item template ID + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateChecklistItemTemplateRequest' + responses: + '200': + description: Checklist item template updated + content: + application/json: + schema: + $ref: '#/components/schemas/ChecklistItemTemplateResponse' + '404': + description: Checklist item template not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + delete: + summary: Delete checklist item template by ID + operationId: deleteChecklistItemTemplateById + tags: + - checklistItemTemplate + parameters: + - name: templateId + in: path + required: true + schema: + type: number + x-go-type: uint + minimum: 1 + format: int64 + description: Checklist item template ID + responses: + '204': + description: Checklist item template deleted + '404': + description: Checklist item template not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' components: schemas: Error: @@ -800,3 +956,55 @@ components: - name - id + CreateChecklistItemTemplateRequest: + type: object + properties: + rows: + type: array + items: + $ref: '#/components/schemas/ChecklistItemTemplateRow' + required: + - rows + UpdateChecklistItemTemplateRequest: + type: object + properties: + id: + type: number + x-go-type: uint + nullable: false + format: int64 + minimum: 1 + rows: + type: array + items: + $ref: '#/components/schemas/ChecklistItemTemplateRow' + required: + - id + - rows + ChecklistItemTemplateResponse: + type: object + properties: + id: + type: number + x-go-type: uint + nullable: false + format: int64 + minimum: 1 + rows: + type: array + items: + $ref: '#/components/schemas/ChecklistItemTemplateRow' + required: + - id + - rows + ChecklistItemTemplateRow: + type: object + properties: + id: + type: number + x-go-type: uint + nullable: false + format: int64 + minimum: 1 + required: + - id