Files
WeiCHEN 9071c272bf refactor(server): drop Server pool; route health/heal/vault via Runtime
Remove production *pgxpool.Pool from Server, centralize domain→HTTP
status mapping, and expose Runtime ports for task-store readiness,
duty heal, and artifact vault registry. Allow app→docduty for heal wiring.
2026-09-22 21:44:56 +08:00

80 lines
2.3 KiB
Go

package server
import (
"errors"
"net/http"
"chat-agent-system/internal/docgov"
"chat-agent-system/internal/projectworkflow"
)
// domainHTTPStatus is the single adapter that maps known domain sentinel /
// typed errors to HTTP status codes. Callers that need a different default
// (400 vs 500) must apply it when ok is false.
//
// This is the only production place in internal/server that should match
// docgov.Err* (and closely related domain sentinels) for HTTP status selection.
// handlers.go must call this mapper (or writeDocGovError / writeTaskError)
// instead of branching on docgov.Err* directly.
func domainHTTPStatus(err error) (status int, ok bool) {
if err == nil {
return 0, false
}
var busy *docgov.DocumentBusyError
if errors.As(err, &busy) {
return http.StatusConflict, true
}
var ce *docgov.ContentError
if errors.As(err, &ce) {
if ce.Code == docgov.ErrCodeDocumentNotFound {
return http.StatusNotFound, true
}
return http.StatusConflict, true
}
switch {
case errors.Is(err, docgov.ErrDocumentBusy),
errors.Is(err, docgov.ErrDocumentLocked),
errors.Is(err, docgov.ErrForceEditNotAllowed),
errors.Is(err, docgov.ErrLeaseNotHeld),
errors.Is(err, docgov.ErrLeaseExpired):
return http.StatusConflict, true
case errors.Is(err, docgov.ErrDocumentNotFound),
errors.Is(err, docgov.ErrProposalNotFound):
return http.StatusNotFound, true
case errors.Is(err, docgov.ErrUnauthorizedActor):
return http.StatusForbidden, true
case errors.Is(err, projectworkflow.ErrPrerequisiteNotMet):
return http.StatusBadRequest, true
default:
return 0, false
}
}
func writeTaskError(w http.ResponseWriter, err error, payload any) {
status := http.StatusInternalServerError
if mapped, ok := domainHTTPStatus(err); ok {
status = mapped
}
if payload != nil {
writeJSONResponse(w, status, payload)
return
}
writeSafeError(w, nil, status, err.Error())
}
func writeDocGovError(w http.ResponseWriter, err error) {
var busy *docgov.DocumentBusyError
if errors.As(err, &busy) {
writeJSONResponse(w, http.StatusConflict, map[string]any{
"error": "document_busy",
"detail": busy,
})
return
}
status := http.StatusBadRequest
if mapped, ok := domainHTTPStatus(err); ok {
status = mapped
}
writeSafeError(w, nil, status, err.Error())
}