60 lines
2.7 KiB
Go
60 lines
2.7 KiB
Go
package storage
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"time"
|
|
|
|
"gardomatic.kleiax.de/internal/platform/validate"
|
|
)
|
|
|
|
// LocationModelInterface persists hierarchical locations within a garden.
|
|
type LocationModelInterface interface {
|
|
Insert(location Location) (Location, error)
|
|
Get(gardenID, id int) (Location, error)
|
|
GetAllForGarden(gardenID int) ([]Location, error)
|
|
Update(gardenID int, location Location) (Location, error)
|
|
Delete(gardenID, id int) error
|
|
}
|
|
|
|
// ValidateLocation applies persistence-independent location validation rules.
|
|
func ValidateLocation(v *validate.Validator, location Location) {
|
|
v.Check(strings.TrimSpace(location.Name) != "", "name", "must be provided")
|
|
v.Check(len(location.Name) <= 500, "name", "must not be more than 500 bytes long")
|
|
v.Check(len(location.Description) <= 10_000, "description", "must not be more than 10000 bytes long")
|
|
v.Check(len(location.Kind) <= 100, "kind", "must not be more than 100 bytes long")
|
|
v.Check(len(location.Attributes) == 0 || json.Valid(location.Attributes), "attributes", "must be valid JSON")
|
|
if location.ParentID != nil {
|
|
v.Check(*location.ParentID > 0, "parent_id", "must be a positive integer")
|
|
v.Check(*location.ParentID != location.ID, "parent_id", "must not refer to the location itself")
|
|
}
|
|
if location.AreaSQM != nil {
|
|
v.Check(*location.AreaSQM >= 0, "area_sqm", "must be zero or greater")
|
|
}
|
|
validateOptionalEnum(v, "sun_exposure", location.SunExposure, "sunny", "partial_shade", "shade")
|
|
validateOptionalEnum(v, "soil_condition", location.SoilCondition, "dry", "moist", "boggy")
|
|
validateOptionalEnum(v, "soil_reaction", location.SoilReaction, "alkaline", "acidic", "neutral")
|
|
}
|
|
|
|
// Location describes a physical place where plants can be assigned.
|
|
type Location struct {
|
|
ID int `json:"id"`
|
|
GardenID int `json:"garden_id"`
|
|
ParentID *int `json:"parent_id,omitempty"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
ImageData string `json:"image_data,omitempty"`
|
|
ImageID *int `json:"image_id,omitempty"`
|
|
Kind string `json:"kind"`
|
|
AreaSQM *float64 `json:"area_sqm,omitempty"`
|
|
SunExposure *string `json:"sun_exposure,omitempty"`
|
|
SoilCondition *string `json:"soil_condition,omitempty"`
|
|
SoilReaction *string `json:"soil_reaction,omitempty"`
|
|
Attributes json.RawMessage `json:"attributes"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
Version int `json:"version"`
|
|
CreatedBy int `json:"created_by"`
|
|
UpdatedBy int `json:"updated_by"`
|
|
}
|