package main import ( "database/sql/driver" "encoding/json" "time" "github.com/google/uuid" "gorm.io/gorm" ) // JSON is a generic JSON column type for GORM. type JSON json.RawMessage func (j JSON) Value() (driver.Value, error) { if len(j) == 0 { return nil, nil } return []byte(j), nil } func (j *JSON) Scan(value interface{}) error { if value == nil { *j = JSON("null") return nil } switch v := value.(type) { case []byte: *j = JSON(v) case string: *j = JSON(v) } return nil } func (j JSON) MarshalJSON() ([]byte, error) { if len(j) == 0 { return []byte("null"), nil } return []byte(j), nil } func (j *JSON) UnmarshalJSON(data []byte) error { *j = JSON(data) return nil } func (JSON) GormDataType() string { return "jsonb" } // Base fields shared by all models. type Base struct { ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at"` } type Template struct { Base Name string `json:"name"` Description *string `json:"description"` Elements JSON `gorm:"type:jsonb" json:"elements"` Order float64 `gorm:"default:0" json:"order"` GroupID *uuid.UUID `gorm:"type:uuid" json:"group_id"` Group *Group `gorm:"foreignKey:GroupID" json:"group,omitempty"` Files []File `gorm:"foreignKey:TemplateID;constraint:OnDelete:CASCADE" json:"files,omitempty"` Sheets []Sheet `gorm:"foreignKey:TemplateID;constraint:OnDelete:CASCADE" json:"sheets,omitempty"` TemplateAttributes []TemplateAttribute `gorm:"foreignKey:TemplateID;constraint:OnDelete:CASCADE" json:"template_attributes,omitempty"` } type File struct { Base Name string `json:"name"` Content []byte `gorm:"type:bytea" json:"-"` Cells JSON `gorm:"type:jsonb" json:"cells"` TemplateID *uuid.UUID `gorm:"type:uuid" json:"template_id"` Template *Template `gorm:"foreignKey:TemplateID" json:"template,omitempty"` } type Sheet struct { Base Name string `json:"name"` Cells JSON `gorm:"type:jsonb" json:"cells"` TemplateID uuid.UUID `gorm:"type:uuid" json:"template_id"` Template *Template `gorm:"foreignKey:TemplateID" json:"template,omitempty"` } type Attribute struct { Base Name string `json:"name"` IsRequired bool `json:"is_required"` TemplateAttributes []TemplateAttribute `gorm:"foreignKey:AttributeID" json:"template_attributes,omitempty"` } type TemplateAttribute struct { TemplateID uuid.UUID `gorm:"type:uuid;primaryKey" json:"template_id"` AttributeID uuid.UUID `gorm:"type:uuid;primaryKey" json:"attribute_id"` Value *string `json:"value"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` Template *Template `gorm:"foreignKey:TemplateID" json:"template,omitempty"` Attribute *Attribute `gorm:"foreignKey:AttributeID" json:"attribute,omitempty"` } type Standard struct { Base Name string `json:"name"` ProtocolName string `json:"protocol_name"` RegistryNumber string `json:"registry_number"` Range string `json:"range"` Accuracy string `json:"accuracy"` ValidUntil time.Time `gorm:"type:date" json:"valid_until"` } type Group struct { Base Name string `json:"name"` Order float64 `gorm:"default:0" json:"order"` IsVisible bool `gorm:"default:true" json:"is_visible"` Templates []Template `gorm:"foreignKey:GroupID" json:"templates,omitempty"` } type Laboratory struct { Base Name string `json:"name"` ConditionTypes []ConditionType `gorm:"many2many:laboratory_condition_type" json:"condition_types"` DailyConditions []DailyCondition `gorm:"foreignKey:LaboratoryID;constraint:OnDelete:CASCADE" json:"daily_conditions,omitempty"` } func (Laboratory) TableName() string { return "laboratorys" } type ConditionType struct { Base Name string `json:"name"` Unit string `json:"unit"` Laboratories []Laboratory `gorm:"many2many:laboratory_condition_type" json:"laboratories,omitempty"` } func (ConditionType) TableName() string { return "conditiontypes" } type DailyCondition struct { Base LaboratoryID uuid.UUID `gorm:"type:uuid" json:"laboratory_id"` MeasurementDate time.Time `gorm:"type:date" json:"measurement_date"` Conditions JSON `gorm:"type:jsonb" json:"conditions"` Laboratory *Laboratory `gorm:"foreignKey:LaboratoryID" json:"laboratory,omitempty"` } func (DailyCondition) TableName() string { return "daily_conditions" }