From d42f1fc3cf11070066ba5f9a77288431ee62d67e Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Mon, 20 Mar 2023 21:18:53 -0800 Subject: [PATCH] #352 - require one date to be set to save --- .../data/repo/repo_maintenance_entry.go | 48 ++++++++++++------- backend/internal/web/adapters/decoders.go | 23 ++++++--- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/backend/internal/data/repo/repo_maintenance_entry.go b/backend/internal/data/repo/repo_maintenance_entry.go index 7ef282b..daf7887 100644 --- a/backend/internal/data/repo/repo_maintenance_entry.go +++ b/backend/internal/data/repo/repo_maintenance_entry.go @@ -2,6 +2,7 @@ package repo import ( "context" + "errors" "time" "github.com/google/uuid" @@ -18,15 +19,38 @@ import ( type MaintenanceEntryRepository struct { db *ent.Client } -type ( - MaintenanceEntryCreate struct { - CompletedDate types.Date `json:"completedDate"` - ScheduledDate types.Date `json:"scheduledDate"` - Name string `json:"name"` - Description string `json:"description"` - Cost float64 `json:"cost,string"` - } +type MaintenanceEntryCreate struct { + CompletedDate types.Date `json:"completedDate"` + ScheduledDate types.Date `json:"scheduledDate"` + Name string `json:"name" validate:"required"` + Description string `json:"description"` + Cost float64 `json:"cost,string"` +} + +func (mc MaintenanceEntryCreate) Validate() error { + if mc.CompletedDate.Time().IsZero() && mc.ScheduledDate.Time().IsZero() { + return errors.New("either completedDate or scheduledDate must be set") + } + return nil +} + +type MaintenanceEntryUpdate struct { + CompletedDate types.Date `json:"completedDate"` + ScheduledDate types.Date `json:"scheduledDate"` + Name string `json:"name"` + Description string `json:"description"` + Cost float64 `json:"cost,string"` +} + +func (mu MaintenanceEntryUpdate) Validate() error { + if mu.CompletedDate.Time().IsZero() && mu.ScheduledDate.Time().IsZero() { + return errors.New("either completedDate or scheduledDate must be set") + } + return nil +} + +type ( MaintenanceEntry struct { ID uuid.UUID `json:"id"` CompletedDate types.Date `json:"completedDate"` @@ -36,14 +60,6 @@ type ( Cost float64 `json:"cost,string"` } - MaintenanceEntryUpdate struct { - CompletedDate types.Date `json:"completedDate"` - ScheduledDate types.Date `json:"scheduledDate"` - Name string `json:"name"` - Description string `json:"description"` - Cost float64 `json:"cost,string"` - } - MaintenanceLog struct { ItemID uuid.UUID `json:"itemId"` CostAverage float64 `json:"costAverage"` diff --git a/backend/internal/web/adapters/decoders.go b/backend/internal/web/adapters/decoders.go index d1444ef..ef4bf6c 100644 --- a/backend/internal/web/adapters/decoders.go +++ b/backend/internal/web/adapters/decoders.go @@ -29,20 +29,31 @@ func DecodeQuery[T any](r *http.Request) (T, error) { return v, nil } +type Validator interface { + Validate() error +} + func DecodeBody[T any](r *http.Request) (T, error) { - var v T + var val T - err := server.Decode(r, &v) + err := server.Decode(r, &val) if err != nil { - return v, errors.Wrap(err, "body decoding error") + return val, errors.Wrap(err, "body decoding error") } - err = validate.Check(v) + err = validate.Check(val) if err != nil { - return v, errors.Wrap(err, "validation error") + return val, err } - return v, nil + if v, ok := any(val).(Validator); ok { + err = v.Validate() + if err != nil { + return val, errors.Wrap(err, "validation error") + } + } + + return val, nil } func RouteUUID(r *http.Request, key string) (uuid.UUID, error) {