Files
Gardomatic/lib/client/models.go
T
2026-09-16 20:21:41 +02:00

649 lines
28 KiB
Go

package client
import (
"encoding/json"
"time"
)
// User is the public user representation returned by the API.
type User struct {
ID int `json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Name string `json:"name"`
Email string `json:"email"`
Color string `json:"color"`
Activated bool `json:"activated"`
Role string `json:"role"`
Permissions []string `json:"permissions"`
}
// AdminUserInviteInput contains the identity fields for an administrator-created
// account invitation.
type AdminUserInviteInput struct {
Name string `json:"name"`
Email string `json:"email"`
}
// IsAdmin reports whether the user can manage application roles.
func (user User) IsAdmin() bool { return user.Can("roles:manage") }
// Can reports whether the API-resolved application permissions contain permission.
func (user User) Can(permission string) bool {
for _, granted := range user.Permissions {
if granted == permission || granted == "*" {
return true
}
}
return false
}
// AccountSession describes one server-side login session for the current user.
type AccountSession struct {
ID string `json:"id"`
CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"`
Current bool `json:"current"`
}
// Garden is the public garden representation returned by the API.
type Garden struct {
ID int `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
ImageData string `json:"image_data,omitempty"`
ImageID *int `json:"image_id,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
Role string `json:"role"`
Permissions []string `json:"permissions"`
}
// Can reports whether the authenticated member has a concrete permission in
// this garden. The API resolves role defaults and garden-specific overrides.
func (garden Garden) Can(permission string) bool {
for _, granted := range garden.Permissions {
if granted == permission || granted == "*" || granted == "garden:*" && permission != "garden:delete" {
return true
}
}
if garden.Permissions != nil {
return false
}
// Compatibility for older API responses. Custom roles deliberately have no
// fallback: their effective permissions must always come from the API.
switch garden.Role {
case "owner":
return validLegacyGardenPermission(permission)
case "admin":
return validLegacyGardenPermission(permission) && permission != "garden:delete"
case "member":
switch permission {
case "garden:read", "content:write",
"plants:create", "plants:read:own", "plants:read:other", "plants:update:own", "plants:delete:own",
"locations:create", "locations:read:own", "locations:read:other", "locations:update:own", "locations:delete:own",
"tasks:create", "tasks:read:own", "tasks:read:other", "tasks:update:own", "tasks:delete:own", "tasks:complete:own", "tasks:complete:other":
return true
}
case "viewer":
return permission == "garden:read" || permission == "plants:read:own" || permission == "plants:read:other" ||
permission == "locations:read:own" || permission == "locations:read:other" || permission == "tasks:read:own" || permission == "tasks:read:other"
case "worker":
return permission == "garden:read" || permission == "tasks:read:own" || permission == "tasks:read:other" ||
permission == "tasks:complete:own" || permission == "tasks:complete:other"
}
return false
}
func validLegacyGardenPermission(permission string) bool {
switch permission {
case "garden:read", "garden:update", "garden:delete", "content:write", "members:write", "species:write",
"plants:create", "plants:read:own", "plants:read:other", "plants:update:own", "plants:update:other", "plants:delete:own", "plants:delete:other",
"locations:create", "locations:read:own", "locations:read:other", "locations:update:own", "locations:update:other", "locations:delete:own", "locations:delete:other",
"tasks:create", "tasks:read:own", "tasks:read:other", "tasks:update:own", "tasks:update:other", "tasks:delete:own", "tasks:delete:other", "tasks:complete:own", "tasks:complete:other":
return true
}
return false
}
// GardenMember describes a user's role within one garden.
type GardenMember struct {
GardenID int `json:"garden_id"`
UserID int `json:"user_id"`
Role string `json:"role"`
JoinedAt time.Time `json:"joined_at"`
Name string `json:"name"`
Email string `json:"email"`
}
// GardenInvite describes a pending invitation to a garden.
type GardenInvite struct {
ID int `json:"id"`
GardenID int `json:"garden_id"`
Email string `json:"email"`
Role string `json:"role"`
InvitedBy int `json:"invited_by"`
ExpiresAt time.Time `json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
}
// GardenInviteInput contains the recipient and role for a garden invitation.
type GardenInviteInput struct {
Email string `json:"email"`
Role string `json:"role"`
}
// Role is an application or garden role with its base permissions.
type Role struct {
Name string `json:"name"`
Scope string `json:"scope"`
GardenID *int `json:"garden_id,omitempty"`
Label string `json:"label"`
System bool `json:"system"`
Permissions []string `json:"permissions"`
}
// RoleInput contains writable role fields.
type RoleInput struct {
Name string `json:"name,omitempty"`
Scope string `json:"scope,omitempty"`
Label string `json:"label"`
Permissions []string `json:"permissions"`
}
// GardenRoleSetting combines a role template with its effective permissions in
// one garden.
type GardenRoleSetting struct {
Role Role `json:"role"`
EffectivePermissions []string `json:"effective_permissions"`
}
// CreateGardenInput contains writable fields for a new garden.
type CreateGardenInput struct {
Name string `json:"name"`
Description string `json:"description"`
ImageData string `json:"image_data,omitempty"`
ImageID *int `json:"image_id,omitempty"`
}
// UpdateGardenInput contains optional garden fields for a partial update.
type UpdateGardenInput struct {
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
ImageData *string `json:"image_data,omitempty"`
ImageID *int `json:"image_id,omitempty"`
}
// Species describes global or garden-specific plant master data.
type Species struct {
ID int `json:"id"`
GardenID *int `json:"garden_id,omitempty"`
CommonName string `json:"common_name"`
Cultivar string `json:"cultivar"`
BotanicalName string `json:"botanical_name"`
CategoryID *int `json:"category_id,omitempty"`
Category string `json:"category"`
SunExposure *string `json:"sun_exposure,omitempty"`
SoilCondition *string `json:"soil_condition,omitempty"`
SoilReaction *string `json:"soil_reaction,omitempty"`
WinterProtection *string `json:"winter_protection,omitempty"`
SpacingCM *int `json:"spacing_cm,omitempty"`
// HeightCM is retained as a deprecated API alias for HeightCMTo.
HeightCM *int `json:"height_cm,omitempty"`
HeightCMFrom *int `json:"height_cm_from,omitempty"`
HeightCMTo *int `json:"height_cm_to,omitempty"`
WidthCMFrom *int `json:"width_cm_from,omitempty"`
WidthCMTo *int `json:"width_cm_to,omitempty"`
SowMonthFrom *int `json:"sow_month_from,omitempty"`
SowDayFrom *int `json:"sow_day_from,omitempty"`
SowMonthTo *int `json:"sow_month_to,omitempty"`
SowDayTo *int `json:"sow_day_to,omitempty"`
PlantingMonthFrom *int `json:"planting_month_from,omitempty"`
PlantingDayFrom *int `json:"planting_day_from,omitempty"`
PlantingMonthTo *int `json:"planting_month_to,omitempty"`
PlantingDayTo *int `json:"planting_day_to,omitempty"`
HarvestMonthFrom *int `json:"harvest_month_from,omitempty"`
HarvestDayFrom *int `json:"harvest_day_from,omitempty"`
HarvestMonthTo *int `json:"harvest_month_to,omitempty"`
HarvestDayTo *int `json:"harvest_day_to,omitempty"`
Notes string `json:"notes"`
ImageData string `json:"image_data,omitempty"`
ImageID *int `json:"image_id,omitempty"`
Attributes json.RawMessage `json:"attributes"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
Tags []string `json:"tags,omitempty"`
CreatedBy int `json:"created_by"`
UpdatedBy int `json:"updated_by"`
}
// SpeciesInput contains optional species fields used for creation and updates.
type SpeciesInput struct {
Global bool `json:"global,omitempty"`
Tags []string `json:"tags,omitempty"`
CommonName *string `json:"common_name,omitempty"`
Cultivar *string `json:"cultivar,omitempty"`
BotanicalName *string `json:"botanical_name,omitempty"`
CategoryID *int `json:"category_id,omitempty"`
ClearCategoryID bool `json:"clear_category_id,omitempty"`
SunExposure *string `json:"sun_exposure,omitempty"`
SoilCondition *string `json:"soil_condition,omitempty"`
SoilReaction *string `json:"soil_reaction,omitempty"`
WinterProtection *string `json:"winter_protection,omitempty"`
SpacingCM *int `json:"spacing_cm,omitempty"`
// HeightCM is retained for compatibility; new code should use HeightCMTo.
HeightCM *int `json:"height_cm,omitempty"`
HeightCMFrom *int `json:"height_cm_from,omitempty"`
HeightCMTo *int `json:"height_cm_to,omitempty"`
WidthCMFrom *int `json:"width_cm_from,omitempty"`
WidthCMTo *int `json:"width_cm_to,omitempty"`
ClearHeightCMFrom bool `json:"clear_height_cm_from,omitempty"`
ClearHeightCMTo bool `json:"clear_height_cm_to,omitempty"`
ClearWidthCMFrom bool `json:"clear_width_cm_from,omitempty"`
ClearWidthCMTo bool `json:"clear_width_cm_to,omitempty"`
SowMonthFrom *int `json:"sow_month_from,omitempty"`
SowDayFrom *int `json:"sow_day_from,omitempty"`
ClearSowDayFrom bool `json:"clear_sow_day_from,omitempty"`
SowMonthTo *int `json:"sow_month_to,omitempty"`
SowDayTo *int `json:"sow_day_to,omitempty"`
ClearSowDayTo bool `json:"clear_sow_day_to,omitempty"`
PlantingMonthFrom *int `json:"planting_month_from,omitempty"`
PlantingDayFrom *int `json:"planting_day_from,omitempty"`
ClearPlantingDayFrom bool `json:"clear_planting_day_from,omitempty"`
PlantingMonthTo *int `json:"planting_month_to,omitempty"`
PlantingDayTo *int `json:"planting_day_to,omitempty"`
ClearPlantingDayTo bool `json:"clear_planting_day_to,omitempty"`
HarvestMonthFrom *int `json:"harvest_month_from,omitempty"`
HarvestDayFrom *int `json:"harvest_day_from,omitempty"`
ClearHarvestDayFrom bool `json:"clear_harvest_day_from,omitempty"`
HarvestMonthTo *int `json:"harvest_month_to,omitempty"`
HarvestDayTo *int `json:"harvest_day_to,omitempty"`
ClearHarvestDayTo bool `json:"clear_harvest_day_to,omitempty"`
ClearSowRange bool `json:"clear_sow_range,omitempty"`
ClearPlantingRange bool `json:"clear_planting_range,omitempty"`
ClearHarvestRange bool `json:"clear_harvest_range,omitempty"`
Notes *string `json:"notes,omitempty"`
ImageData *string `json:"image_data,omitempty"`
ImageID *int `json:"image_id,omitempty"`
Attributes json.RawMessage `json:"attributes,omitempty"`
}
// SpeciesCategory classifies species and optionally supplies a lifecycle.
type SpeciesCategory struct {
ID int `json:"id"`
Name string `json:"name"`
SortOrder int `json:"sort_order"`
Active bool `json:"active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
Lifecycle *string `json:"lifecycle,omitempty"`
}
// SpeciesCategoryInput contains writable category fields.
type SpeciesCategoryInput struct {
Name *string `json:"name,omitempty"`
SortOrder *int `json:"sort_order,omitempty"`
Active *bool `json:"active,omitempty"`
Lifecycle *string `json:"lifecycle,omitempty"`
}
// TaskPriority maps a display name to the numeric priority stored on tasks.
type TaskPriority struct {
ID int `json:"id"`
Name string `json:"name"`
Value int `json:"value"`
SortOrder int `json:"sort_order"`
Active bool `json:"active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
}
// TaskPriorityInput contains writable priority-catalogue fields.
type TaskPriorityInput struct {
Name *string `json:"name,omitempty"`
Value *int `json:"value,omitempty"`
SortOrder *int `json:"sort_order,omitempty"`
Active *bool `json:"active,omitempty"`
}
// Plant represents a plant instance owned by a garden.
type Plant struct {
ID int `json:"id"`
GardenID int `json:"garden_id"`
SpeciesID *int `json:"species_id,omitempty"`
Name string `json:"name"`
Notes string `json:"notes"`
ImageData string `json:"image_data,omitempty"`
ImageID *int `json:"image_id,omitempty"`
AcquiredAt *time.Time `json:"acquired_at,omitempty"`
Status string `json:"status"`
RemovedAt *time.Time `json:"removed_at,omitempty"`
Attributes json.RawMessage `json:"attributes"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
Tags []string `json:"tags,omitempty"`
CreatedBy int `json:"created_by"`
UpdatedBy int `json:"updated_by"`
PlantedBy int `json:"planted_by"`
PlantedByName string `json:"planted_by_name,omitempty"`
}
// PlantInput contains optional plant fields used for creation and updates.
type PlantInput struct {
Tags []string `json:"tags,omitempty"`
SpeciesID *int `json:"species_id,omitempty"`
ClearSpeciesID bool `json:"clear_species_id,omitempty"`
Name *string `json:"name,omitempty"`
Notes *string `json:"notes,omitempty"`
ImageData *string `json:"image_data,omitempty"`
ImageID *int `json:"image_id,omitempty"`
AcquiredAt *time.Time `json:"acquired_at,omitempty"`
ClearAcquiredAt bool `json:"clear_acquired_at,omitempty"`
Status *string `json:"status,omitempty"`
RemovedAt *time.Time `json:"removed_at,omitempty"`
Attributes json.RawMessage `json:"attributes,omitempty"`
}
// Location describes a hierarchical place within a garden.
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"`
}
// LocationInput contains optional location fields used for creation and updates.
type LocationInput struct {
ParentID *int `json:"parent_id,omitempty"`
ClearParentID bool `json:"clear_parent_id,omitempty"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
ImageData *string `json:"image_data,omitempty"`
ImageID *int `json:"image_id,omitempty"`
Kind *string `json:"kind,omitempty"`
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,omitempty"`
}
// PlantLocation represents a plant's assignment to a location.
type PlantLocation struct {
ID int `json:"id"`
PlantID int `json:"plant_id"`
LocationID int `json:"location_id"`
Quantity int `json:"quantity"`
PlantedAt *time.Time `json:"planted_at,omitempty"`
RemovedAt *time.Time `json:"removed_at,omitempty"`
Notes string `json:"notes"`
CreatedAt time.Time `json:"created_at"`
Version int `json:"version"`
}
// PlantLocationInput contains optional assignment fields used for creation and updates.
type PlantLocationInput struct {
LocationID *int `json:"location_id,omitempty"`
Quantity *int `json:"quantity,omitempty"`
PlantedAt *time.Time `json:"planted_at,omitempty"`
ClearPlantedAt bool `json:"clear_planted_at,omitempty"`
RemovedAt *time.Time `json:"removed_at,omitempty"`
Notes *string `json:"notes,omitempty"`
}
// Task represents a manual or generated garden work item.
type Task struct {
ID int `json:"id"`
GardenID int `json:"garden_id"`
PlantID *int `json:"plant_id,omitempty"`
LocationID *int `json:"location_id,omitempty"`
TemplateID *int `json:"template_id,omitempty"`
Title string `json:"title"`
Description string `json:"description"`
DueAtStart *time.Time `json:"due_at_start,omitempty"`
DueAtEnd *time.Time `json:"due_at_end,omitempty"`
GeneratedFor *time.Time `json:"generated_for,omitempty"`
Recurrence string `json:"recurrence,omitempty"`
RecurrenceInterval int `json:"recurrence_interval"`
RepeatFromID *int `json:"repeat_from_id,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
CompletedBy *int `json:"completed_by,omitempty"`
Priority int `json:"priority"`
Active *bool `json:"active,omitempty"`
CreatedBy int `json:"created_by"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
Tags []string `json:"tags,omitempty"`
PlantStatusOnCompletion *string `json:"plant_status_on_completion,omitempty"`
}
// TaskInput contains writable fields for task creation and partial updates.
type TaskInput struct {
Tags []string `json:"tags,omitempty"`
PlantID *int `json:"plant_id,omitempty"`
LocationID *int `json:"location_id,omitempty"`
ClearPlantID bool `json:"clear_plant_id,omitempty"`
ClearLocationID bool `json:"clear_location_id,omitempty"`
Title *string `json:"title,omitempty"`
Description *string `json:"description,omitempty"`
DueAtStart *time.Time `json:"due_at_start,omitempty"`
DueAtEnd *time.Time `json:"due_at_end,omitempty"`
ClearDueAtStart bool `json:"clear_due_at_start,omitempty"`
ClearDueAtEnd bool `json:"clear_due_at_end,omitempty"`
Recurrence *string `json:"recurrence,omitempty"`
RecurrenceInterval *int `json:"recurrence_interval,omitempty"`
Priority *int `json:"priority,omitempty"`
Active *bool `json:"active,omitempty"`
Completed *bool `json:"completed,omitempty"`
PlantStatusOnCompletion *string `json:"plant_status_on_completion,omitempty"`
}
// CareInstruction is garden-specific cultivation guidance for a species.
type CareInstruction struct {
ID int `json:"id"`
SpeciesID int `json:"species_id"`
Text string `json:"text"`
Status string `json:"status"`
CreatedBy int `json:"created_by"`
UpdatedBy int `json:"updated_by"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
}
// CareInstructionInput contains writable care-instruction fields.
type CareInstructionInput struct {
Text *string `json:"text,omitempty"`
Status *string `json:"status,omitempty"`
}
// JournalEntry is a garden journal or pinboard entry with related media.
type JournalEntry struct {
ID int `json:"id"`
GardenID int `json:"garden_id"`
AuthorID int `json:"author_id"`
AuthorName string `json:"author_name"`
AuthorColor string `json:"author_color"`
EntryType string `json:"entry_type"`
Title string `json:"title"`
Body string `json:"body"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
Tags []string `json:"tags,omitempty"`
Attachments []JournalAttachment `json:"attachments,omitempty"`
}
// JournalEntryInput contains writable journal-entry fields.
type JournalEntryInput struct {
Title *string `json:"title,omitempty"`
Body *string `json:"body,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
Tags []string `json:"tags,omitempty"`
EntryType *string `json:"entry_type,omitempty"`
}
// JournalAttachment describes attachment metadata without its binary body.
type JournalAttachment struct {
ID int `json:"id"`
EntryID int `json:"entry_id"`
FileName string `json:"file_name"`
MediaType string `json:"media_type"`
Size int64 `json:"size"`
CreatedAt time.Time `json:"created_at"`
ImageID *int `json:"image_id,omitempty"`
}
// JournalAttachmentData combines attachment metadata with its binary body.
type JournalAttachmentData struct {
JournalAttachment
Data []byte
}
// SpeciesTaskTemplate describes a rule for generating tasks from species data.
type SpeciesTaskTemplate struct {
ID int `json:"id"`
SpeciesID int `json:"species_id"`
Origin string `json:"origin"`
Title string `json:"title"`
Description string `json:"description"`
TriggerType string `json:"trigger_type"`
MonthFrom *int `json:"month_from,omitempty"`
DayFrom *int `json:"day_from,omitempty"`
MonthTo *int `json:"month_to,omitempty"`
DayTo *int `json:"day_to,omitempty"`
OffsetDaysFrom *int `json:"offset_days_from,omitempty"`
OffsetDaysTo *int `json:"offset_days_to,omitempty"`
IntervalDays *int `json:"interval_days,omitempty"`
TriggerOffset int `json:"trigger_offset"`
TriggerOffsetUnit string `json:"trigger_offset_unit"`
Duration int `json:"duration"`
DurationUnit string `json:"duration_unit"`
Recurrence string `json:"recurrence,omitempty"`
RecurrenceInterval int `json:"recurrence_interval"`
Priority int `json:"priority"`
Active bool `json:"active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
}
// ApplicationSettings contains application-wide lifecycle automation settings.
type ApplicationSettings struct {
LifecycleStatusEnabled bool `json:"lifecycle_status_enabled"`
LifecycleRemovalMonth int `json:"lifecycle_removal_month"`
LifecycleRemovalDay int `json:"lifecycle_removal_day"`
Timezone string `json:"timezone"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
}
// ApplicationSettingsInput contains writable lifecycle automation settings.
type ApplicationSettingsInput struct {
LifecycleStatusEnabled *bool `json:"lifecycle_status_enabled,omitempty"`
LifecycleRemovalMonth *int `json:"lifecycle_removal_month,omitempty"`
LifecycleRemovalDay *int `json:"lifecycle_removal_day,omitempty"`
Timezone *string `json:"timezone,omitempty"`
}
// EnvironmentVariable describes one effective process configuration value.
// Sensitive values are masked by the API before they leave the process.
type EnvironmentVariable struct {
Component string `json:"component"`
Name string `json:"name"`
Value string `json:"value"`
}
// SpeciesTaskTemplateInput contains writable task-template fields.
type SpeciesTaskTemplateInput struct {
Title *string `json:"title,omitempty"`
Description *string `json:"description,omitempty"`
TriggerType *string `json:"trigger_type,omitempty"`
MonthFrom *int `json:"month_from,omitempty"`
DayFrom *int `json:"day_from,omitempty"`
ClearDayFrom bool `json:"clear_day_from,omitempty"`
MonthTo *int `json:"month_to,omitempty"`
DayTo *int `json:"day_to,omitempty"`
ClearDayTo bool `json:"clear_day_to,omitempty"`
OffsetDaysFrom *int `json:"offset_days_from,omitempty"`
OffsetDaysTo *int `json:"offset_days_to,omitempty"`
IntervalDays *int `json:"interval_days,omitempty"`
ClearIntervalDays bool `json:"clear_interval_days,omitempty"`
TriggerOffset *int `json:"trigger_offset,omitempty"`
TriggerOffsetUnit *string `json:"trigger_offset_unit,omitempty"`
Duration *int `json:"duration,omitempty"`
DurationUnit *string `json:"duration_unit,omitempty"`
Recurrence *string `json:"recurrence,omitempty"`
RecurrenceInterval *int `json:"recurrence_interval,omitempty"`
Priority *int `json:"priority,omitempty"`
Active *bool `json:"active,omitempty"`
}
// Credentials contains email and password authentication input.
type Credentials struct {
Email string `json:"email"`
Password string `json:"password"`
}
// RegisterUserInput contains the fields required to register an account.
type RegisterUserInput struct {
Name string `json:"name"`
Email string `json:"email"`
Password string `json:"password"`
}
// TokenInput wraps a plaintext activation or reset token.
type TokenInput struct {
Token string `json:"token"`
}
// EmailInput wraps an email address for token requests.
type EmailInput struct {
Email string `json:"email"`
}
// UpdatePasswordInput contains a new password and its reset token.
type UpdatePasswordInput struct {
Password string `json:"password"`
Token string `json:"token"`
}
// AuthenticationToken is a bearer token and its expiration time.
type AuthenticationToken struct {
Token string `json:"token"`
Expiry time.Time `json:"expiry"`
}
// Health describes API availability and build information.
type Health struct {
Status string `json:"status"`
ServerTime time.Time `json:"server_time"`
SystemInfo SystemInfo `json:"system_info"`
}
// SystemInfo identifies the running API environment and version.
type SystemInfo struct {
Environment string `json:"environment"`
Version string `json:"version"`
}