Files
artex/server/task_metadata.go
T
dela 0335d572de
ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
web / web (push) Waiting to run
docs / links (push) Canceled after 0s
detections / detections (push) Canceled after 0s
First Commit
2026-10-09 08:38:16 +08:00

77 lines
2.4 KiB
Go

package server
import (
"errors"
"fmt"
"net/http"
"strings"
"unicode/utf8"
"github.com/Autumn-27/artex/db"
)
const (
maxTaskNameRunes = 200
maxTaskMetadataRequestSize = 16 << 10
)
// 작업 메타데이터 수정 API 가 사용자에게 돌려주는 오류 응답 문구. JSON 필드명
// (name·pinned)은 원문 그대로 두고, 사람이 읽는 메시지만 한국어로 둔다.
const (
errTaskMetaRequestTooLarge = "요청 본문이 너무 큽니다"
errTaskMetaNoFields = "name 또는 pinned 중 하나는 반드시 제공해야 합니다"
errTaskMetaNameEmpty = "작업 이름은 비워 둘 수 없습니다"
// errTaskMetaNameTooLongFmt 는 fmt.Sprintf 로 상한을 채우는 형식 문자열이다.
errTaskMetaNameTooLongFmt = "작업 이름은 최대 %d자까지 입력할 수 있습니다"
)
// updateTaskMetadata changes list-only task metadata. It intentionally does not
// touch lifecycle state, scheduling, or the task's immutable description/goal.
func (s *Server) updateTaskMetadata(w http.ResponseWriter, r *http.Request) {
taskID := r.PathValue("id")
if _, ok := s.m.Task(taskID); !ok {
writeErr(w, http.StatusNotFound, "task not found")
return
}
r.Body = http.MaxBytesReader(w, r.Body, maxTaskMetadataRequestSize)
var request struct {
Name *string `json:"name"`
Pinned *bool `json:"pinned"`
}
if err := decode(r, &request); err != nil {
var tooLarge *http.MaxBytesError
if errors.As(err, &tooLarge) {
writeErr(w, http.StatusRequestEntityTooLarge, errTaskMetaRequestTooLarge)
} else {
writeErr(w, http.StatusBadRequest, err.Error())
}
return
}
if request.Name == nil && request.Pinned == nil {
writeErr(w, http.StatusBadRequest, errTaskMetaNoFields)
return
}
if request.Name != nil {
name := strings.TrimSpace(*request.Name)
if name == "" {
writeErr(w, http.StatusBadRequest, errTaskMetaNameEmpty)
return
}
if utf8.RuneCountInString(name) > maxTaskNameRunes {
writeErr(w, http.StatusBadRequest, fmt.Sprintf(errTaskMetaNameTooLongFmt, maxTaskNameRunes))
return
}
request.Name = &name
}
task, err := s.m.UpdateTaskMetadata(taskID, db.TaskPatch{Name: request.Name, Pinned: request.Pinned})
if err != nil {
writeErr(w, http.StatusInternalServerError, err.Error())
return
}
if task == nil {
writeErr(w, http.StatusNotFound, "task not found")
return
}
writeJSON(w, http.StatusOK, taskDTO(task, s.resolvedTaskStatus(task)))
}