1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2//
3// SPDX-License-Identifier: AGPL-3.0-or-later
4
5package planning
6
7import (
8 "crypto/sha256"
9 "fmt"
10 "strings"
11 "time"
12)
13
14// TaskStatus represents the status of a task
15type TaskStatus int
16
17const (
18 StatusPending TaskStatus = iota
19 StatusInProgress
20 StatusCompleted
21 StatusFailed
22)
23
24// String returns the emoji representation of the task status
25func (s TaskStatus) String() string {
26 switch s {
27 case StatusPending:
28 return "☐"
29 case StatusInProgress:
30 return "⟳"
31 case StatusCompleted:
32 return "☑"
33 case StatusFailed:
34 return "☒"
35 default:
36 return "☐"
37 }
38}
39
40// ParseStatus converts a string status to TaskStatus enum
41func ParseStatus(status string) TaskStatus {
42 switch strings.ToLower(status) {
43 case "pending":
44 return StatusPending
45 case "in_progress":
46 return StatusInProgress
47 case "completed":
48 return StatusCompleted
49 case "failed":
50 return StatusFailed
51 default:
52 return StatusPending
53 }
54}
55
56// Goal represents the overarching goal
57type Goal struct {
58 Text string `json:"text"`
59 UpdatedAt time.Time `json:"updated_at"`
60}
61
62// Task represents a single task
63type Task struct {
64 ID string `json:"id"`
65 Title string `json:"title"`
66 Description string `json:"description"`
67 Status TaskStatus `json:"status"`
68 CreatedAt time.Time `json:"created_at"`
69 UpdatedAt time.Time `json:"updated_at"`
70}
71
72// NewTask creates a new task with a deterministic ID
73func NewTask(title, description string) *Task {
74 // Generate deterministic ID based on title and description
75 id := generateTaskID(title, description)
76
77 return &Task{
78 ID: id,
79 Title: title,
80 Description: description,
81 Status: StatusPending,
82 CreatedAt: time.Now(),
83 UpdatedAt: time.Now(),
84 }
85}
86
87// UpdateStatus updates the task status and timestamp
88func (t *Task) UpdateStatus(status TaskStatus) {
89 t.Status = status
90 t.UpdatedAt = time.Now()
91}
92
93// generateTaskID creates a deterministic 8-character ID based on task content
94func generateTaskID(title, description string) string {
95 content := fmt.Sprintf("%s:%s", title, description)
96 hash := sha256.Sum256([]byte(content))
97 return fmt.Sprintf("%x", hash[:4]) // 8 hex characters
98}