From e00edfa42fba5ce92362202243fe31fd706560dc Mon Sep 17 00:00:00 2001 From: Amolith Date: Fri, 19 Dec 2025 00:32:10 -0700 Subject: [PATCH] feat(lunatask): add builder pattern for requests Fluent builders for: TaskBuilder, TaskUpdateBuilder, NoteBuilder, JournalEntryBuilder, PersonBuilder, TimelineNoteBuilder. Example: task := lunatask.NewTask("Call mom").InArea(id).WithPriority(1).Build() Assisted-by: Claude Sonnet 4 via Crush --- lunatask/builders.go | 304 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 lunatask/builders.go diff --git a/lunatask/builders.go b/lunatask/builders.go new file mode 100644 index 0000000000000000000000000000000000000000..52949036c9ff0123f1dfb4b6a06000abc68dad33 --- /dev/null +++ b/lunatask/builders.go @@ -0,0 +1,304 @@ +// SPDX-FileCopyrightText: Amolith +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +package lunatask + +import "time" + +// TaskBuilder provides a fluent interface for constructing CreateTaskRequest. +type TaskBuilder struct { + req CreateTaskRequest +} + +// NewTask creates a new TaskBuilder with the required name field. +func NewTask(name string) *TaskBuilder { + return &TaskBuilder{req: CreateTaskRequest{Name: name}} +} + +// InArea sets the area ID for the task. +func (b *TaskBuilder) InArea(areaID string) *TaskBuilder { + b.req.AreaID = &areaID + return b +} + +// InGoal sets the goal ID for the task. +func (b *TaskBuilder) InGoal(goalID string) *TaskBuilder { + b.req.GoalID = &goalID + return b +} + +// WithNote sets the note/description for the task. +func (b *TaskBuilder) WithNote(note string) *TaskBuilder { + b.req.Note = ¬e + return b +} + +// WithStatus sets the task status (later, next, started, waiting, completed). +func (b *TaskBuilder) WithStatus(status string) *TaskBuilder { + b.req.Status = &status + return b +} + +// WithMotivation sets the motivation (must, should, want). +func (b *TaskBuilder) WithMotivation(motivation string) *TaskBuilder { + b.req.Motivation = &motivation + return b +} + +// WithEstimate sets the time estimate in minutes (0-720). +func (b *TaskBuilder) WithEstimate(minutes int) *TaskBuilder { + b.req.Estimate = &minutes + return b +} + +// WithPriority sets the priority (-2 to 2: lowest, low, neutral, high, highest). +func (b *TaskBuilder) WithPriority(priority int) *TaskBuilder { + b.req.Priority = &priority + return b +} + +// WithEisenhower sets the Eisenhower matrix category (0-4). +func (b *TaskBuilder) WithEisenhower(eisenhower int) *TaskBuilder { + b.req.Eisenhower = &eisenhower + return b +} + +// ScheduledOn sets the scheduled date for the task. +func (b *TaskBuilder) ScheduledOn(date Date) *TaskBuilder { + b.req.ScheduledOn = &date + return b +} + +// CompletedAt sets the completion timestamp. +func (b *TaskBuilder) CompletedAt(t time.Time) *TaskBuilder { + b.req.CompletedAt = &t + return b +} + +// FromSource sets the external source integration. +func (b *TaskBuilder) FromSource(source, sourceID string) *TaskBuilder { + b.req.Source = &source + b.req.SourceID = &sourceID + return b +} + +// Build returns the constructed CreateTaskRequest. +func (b *TaskBuilder) Build() *CreateTaskRequest { + return &b.req +} + +// TaskUpdateBuilder provides a fluent interface for constructing UpdateTaskRequest. +type TaskUpdateBuilder struct { + req UpdateTaskRequest +} + +// NewTaskUpdate creates a new TaskUpdateBuilder. +func NewTaskUpdate() *TaskUpdateBuilder { + return &TaskUpdateBuilder{} +} + +// Name sets the task name. +func (b *TaskUpdateBuilder) Name(name string) *TaskUpdateBuilder { + b.req.Name = &name + return b +} + +// InArea sets the area ID for the task. +func (b *TaskUpdateBuilder) InArea(areaID string) *TaskUpdateBuilder { + b.req.AreaID = &areaID + return b +} + +// InGoal sets the goal ID for the task. +func (b *TaskUpdateBuilder) InGoal(goalID string) *TaskUpdateBuilder { + b.req.GoalID = &goalID + return b +} + +// WithNote sets the note/description for the task. +func (b *TaskUpdateBuilder) WithNote(note string) *TaskUpdateBuilder { + b.req.Note = ¬e + return b +} + +// WithStatus sets the task status (later, next, started, waiting, completed). +func (b *TaskUpdateBuilder) WithStatus(status string) *TaskUpdateBuilder { + b.req.Status = &status + return b +} + +// WithMotivation sets the motivation (must, should, want). +func (b *TaskUpdateBuilder) WithMotivation(motivation string) *TaskUpdateBuilder { + b.req.Motivation = &motivation + return b +} + +// WithEstimate sets the time estimate in minutes (0-720). +func (b *TaskUpdateBuilder) WithEstimate(minutes int) *TaskUpdateBuilder { + b.req.Estimate = &minutes + return b +} + +// WithPriority sets the priority (-2 to 2: lowest, low, neutral, high, highest). +func (b *TaskUpdateBuilder) WithPriority(priority int) *TaskUpdateBuilder { + b.req.Priority = &priority + return b +} + +// WithEisenhower sets the Eisenhower matrix category (0-4). +func (b *TaskUpdateBuilder) WithEisenhower(eisenhower int) *TaskUpdateBuilder { + b.req.Eisenhower = &eisenhower + return b +} + +// ScheduledOn sets the scheduled date for the task. +func (b *TaskUpdateBuilder) ScheduledOn(date Date) *TaskUpdateBuilder { + b.req.ScheduledOn = &date + return b +} + +// CompletedAt sets the completion timestamp. +func (b *TaskUpdateBuilder) CompletedAt(t time.Time) *TaskUpdateBuilder { + b.req.CompletedAt = &t + return b +} + +// Build returns the constructed UpdateTaskRequest. +func (b *TaskUpdateBuilder) Build() *UpdateTaskRequest { + return &b.req +} + +// NoteBuilder provides a fluent interface for constructing CreateNoteRequest. +type NoteBuilder struct { + req CreateNoteRequest +} + +// NewNote creates a new NoteBuilder. +func NewNote() *NoteBuilder { + return &NoteBuilder{} +} + +// WithName sets the note name/title. +func (b *NoteBuilder) WithName(name string) *NoteBuilder { + b.req.Name = &name + return b +} + +// WithContent sets the note content. +func (b *NoteBuilder) WithContent(content string) *NoteBuilder { + b.req.Content = &content + return b +} + +// InNotebook sets the notebook ID. +func (b *NoteBuilder) InNotebook(notebookID string) *NoteBuilder { + b.req.NotebookID = ¬ebookID + return b +} + +// FromSource sets the external source integration. +func (b *NoteBuilder) FromSource(source, sourceID string) *NoteBuilder { + b.req.Source = &source + b.req.SourceID = &sourceID + return b +} + +// Build returns the constructed CreateNoteRequest. +func (b *NoteBuilder) Build() *CreateNoteRequest { + return &b.req +} + +// JournalEntryBuilder provides a fluent interface for constructing CreateJournalEntryRequest. +type JournalEntryBuilder struct { + req CreateJournalEntryRequest +} + +// NewJournalEntry creates a new JournalEntryBuilder with the required date. +func NewJournalEntry(date Date) *JournalEntryBuilder { + return &JournalEntryBuilder{req: CreateJournalEntryRequest{DateOn: date}} +} + +// WithName sets the entry title (defaults to weekday name if omitted). +func (b *JournalEntryBuilder) WithName(name string) *JournalEntryBuilder { + b.req.Name = &name + return b +} + +// WithContent sets the Markdown content. +func (b *JournalEntryBuilder) WithContent(content string) *JournalEntryBuilder { + b.req.Content = &content + return b +} + +// Build returns the constructed CreateJournalEntryRequest. +func (b *JournalEntryBuilder) Build() *CreateJournalEntryRequest { + return &b.req +} + +// PersonBuilder provides a fluent interface for constructing CreatePersonRequest. +type PersonBuilder struct { + req CreatePersonRequest +} + +// NewPerson creates a new PersonBuilder. +func NewPerson() *PersonBuilder { + return &PersonBuilder{} +} + +// WithFirstName sets the person's first name. +func (b *PersonBuilder) WithFirstName(name string) *PersonBuilder { + b.req.FirstName = &name + return b +} + +// WithLastName sets the person's last name. +func (b *PersonBuilder) WithLastName(name string) *PersonBuilder { + b.req.LastName = &name + return b +} + +// WithRelationshipStrength sets the relationship strength category. +func (b *PersonBuilder) WithRelationshipStrength(strength string) *PersonBuilder { + b.req.RelationshipStrength = &strength + return b +} + +// FromSource sets the external source integration. +func (b *PersonBuilder) FromSource(source, sourceID string) *PersonBuilder { + b.req.Source = &source + b.req.SourceID = &sourceID + return b +} + +// Build returns the constructed CreatePersonRequest. +func (b *PersonBuilder) Build() *CreatePersonRequest { + return &b.req +} + +// TimelineNoteBuilder provides a fluent interface for constructing CreatePersonTimelineNoteRequest. +type TimelineNoteBuilder struct { + req CreatePersonTimelineNoteRequest +} + +// NewTimelineNote creates a new TimelineNoteBuilder with the required person ID. +func NewTimelineNote(personID string) *TimelineNoteBuilder { + return &TimelineNoteBuilder{req: CreatePersonTimelineNoteRequest{PersonID: personID}} +} + +// OnDate sets the date for the timeline note. +func (b *TimelineNoteBuilder) OnDate(date Date) *TimelineNoteBuilder { + b.req.DateOn = &date + return b +} + +// WithContent sets the Markdown content. +func (b *TimelineNoteBuilder) WithContent(content string) *TimelineNoteBuilder { + b.req.Content = &content + return b +} + +// Build returns the constructed CreatePersonTimelineNoteRequest. +func (b *TimelineNoteBuilder) Build() *CreatePersonTimelineNoteRequest { + return &b.req +}