Канали: редагування не працювало ніколи
All checks were successful
CI / hygiene (push) Successful in 7s
CI / web (push) Successful in 1m9s
CI / server (push) Successful in 1m43s
CI / agent (push) Successful in 1m0s

Маршрут PUT /api/v1/channels/{id} стояв на handleCreateChannel з
першого дня. Обробник читав тіло й ЗАВЖДИ кликав CreateChannel: він
жодного разу не читав id зі шляху.

При цьому UpdateChannel у store написана повністю й ретельно
прокоментована — включно з рішенням «порожній секрет означає лишити
токен як є, бо розшифрувати збережений заради показу означало б
віддати його туди, звідки він не повернеться». У всьому дереві її не
кликав НІХТО.

Ззовні це виглядало так: правка каналу або заводила дубль, або — якщо
назву лишили — падала з «канал із такою назвою вже є». Тобто
відредагувати канал було неможливо взагалі, а повідомлення про помилку
вказувало не на ту причину.

Візерунок узято з правил у тому самому файлі: там гілка оновлення за
PathValue уже стояла й працювала.
This commit is contained in:
byrsapty 2026-08-28 13:53:07 +03:00
parent 6de3565bbe
commit e0fdfcde06

View file

@ -471,7 +471,7 @@ func (s *Server) handleCreateChannel(w http.ResponseWriter, r *http.Request, p *
return
}
id, err := s.store.CreateChannel(r.Context(), p.TenantID, store.ChannelInput{
in := store.ChannelInput{
Kind: req.Kind,
Name: req.Name,
Config: jsonOr(req.Config, "{}"),
@ -479,7 +479,44 @@ func (s *Server) handleCreateChannel(w http.ResponseWriter, r *http.Request, p *
MinSeverity: req.MinSeverity,
Secret: req.Secret,
Enabled: req.Enabled == nil || *req.Enabled,
}, s.keyring)
}
// Оновлення наявного каналу приходить сюди ж — так само, як у
// правил вище: форма однакова, і розділяти її на дві гілки на
// клієнті означало б розійтися в перевірках.
//
// Цієї гілки НЕ БУЛО ЗОВСІМ. Маршрут PUT /channels/{id} стояв на
// цьому обробнику з першого дня, обробник читав тіло й завжди кликав
// CreateChannel, а написана й ретельно прокоментована UpdateChannel
// не мала жодного виклику в усьому дереві.
//
// Ззовні це виглядало так: правка каналу або заводила ДУБЛЬ, або
// якщо назву лишили — падала з «канал із такою назвою вже є». Тобто
// відредагувати канал було неможливо взагалі, і повідомлення про
// помилку вказувало не на ту причину.
if id := r.PathValue("id"); id != "" {
if err := s.store.UpdateChannel(r.Context(), p.TenantID, id, in, s.keyring); err != nil {
if errors.Is(err, store.ErrNotFound) {
writeError(w, http.StatusNotFound, "not_found", "канал не знайдено")
return
}
if isUniqueViolation(err) {
writeError(w, http.StatusConflict, "duplicate", "канал із такою назвою вже є")
return
}
if isBadUUID(err) {
writeError(w, http.StatusNotFound, "not_found", "канал не знайдено")
return
}
s.log.Error("оновлення каналу", "err", err)
writeError(w, http.StatusInternalServerError, "internal", "внутрішня помилка")
return
}
writeJSON(w, http.StatusOK, map[string]any{"id": id})
return
}
id, err := s.store.CreateChannel(r.Context(), p.TenantID, in, s.keyring)
if err != nil {
if isUniqueViolation(err) {
writeError(w, http.StatusConflict, "duplicate", "канал із такою назвою вже є")