models

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 10, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package models defines the core domain types for the todo app.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Board

type Board struct {
	ID       int64  `json:"id"`
	Name     string `json:"name"`
	Position int    `json:"position"`
}

Board is a top-level grouping of todos. Each todo belongs to exactly one board; the UI shows one board at a time and lets the user switch between them via the header bar.

type CompleteTodo

type CompleteTodo struct {
	Completed bool `json:"completed"`
}

CompleteTodo is the payload for the /complete endpoint.

type CreateBoard

type CreateBoard struct {
	Name     string `json:"name"`
	Position *int   `json:"position,omitempty"`
}

CreateBoard is the payload for creating a new board.

type CreateLabel

type CreateLabel struct {
	Name string `json:"name"`
}

CreateLabel is the payload for adding a label to the predefined set.

type CreatePriority

type CreatePriority struct {
	Name string `json:"name"`
}

CreatePriority is the payload for adding a priority to the predefined set.

type CreateSavedSearch added in v0.3.0

type CreateSavedSearch struct {
	Name  string `json:"name"`
	Query string `json:"query"`
}

CreateSavedSearch is the payload for saving a filter query under a name.

type CreateTodo

type CreateTodo struct {
	BoardID     *int64      `json:"boardId,omitempty"`
	Title       string      `json:"title"`
	Description string      `json:"description"`
	ParentID    *int64      `json:"parentId,omitempty"`
	Position    *int        `json:"position,omitempty"`
	Labels      []string    `json:"labels,omitempty"`
	Priority    string      `json:"priority,omitempty"`
	DueDate     *string     `json:"dueDate,omitempty"`
	Recurrence  *Recurrence `json:"recurrence,omitempty"`
	// NoSchedule is the explicit opt-out from a server-configured default due
	// date (-default-due): this todo has no due date on purpose.
	NoSchedule bool    `json:"noSchedule,omitempty"`
	CreatedAt  *string `json:"createdAt,omitempty"`
}

CreateTodo is the payload for creating a new todo. CreatedAt is optional: absent/empty defaults the new todo's creation time to now.

type Label

type Label struct {
	Name  string `json:"name"`
	Color string `json:"color,omitempty"`
}

Label is a label with its colour. Colour is a hex string (e.g. "#ef4444") or empty when no user-defined colour is set (the client picks from a palette deterministically by name).

type LabelColor

type LabelColor struct {
	Name  string `json:"name"`
	Color string `json:"color,omitempty"`
}

LabelColor pairs a label name with its colour for inline rendering on todos.

type MoveTodo

type MoveTodo struct {
	OptionalParent
	Position *int   `json:"position,omitempty"`
	BoardID  *int64 `json:"boardId,omitempty"`
}

MoveTodo moves a todo to a new parent, position, and/or board. If Position is nil, the item is appended to the end of its sibling group. Parent embeds OptionalParent for the absent/null/value tri-state on parentId. BoardID, when set to a board other than the todo's current one, moves the todo (with its whole subtree) to that board as a root todo. A parentId value takes precedence over BoardID — a subtask always inherits its parent's board — so the two are not meant to be combined.

func (*MoveTodo) UnmarshalJSON

func (m *MoveTodo) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes position and boardId and routes parentId through OptionalParent. Without this, the promoted UnmarshalJSON would drop the position field.

type NthWeekday

type NthWeekday struct {
	N       int `json:"n"`       // 1..5, or -1 for last
	Weekday int `json:"weekday"` // 0=Sun..6=Sat
}

NthWeekday pins a recurrence to an ordinal weekday of the month, e.g. the 2nd Tuesday (N=2, Weekday=2) or the last Friday (N=-1, Weekday=5).

type OptionalParent

type OptionalParent struct {
	ID  *int64
	Set bool
}

OptionalParent captures the three-way distinction encoding/json cannot express with a single tagged pointer field when decoding parentId:

  • absent -> Set=false (leave parent unchanged)
  • null -> Set=true, ID=nil (move to root)
  • <number> -> Set=true, ID=&value (move under that parent)

Both UpdateTodo and MoveTodo embed it so the wire contract is defined once.

func (*OptionalParent) UnmarshalJSON

func (p *OptionalParent) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes parentId preserving the absent/null/value distinction.

type Priority

type Priority struct {
	Name     string `json:"name"`
	Color    string `json:"color,omitempty"`
	Position *int   `json:"position,omitempty"`
}

Priority is a priority level with its colour. Colour is a hex string (e.g. "#ef4444") or empty when no user-defined colour is set (the client picks from a palette deterministically by name). Unlike labels, a todo carries at most one priority. Position is the user-defined ordering (0 = highest precedence); priorities without an explicit position sort last.

type Recurrence

