1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
package models
import "time"
type AtomSource string
const (
SourceTrello AtomSource = "trello"
SourceTodoist AtomSource = "todoist"
SourceMeal AtomSource = "plantoeat"
)
type AtomType string
const (
TypeTask AtomType = "task"
TypeNote AtomType = "note"
TypeMeal AtomType = "meal"
)
// Atom represents a unified unit of work or information
type Atom struct {
ID string
Title string
Description string
Source AtomSource
Type AtomType
// Metadata
URL string
DueDate *time.Time
CreatedAt time.Time
Priority int // Normalized: 1 (Low) to 4 (Urgent)
// UI Helpers (to be populated by mappers)
SourceIcon string // e.g., "trello-icon.svg" or emoji
ColorClass string // e.g., "border-blue-500"
// Original Data (for write operations)
Raw interface{}
}
// TaskToAtom converts a Todoist Task to an Atom
func TaskToAtom(t Task) Atom {
// Todoist priority: 1 (normal) to 4 (urgent)
// Keep as-is since it already matches our 1-4 scale
priority := t.Priority
if priority < 1 {
priority = 1
}
if priority > 4 {
priority = 4
}
return Atom{
ID: t.ID,
Title: t.Content,
Description: t.Description,
Source: SourceTodoist,
Type: TypeTask,
URL: t.URL,
DueDate: t.DueDate,
CreatedAt: t.CreatedAt,
Priority: priority,
SourceIcon: "✓", // Checkmark emoji for tasks
ColorClass: "border-red-500",
Raw: t,
}
}
// CardToAtom converts a Trello Card to an Atom
func CardToAtom(c Card) Atom {
// Trello doesn't have explicit priority, default to medium (2)
// Can be enhanced later with label-based priority detection
priority := 2
return Atom{
ID: c.ID,
Title: c.Name,
Description: c.ListName, // Use list name as description
Source: SourceTrello,
Type: TypeTask,
URL: c.URL,
DueDate: c.DueDate,
CreatedAt: time.Time{}, // Trello ID contains timestamp, can be parsed later
Priority: priority,
SourceIcon: "📋", // Clipboard emoji for boards
ColorClass: "border-blue-500",
Raw: c,
}
}
// MealToAtom converts a PlanToEat Meal to an Atom
func MealToAtom(m Meal) Atom {
// Meals don't have priority, default to low (1)
priority := 1
return Atom{
ID: m.ID,
Title: m.RecipeName,
Description: m.MealType, // breakfast, lunch, dinner
Source: SourceMeal,
Type: TypeMeal,
URL: m.RecipeURL,
DueDate: &m.Date, // Meal date is effectively the "due date"
CreatedAt: time.Time{},
Priority: priority,
SourceIcon: "🍽️", // Fork and knife emoji for meals
ColorClass: "border-green-500",
Raw: m,
}
}
|