timeline.go

 1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
 2//
 3// SPDX-License-Identifier: AGPL-3.0-or-later
 4
 5package lunatask
 6
 7import (
 8	"context"
 9	"fmt"
10	"net/http"
11	"time"
12)
13
14// PersonTimelineNote is a note on a person's memory timeline.
15// Content is encrypted client-side and will be null when read.
16type PersonTimelineNote struct {
17	ID        string    `json:"id"`
18	DateOn    *Date     `json:"date_on"`
19	CreatedAt time.Time `json:"created_at"`
20	UpdatedAt time.Time `json:"updated_at"`
21}
22
23// CreatePersonTimelineNoteRequest defines a timeline note for a person.
24// Use [TimelineNoteBuilder] for a fluent construction API.
25type CreatePersonTimelineNoteRequest struct {
26	// PersonID is the ID of the person to add the note to (required).
27	PersonID string `json:"person_id"`
28	// DateOn is the date for the note (optional, defaults to today).
29	DateOn *Date `json:"date_on,omitempty"`
30	// Content is the Markdown content of the note (optional but impractical if empty).
31	Content *string `json:"content,omitempty"`
32}
33
34// personTimelineNoteResponse wraps a single timeline note from the API.
35type personTimelineNoteResponse struct {
36	PersonTimelineNote PersonTimelineNote `json:"person_timeline_note"`
37}
38
39// CreatePersonTimelineNote adds a note to a person's memory timeline.
40// Get person IDs from [Client.ListPeople].
41func (c *Client) CreatePersonTimelineNote(
42	ctx context.Context,
43	note *CreatePersonTimelineNoteRequest,
44) (*PersonTimelineNote, error) {
45	if note.PersonID == "" {
46		return nil, fmt.Errorf("%w: person_id is required", ErrBadRequest)
47	}
48
49	resp, _, err := doJSON[personTimelineNoteResponse](ctx, c, http.MethodPost, "/person_timeline_notes", note)
50	if err != nil {
51		return nil, err
52	}
53
54	return &resp.PersonTimelineNote, nil
55}