50f4ca96-7455-4f46-8586-16dd2c87d3d6
ID
stopped
Status
—
Cost
—
Tokens
gemini-3.1-flash-lite-preview
Model
ad-hoc
Job
Transcript 3 messages
[task_id: sc-taskify-create-task] Update file main.go with the following content:
package main
import (
"database/sql"
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
"github.com/e2e-test/taskify-api/internal/service"
_ "github.com/lib/pq"
)
var taskService *service.TaskService
func main() {
db, err := sql.Open("postgres", "host=localhost user=test password=test dbname=test port=5432")
if err != nil {
log.Fatal(err)
}
defer db.Close()
taskService = service.NewTaskService(db)
http.HandleFunc("/api/v1/tasks", handleTasks)
http.HandleFunc("/api/v1/tasks/", handleTaskByID)
fmt.Println("taskify-api listening on :8080")
http.ListenAndServe(":8080", nil)
}
type CreateTaskRequest struct {
Title string json:"title"
Description string json:"description"
}
func handleTasks(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPost:
createTask(w, r)
case http.MethodGet:
listTasks(w, r)
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
func createTask(w http.ResponseWriter, r *http.Request) {
var req CreateTaskRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
task, err := taskService.CreateTask(req.Title, req.Description)
if err != nil {
http.Error(w, "Failed to create task", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(task)
}
func listTasks(w http.ResponseWriter, r *http.Request) {
tasks := []*service.Task{}
rows, err := taskService.DB().Query("SELECT id, title, description, created_at, updated_at FROM tasks")
if err != nil {
http.Error(w, "Failed to list tasks", http.StatusInternalServerError)
return
}
defer rows.Close()
for rows.Next() {
var task service.Task
if err := rows.Scan(&task.ID, &task.Title, &task.Description, &task.CreatedAt, &task.UpdatedAt); err != nil {
http.Error(w, "Failed to scan task", http.StatusInternalServerError)
return
}
tasks = append(tasks, &task)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(tasks)
}
func handleTaskByID(w http.ResponseWriter, r *http.Request) {
idStr := r.URL.Path[len("/api/v1/tasks/"):]
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
http.Error(w, "Invalid task ID", http.StatusBadRequest)
return
}
switch r.Method {
case http.MethodPatch:
completeTask(w, r, id)
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
func completeTask(w http.ResponseWriter, r *http.Request, id int64) {
_, err := taskService.DB().Exec("UPDATE tasks SET completed_at = NOW(), updated_at = NOW() WHERE id = $1", id)
if err != nil {
http.Error(w, "Failed to complete task", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, `{"id": %d, "completed": true}`)
}
func (s *TaskService) DB() *sql.DB {
return s.db
}
I'll update the file main.go with the provided content.
workspace_write
{"content":"package main\n\nimport (\n\t\"database/sql\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"strconv\"\n\n\t\"github.com/e2e-test/taskify-api/internal/service\"\n\t_ \"github.com/lib/pq\"\n)\n\nvar taskService *service.TaskService\n\nfunc main() {\n\tdb, err := sql.Open(\"postgres\", \"host=localhost user=test password=test dbname=test port=5432\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer db.Close()\n\n\ttaskService = service.NewTaskService(db)\n\n\thttp.HandleFunc(\"/api/v1/tasks\", handleTasks)\n\thttp.HandleFunc(\"/api/v1/tasks/\", handleTaskByID)\n\n\tfmt.Println(\"taskify-api listening on :8080\")\n\thttp.ListenAndServe(\":8080\", nil)\n}\n\ntype CreateTaskRequest struct {\n\tTitle string `json:\"title\"`\n\tDescription string `json:\"description\"`\n}\n\nfunc handleTasks(w http.ResponseWriter, r *http.Request) {\n\tswitch r.Method {\n\tcase http.MethodPost:\n\t\tcreateTask(w, r)\n\tcase http.MethodGet:\n\t\tlistTasks(w, r)\n\tdefault:\n\t\thttp.Error(w, \"Method not allowed\", http.StatusMethodNotAllowed)\n\t}\n}\n\nfunc createTask(w http.ResponseWriter, r *http.Request) {\n\tvar req CreateTaskRequest\n\tif err := json.NewDecoder(r.Body).Decode(\u0026req); err != nil {\n\t\thttp.Error(w, \"Invalid request body\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\ttask, err := taskService.CreateTask(req.Title, req.Description)\n\tif err != nil {\n\t\thttp.Error(w, \"Failed to create task\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tw.WriteHeader(http.StatusCreated)\n\tjson.NewEncoder(w).Encode(task)\n}\n\nfunc listTasks(w http.ResponseWriter, r *http.Request) {\n\ttasks := []*service.Task{}\n\trows, err := taskService.DB().Query(\"SELECT id, title, description, created_at, updated_at FROM tasks\")\n\tif err != nil {\n\t\thttp.Error(w, \"Failed to list tasks\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\tdefer rows.Close()\n\n\tfor rows.Next() {\n\t\tvar task service.Task\n\t\tif err := rows.Scan(\u0026task.ID, \u0026task.Title, \u0026task.Description, \u0026task.CreatedAt, \u0026task.UpdatedAt); err != nil {\n\t\t\thttp.Error(w, \"Failed to scan task\", http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\ttasks = append(tasks, \u0026task)\n\t}\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tjson.NewEncoder(w).Encode(tasks)\n}\n\nfunc handleTaskByID(w http.ResponseWriter, r *http.Request) {\n\tidStr := r.URL.Path[len(\"/api/v1/tasks/\"):]\n\tid, err := strconv.ParseInt(idStr, 10, 64)\n\tif err != nil {\n\t\thttp.Error(w, \"Invalid task ID\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tswitch r.Method {\n\tcase http.MethodPatch:\n\t\tcompleteTask(w, r, id)\n\tdefault:\n\t\thttp.Error(w, \"Method not allowed\", http.StatusMethodNotAllowed)\n\t}\n}\n\nfunc completeTask(w http.ResponseWriter, r *http.Request, id int64) {\n\t_, err := taskService.DB().Exec(\"UPDATE tasks SET completed_at = NOW(), updated_at = NOW() WHERE id = $1\", id)\n\tif err != nil {\n\t\thttp.Error(w, \"Failed to complete task\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tw.WriteHeader(http.StatusOK)\n\tfmt.Fprintf(w, `{\"id\": %d, \"completed\": true}`)\n}\n\nfunc (s *TaskService) DB() *sql.DB {\n\treturn s.db\n}\n","file_path":"/workspace/main.go"}{"file_path":"/workspace/main.go","success":true}The file main.go has been successfully updated with the provided content. The file now contains the complete Go HTTP server implementation for the taskify API with endpoints for creating tasks, listing tasks, and completing tasks by ID.