Flow

50f4ca96-7455-4f46-8586-16dd2c87d3d6

ID

stopped

Status

Cost

Tokens

gemini-3.1-flash-lite-preview

Model

ad-hoc

Job

taskify-api
taskify-api

Transcript 3 messages

user

[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
}

assistant

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}
assistant

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.