Overview
User Segments
Section titled “User Segments”User segments within a resolved organization + project — mirrors
EnvironmentsController’s resolve-then-dispatch shape one level deeper.
{project} is resolved key-or-guid, scoped to the resolved org (with the service-token
project allowlist forwarded), via ResolveProjectIdAsync
for every action. {segment} (get/update/delete) is then resolved key-or-guid, scoped to
the resolved project, via ResolveSegmentIdAsync.
Dispatched commands/queries always use the resolved GUIDs, never the raw route strings. Writes
(create/update/delete) require at least Member
(RequireRole); a Viewer attempting one gets a 403
forbidden envelope.
There is no GetUserSegmentQuery — Get resolves {segment} then
dispatches ListUserSegmentsQuery and finds the match in-memory, throwing
NotFoundException if absent. This keeps the task scoped to the public layer with
no new Application handler: the resolver has already validated the id exists within the
project, and a project’s segment set is bounded (unlike flags/environments’ own list, this
never needs true server-side pagination for the lookup).
Operator is a bare string on the wire; write actions
parse it to OperatorType via TryParse1(ReadOnlySpan{Char},Boolean,0@)
(case-insensitive). An unrecognized value throws the custom
ValidationException BEFORE any command is dispatched — mapped to a 400
validation_failed envelope by PublicApiExceptionFilterAttribute, same as
every other handler-thrown validation failure on this surface.