type Recurrence struct {
	Frequency      string      `json:"frequency"`                // "daily"|"weekly"|"monthly"|"yearly"
	Interval       int         `json:"interval"`                 // >= 1 (every N)
	Weekdays       []int       `json:"weekdays,omitempty"`       // weekly: target weekdays, 0=Sun..6=Sat
	MonthDays      []int       `json:"monthDays,omitempty"`      // monthly: target days-of-month 1..31 (e.g. "every 2, 15, 27")
	LastDay        bool        `json:"lastDay,omitempty"`        // monthly: target the last day of the month
	NthWeekday     *NthWeekday `json:"nthWeekday,omitempty"`     // monthly: ordinal weekday, e.g. "every 2nd tuesday"
	EndDate        string      `json:"endDate,omitempty"`        // "YYYY-MM-DD"; recurrence stops after this date
	FromCompletion bool        `json:"fromCompletion,omitempty"` // every! : advance from completion date, not due date
}

Recurrence is a Todoist-style repeating schedule. A todo is recurring iff its Recurrence is non-nil. Completing a recurring todo spawns a new incomplete instance whose due date is advanced by these rules.

The fields cover the date-level Todoist grammar (times are out of scope: the app is date-only). All targets are optional; what is set depends on the frequency:

  • daily: Interval only.
  • weekly: Interval; Weekdays restricts to specific weekdays.
  • monthly: Interval plus one of MonthDays, LastDay, or NthWeekday. With none set, the base day-of-month is kept.
  • yearly: Interval only.

func (Recurrence) Valid

func (r Recurrence) Valid() bool

Valid reports whether the recurrence rule is self-consistent: a known frequency, a positive interval, weekday targets in [0,6], month-day targets in [1,31], a sane ordinal weekday, and an ISO end date when set. Used by both API input validation and the db advance path.

type SavedSearch added in v0.3.0

type SavedSearch struct {
	ID    int64  `json:"id"`
	Name  string `json:"name"`
	Query string `json:"query"`
}

SavedSearch is a named filter query the user can re-apply from the toolbar. Searches are global (not board-scoped): applying one filters the active board with the stored query text.

type Todo

type Todo struct {
	ID              int64        `json:"id"`
	BoardID         int64        `json:"boardId"`
	Title           string       `json:"title"`
	Description     string       `json:"description"`
	Completed       bool         `json:"completed"`
	ParentID        *int64       `json:"parentId,omitempty"`
	Position        int          `json:"position"`
	Labels          []string     `json:"labels,omitempty"`
	LabelColors     []LabelColor `json:"labelColors,omitempty"`
	Priority        string       `json:"priority,omitempty"`        // priority name, "" = none
	PriorityColor   string       `json:"priorityColor,omitempty"`   // hex colour for the priority, "" = auto
	DueDate         string       `json:"dueDate,omitempty"`         // "YYYY-MM-DD", "" = none
	Recurrence      *Recurrence  `json:"recurrence,omitempty"`      // nil = non-recurring
	CreatedAt       string       `json:"createdAt,omitempty"`       // RFC3339 UTC, stamped at creation
	CompletedAt     string       `json:"completedAt,omitempty"`     // RFC3339 UTC, stamped on completion, "" = not completed
	ScheduleText    string       `json:"scheduleText,omitempty"`    // canonical free-text seed for the edit field (computed, not stored)
	RecurrenceLabel string       `json:"recurrenceLabel,omitempty"` // short badge label, e.g. "2 weeks on Mon, Wed" (computed, not stored)
}

Todo represents a single todo item.

type UpdateBoard

type UpdateBoard struct {
	Name     *string `json:"name,omitempty"`
	Position *int    `json:"position,omitempty"`
}

UpdateBoard is the payload for renaming or reordering a board.

type UpdateLabel

type UpdateLabel struct {
	Color *string `json:"color"`
}

UpdateLabel is the payload for changing a label's colour. Colour is a hex string; an empty string clears the user-defined colour so the label reverts to the auto-assigned palette colour.

type UpdatePriority

type UpdatePriority struct {
	Color *string `json:"color"`
}

UpdatePriority is the payload for changing a priority's colour. Colour is a hex string; an empty string clears the user-defined colour.

type UpdateTodo

type UpdateTodo struct {
	Title       *string `json:"title,omitempty"`
	Description *string `json:"description,omitempty"`
	Completed   *bool   `json:"completed,omitempty"`
	OptionalParent
	Position      *int        `json:"position,omitempty"`
	Labels        *[]string   `json:"labels,omitempty"`
	Priority      *string     `json:"-"` // value to set; nil+PrioritySet = clear
	PrioritySet   bool        `json:"-"`
	DueDate       *string     `json:"-"` // value to set; nil+DueDateSet = clear
	DueDateSet    bool        `json:"-"`
	Recurrence    *Recurrence `json:"-"` // value to set; nil+RecurrenceSet = clear
	RecurrenceSet bool        `json:"-"`
}

UpdateTodo is the payload for updating an existing todo. All fields are optional; omitted fields are left unchanged. Pointer-valued JSON fields let us distinguish "unset" from "zero". Parent embeds OptionalParent for the absent/null/value tri-state on parentId.

func (*UpdateTodo) UnmarshalJSON

func (u *UpdateTodo) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes scalar fields normally and routes parentId through OptionalParent so the absent/null/value tri-state is preserved. This is required because embedding OptionalParent would otherwise promote its UnmarshalJSON and silently drop every other field.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL