package console import ( "fmt" "net/http" "github.com/carlosframework/platform/internal/release" ) // The ship door's swap-demand sentences live here, not in apicli.go: the // moves copy gate pins the jsonError text of that file. const ( apiShipSwapBad = `swap must be "hold" or left out` apiShipSwapConflict = "version %s was already shipped with a different swap demand. Versions are immutable: ship under a new version" ) // refuseBadSwap answers 400 and reports true when the meta part carries a // swap demand other than "hold" (zero-downtime spec §4.2). func refuseBadSwap(w http.ResponseWriter, swap string) bool { if swap != "" && swap != release.DemandHold { jsonError(w, http.StatusBadRequest, apiShipSwapBad) return true } return false } // refuseSwapConflict answers 409 and reports true when a re-ship of an // existing version adds or drops the demand. The demand decides how the bytes // are swapped in, so such a re-ship is a different release: the capability // block's rule. func refuseSwapConflict(w http.ResponseWriter, stored, sent, ver string) bool { if stored != sent { jsonError(w, http.StatusConflict, fmt.Sprintf(apiShipSwapConflict, ver)) return true } return false } // addSwapEcho adds the release's own swap demand to a ship response // (zero-downtime spec §4.2), closing the gap addCapabilitiesEcho closes: a // console from before the field ignores it and stores a release that demands // nothing, which would swap in overlap; a client that sent a demand refuses // an answer without its echo. func addSwapEcho(body map[string]any, swap string) { if swap != "" { body["swap"] = swap } }