diff --git a/backend/lib/cgc_2046/courses/course.ex b/backend/lib/cgc_2046/courses/course.ex index 6417d22b..fe0fb25f 100644 --- a/backend/lib/cgc_2046/courses/course.ex +++ b/backend/lib/cgc_2046/courses/course.ex @@ -428,6 +428,9 @@ defmodule Cgc2046.Courses.Course do Ash.Changeset.add_error( changeset, field: :slug, + # 带被拒新值——Ash keyword add_error 不传 :value 时错误消息 Value 恒为 nil, + # 排障时无法区分「参数丢失」与「锁定拦截」(2026-09-09 生产实例误判过) + value: Ash.Changeset.get_attribute(changeset, :slug), message: "slug is locked once the offering is published (editable in draft only)" ) else diff --git a/backend/lib/cgc_2046/events/event.ex b/backend/lib/cgc_2046/events/event.ex index 989736d2..f94bc6ff 100644 --- a/backend/lib/cgc_2046/events/event.ex +++ b/backend/lib/cgc_2046/events/event.ex @@ -430,6 +430,9 @@ defmodule Cgc2046.Events.Event do Ash.Changeset.add_error( changeset, field: :slug, + # 带被拒新值——Ash keyword add_error 不传 :value 时错误消息 Value 恒为 nil, + # 排障时无法区分「参数丢失」与「锁定拦截」(2026-09-09 生产实例误判过) + value: Ash.Changeset.get_attribute(changeset, :slug), message: "slug is locked once the offering is published (editable in draft only)" ) else diff --git a/backend/test/cgc_2046/events/event_slug_test.exs b/backend/test/cgc_2046/events/event_slug_test.exs index 5920ba48..81380465 100644 --- a/backend/test/cgc_2046/events/event_slug_test.exs +++ b/backend/test/cgc_2046/events/event_slug_test.exs @@ -171,6 +171,9 @@ defmodule Cgc2046.Events.EventSlugTest do assert Exception.message(error) =~ "slug is locked" + # 错误须带被拒新值(可观测性:区分「参数丢失」与「锁定拦截」,2026-09-09 生产误判) + assert Exception.message(error) =~ ~s(Value: "new-slug") + assert Ash.get!(Event, event.id, tenant: workspace.id, authorize?: false).slug == "lock-open-event" end