Add subtasks to the PR

Change-Id: I386be06949a54dee518e9b6a23344d76099b88ba
diff --git a/server/subtasks/service_test.go b/server/subtasks/service_test.go
index 158bcdc..0a8e473 100644
--- a/server/subtasks/service_test.go
+++ b/server/subtasks/service_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"context"
+	"os"
 	"strings"
 	"testing"
 	"time"
@@ -482,6 +483,160 @@
 	}
 }
 
+func TestGenerateSubtaskFile(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil)
+	
+	subtask := tm.SubtaskProposal{
+		Title:          "Implement API endpoints",
+		Description:    "Create REST API endpoints for user management",
+		Priority:       tm.PriorityHigh,
+		AssignedTo:     "backend",
+		EstimatedHours: 12,
+		Dependencies:   []string{"0"},
+		RequiredSkills: []string{"go", "rest_api"},
+	}
+	
+	taskID := "parent-task-subtask-1"
+	parentTaskID := "parent-task"
+	
+	content := service.generateSubtaskFile(subtask, taskID, parentTaskID)
+	
+	// Verify YAML frontmatter
+	if !strings.Contains(content, "id: parent-task-subtask-1") {
+		t.Error("Generated file should contain task ID in frontmatter")
+	}
+	if !strings.Contains(content, "title: Implement API endpoints") {
+		t.Error("Generated file should contain task title in frontmatter")
+	}
+	if !strings.Contains(content, "assignee: backend") {
+		t.Error("Generated file should contain assignee in frontmatter")
+	}
+	if !strings.Contains(content, "status: todo") {
+		t.Error("Generated file should have 'todo' status")
+	}
+	if !strings.Contains(content, "priority: high") {
+		t.Error("Generated file should contain priority in frontmatter")
+	}
+	if !strings.Contains(content, "parent_task_id: parent-task") {
+		t.Error("Generated file should contain parent task ID")
+	}
+	if !strings.Contains(content, "estimated_hours: 12") {
+		t.Error("Generated file should contain estimated hours")
+	}
+	
+	// Verify dependencies are converted properly
+	if !strings.Contains(content, "dependencies:") {
+		t.Error("Generated file should contain dependencies section")
+	}
+	if !strings.Contains(content, "- parent-task-subtask-1") {
+		t.Error("Dependencies should be converted to subtask IDs")
+	}
+	
+	// Verify required skills
+	if !strings.Contains(content, "required_skills:") {
+		t.Error("Generated file should contain required skills section")
+	}
+	if !strings.Contains(content, "- go") {
+		t.Error("Generated file should contain required skills")
+	}
+	
+	// Verify markdown content
+	if !strings.Contains(content, "# Task Description") {
+		t.Error("Generated file should contain markdown task description")
+	}
+	if !strings.Contains(content, "Create REST API endpoints for user management") {
+		t.Error("Generated file should contain task description in body")
+	}
+}
+
+func TestUpdateParentTaskAsCompleted(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil)
+	
+	// Create a temporary task file for testing
+	taskContent := `---
+id: test-task-123
+title: Test Task
+description: A test task for validation
+assignee: backend
+status: todo
+priority: high
+created_at: 2024-01-01T10:00:00Z
+updated_at: 2024-01-01T10:00:00Z
+completed_at: null
+---
+
+# Task Description
+
+A test task for validation
+`
+	
+	// Create temporary file
+	tmpFile, err := os.CreateTemp("", "test-task-*.md")
+	if err != nil {
+		t.Fatalf("Failed to create temp file: %v", err)
+	}
+	defer os.Remove(tmpFile.Name())
+	
+	if err := os.WriteFile(tmpFile.Name(), []byte(taskContent), 0644); err != nil {
+		t.Fatalf("Failed to write temp file: %v", err)
+	}
+	
+	// Create analysis with subtasks
+	analysis := &tm.SubtaskAnalysis{
+		ParentTaskID:        "test-task-123",
+		EstimatedTotalHours: 20,
+		Subtasks: []tm.SubtaskProposal{
+			{
+				Title:      "Subtask 1",
+				AssignedTo: "backend",
+			},
+			{
+				Title:      "Subtask 2", 
+				AssignedTo: "frontend",
+			},
+		},
+	}
+	
+	// Update the parent task
+	err = service.updateParentTaskAsCompleted(tmpFile.Name(), analysis)
+	if err != nil {
+		t.Fatalf("updateParentTaskAsCompleted failed: %v", err)
+	}
+	
+	// Read the updated file
+	updatedContent, err := os.ReadFile(tmpFile.Name())
+	if err != nil {
+		t.Fatalf("Failed to read updated file: %v", err)
+	}
+	
+	updatedString := string(updatedContent)
+	
+	// Verify the status was changed to completed
+	if !strings.Contains(updatedString, "status: completed") {
+		t.Error("Updated file should contain 'status: completed'")
+	}
+	
+	// Verify completed_at was set (should not be null)
+	if strings.Contains(updatedString, "completed_at: null") {
+		t.Error("Updated file should have completed_at timestamp, not null")
+	}
+	
+	// Verify subtask information was added
+	if !strings.Contains(updatedString, "## Subtasks Created") {
+		t.Error("Updated file should contain subtasks information")
+	}
+	
+	if !strings.Contains(updatedString, "test-task-123-subtask-1") {
+		t.Error("Updated file should reference created subtask IDs")
+	}
+	
+	if !strings.Contains(updatedString, "**Total Estimated Hours:** 20") {
+		t.Error("Updated file should contain total estimated hours")
+	}
+}
+
 func TestClose(t *testing.T) {
 	mockProvider := NewMockLLMProvider([]string{})
 	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil)