Refactor, add consts
Change-Id: Iabb1738e90d06ec9830a3d9efcf35cfecc2d86ce
diff --git a/server/tm/git_tm/git_task_manager.go b/server/tm/git_tm/git_task_manager.go
index 5c43828..edfb476 100644
--- a/server/tm/git_tm/git_task_manager.go
+++ b/server/tm/git_tm/git_task_manager.go
@@ -16,21 +16,50 @@
"gopkg.in/yaml.v3"
)
+const (
+ // File system constants
+ DefaultFileMode = 0755
+ TaskFileMode = 0644
+ TaskFileExt = ".md"
+
+ // Frontmatter constants
+ FrontmatterSeparator = "---\n"
+
+ // Task ID format
+ TaskIDPrefix = "task-"
+)
+
+// UserService defines interface for user-related operations
+type UserService interface {
+ GetUserName(userID string) (string, error)
+}
+
+// DefaultUserService provides a simple implementation that uses userID as name
+type DefaultUserService struct{}
+
+func (dus *DefaultUserService) GetUserName(userID string) (string, error) {
+ // For now, just return the userID as the name
+ // This can be enhanced to lookup from a proper user service
+ return userID, nil
+}
+
// GitTaskManager implements TaskManager interface using git as the source of truth
type GitTaskManager struct {
- git git.GitInterface
- repoPath string
- tasksDir string
- logger *slog.Logger
+ git git.GitInterface
+ repoPath string
+ tasksDir string
+ logger *slog.Logger
+ userService UserService
}
// NewGitTaskManager creates a new GitTaskManager instance
func NewGitTaskManager(git git.GitInterface, repoPath string, logger *slog.Logger) *GitTaskManager {
return &GitTaskManager{
- git: git,
- repoPath: repoPath,
- tasksDir: repoPath,
- logger: logger,
+ git: git,
+ repoPath: repoPath,
+ tasksDir: filepath.Join(repoPath, "tasks"),
+ logger: logger,
+ userService: &DefaultUserService{},
}
}
@@ -40,16 +69,34 @@
logger = slog.Default()
}
return &GitTaskManager{
- git: git,
- repoPath: repoPath,
- tasksDir: repoPath,
- logger: logger,
+ git: git,
+ repoPath: repoPath,
+ tasksDir: filepath.Join(repoPath, "tasks"),
+ logger: logger,
+ userService: &DefaultUserService{},
+ }
+}
+
+// NewGitTaskManagerWithUserService creates a new GitTaskManager with custom user service
+func NewGitTaskManagerWithUserService(git git.GitInterface, repoPath string, logger *slog.Logger, userService UserService) *GitTaskManager {
+ if logger == nil {
+ logger = slog.Default()
+ }
+ if userService == nil {
+ userService = &DefaultUserService{}
+ }
+ return &GitTaskManager{
+ git: git,
+ repoPath: repoPath,
+ tasksDir: filepath.Join(repoPath, "tasks"),
+ logger: logger,
+ userService: userService,
}
}
// ensureTasksDir ensures the tasks directory exists
func (gtm *GitTaskManager) ensureTasksDir() error {
- if err := os.MkdirAll(gtm.tasksDir, 0755); err != nil {
+ if err := os.MkdirAll(gtm.tasksDir, DefaultFileMode); err != nil {
return fmt.Errorf("failed to create tasks directory: %w", err)
}
return nil
@@ -59,7 +106,7 @@
func (gtm *GitTaskManager) generateTaskID() string {
timestamp := time.Now().Unix()
random := uuid.New().String()[:8]
- return fmt.Sprintf("task-%d-%s", timestamp, random)
+ return fmt.Sprintf("%s%d-%s", TaskIDPrefix, timestamp, random)
}
// taskToMarkdown converts a Task to markdown format
@@ -95,9 +142,10 @@
// Build markdown content
var content strings.Builder
- content.WriteString("---\n")
+ content.WriteString(FrontmatterSeparator)
content.Write(yamlData)
- content.WriteString("---\n\n")
+ content.WriteString(FrontmatterSeparator)
+ content.WriteString("\n")
if task.Description != "" {
content.WriteString("# Task Description\n\n")
@@ -111,7 +159,7 @@
// parseTaskFromMarkdown parses a Task from markdown format
func (gtm *GitTaskManager) parseTaskFromMarkdown(content string) (*tm.Task, error) {
// Split content into frontmatter and body
- parts := strings.SplitN(content, "---\n", 3)
+ parts := strings.SplitN(content, FrontmatterSeparator, 3)
if len(parts) < 3 {
return nil, fmt.Errorf("invalid markdown format: missing frontmatter")
}
@@ -179,7 +227,7 @@
// readTaskFile reads a task from a file
func (gtm *GitTaskManager) readTaskFile(taskID string) (*tm.Task, error) {
- filePath := filepath.Join(gtm.tasksDir, taskID+".md")
+ filePath := filepath.Join(gtm.tasksDir, taskID+TaskFileExt)
content, err := os.ReadFile(filePath)
if err != nil {
@@ -199,8 +247,8 @@
return fmt.Errorf("failed to convert task to markdown: %w", err)
}
- filePath := filepath.Join(gtm.tasksDir, task.ID+".md")
- if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
+ filePath := filepath.Join(gtm.tasksDir, task.ID+TaskFileExt)
+ if err := os.WriteFile(filePath, []byte(content), TaskFileMode); err != nil {
return fmt.Errorf("failed to write task file: %w", err)
}
@@ -219,8 +267,8 @@
var taskFiles []string
for _, entry := range entries {
- if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".md") {
- taskID := strings.TrimSuffix(entry.Name(), ".md")
+ if !entry.IsDir() && strings.HasSuffix(entry.Name(), TaskFileExt) {
+ taskID := strings.TrimSuffix(entry.Name(), TaskFileExt)
taskFiles = append(taskFiles, taskID)
}
}
@@ -233,7 +281,7 @@
ctx := context.Background()
// Add the task file
- if err := gtm.git.Add(ctx, []string{filepath.Join(gtm.tasksDir, taskID+".md")}); err != nil {
+ if err := gtm.git.Add(ctx, []string{filepath.Join(gtm.tasksDir, taskID+TaskFileExt)}); err != nil {
return fmt.Errorf("failed to add task file: %w", err)
}
@@ -268,6 +316,13 @@
taskID := gtm.generateTaskID()
now := time.Now()
+ // Get owner name from user service
+ ownerName, err := gtm.userService.GetUserName(req.OwnerID)
+ if err != nil {
+ gtm.logger.Warn("Failed to get owner name, using ID", slog.String("ownerID", req.OwnerID), slog.String("error", err.Error()))
+ ownerName = req.OwnerID
+ }
+
// Create task
task := &tm.Task{
ID: taskID,
@@ -275,7 +330,7 @@
Description: req.Description,
Owner: tm.Owner{
ID: req.OwnerID,
- Name: req.OwnerID, // TODO: Look up owner name from a user service
+ Name: ownerName,
},
Status: tm.StatusToDo,
Priority: req.Priority,
@@ -322,7 +377,13 @@
}
if req.OwnerID != nil {
task.Owner.ID = *req.OwnerID
- task.Owner.Name = *req.OwnerID // TODO: Look up owner name from a user service
+ // Get owner name from user service
+ if ownerName, err := gtm.userService.GetUserName(*req.OwnerID); err == nil {
+ task.Owner.Name = ownerName
+ } else {
+ gtm.logger.Warn("Failed to get owner name, using ID", slog.String("ownerID", *req.OwnerID), slog.String("error", err.Error()))
+ task.Owner.Name = *req.OwnerID
+ }
updated = true
}
if req.Status != nil {