Files
artex/server/task_metadata.go
T
dela 97668dab7e
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
detections / detections (push) Waiting to run
docs / links (push) Waiting to run
web / web (push) Waiting to run
Localize user-facing UI, agent output, and backend messages to Simplified Chinese
2026-10-09 14:08:31 +08:00

77 lines
2.3 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)))
}