Accept assignee_child_ids on the admin definition edit route

PATCH /api/v1/admin/quest-definitions/{id} now takes an optional
assignee_child_ids list that replaces the definition's assignee set.
The replace runs inside the core edit's single DAO transaction, so a
rejected list (empty, duplicate, unknown or inactive child) returns 422
and writes nothing, including any other field in the same body. The
existing single regeneration path rebuilds future instances. An omitted
field leaves assignees unchanged.

Task: 1c8096f6-643d-441b-a61a-892e0d5b3b59

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-23 20:57:25 -04:00
co-authored by Claude Opus 5.5
parent 42ea5710d7
commit 69a434bcdb
5 changed files with 460 additions and 32 deletions
+20 -15
View File
@@ -30,10 +30,10 @@ hand-rolled here), and the call goes to
``set_quest_definition_active``. The title policy, the window-name
and due-time policy, the assignee checks, the whole-set window
replacement and the never-hard-delete policy (deactivation is the only
removal path) all live in the core. Assignment is NOT settable
through the API: the core's edit path takes no assignees. The edit
route forwards only SUPPLIED fields (``exclude_unset``), like the
children edit.
removal path) all live in the core. The edit route forwards only
SUPPLIED fields (``exclude_unset``), like the children edit; a supplied
``assignee_child_ids`` list REPLACES the whole assignee set inside the
core edit's one transaction (and its one regeneration).
The presence routes follow the same pattern over
:mod:`nestquest_core.presence_management` — the ONE presence write
@@ -182,8 +182,9 @@ deliberately narrow):
set_active on an unknown id) is mapped to 404.
- A core ``ValueError`` reporting a NON-EXISTENT DEFINITION (edit or
set_active on an unknown id — the core prefixes that error with
``definition_id:``) is mapped to 404. Create's rejected-assignee
error names a child from the BODY, not a path id, so it maps to 422.
``definition_id:``) is mapped to 404. Create's and edit's
rejected-assignee error names a child from the BODY, not a path id,
so it maps to 422.
- Every OTHER core ``ValueError`` — an empty display name, an explicit
``null`` colour/avatar_ref (clearing is not supported), a reorder
list that is not a complete permutation of the children (missing,
@@ -476,11 +477,12 @@ class AdminQuestDefinitionEditRequest(BaseModel):
field stays unchanged. An explicit ``null`` ``description``/
``icon`` IS passed and CLEARS the stored value (the core supports
clearing here, unlike the children edit); an explicit ``null``
``rule`` or ``windows`` is passed and rejected by the core. A
supplied ``windows`` list REPLACES the whole window set, and
``assignees`` are deliberately absent — assignment is not settable
through this route. An omitted (or ``null``) ``skip_on_away``
keeps the stored value.
``rule``, ``windows`` or ``assignee_child_ids`` is passed and
rejected by the core. A supplied ``windows`` list REPLACES the
whole window set, and a supplied ``assignee_child_ids`` list
REPLACES the whole assignee set (non-empty, every id an existing
active child — create's contract; a rejection changes nothing). An
omitted (or ``null``) ``skip_on_away`` keeps the stored value.
"""
title: str | None = None
@@ -489,6 +491,7 @@ class AdminQuestDefinitionEditRequest(BaseModel):
rule: AdminRuleRequest | None = None
windows: list[str | tuple[str, str | None]] | None = None
skip_on_away: StrictBool | None = None
assignee_child_ids: list[int] | None = None
class AdminQuestDefinitionActiveRequest(BaseModel):
@@ -1266,10 +1269,12 @@ async def admin_edit_quest_definition(
field is never passed to
:func:`nestquest_core.quest_definitions.edit_quest_definition` and
stays unchanged; a supplied ``windows`` list replaces the WHOLE
window set in the core, and a supplied ``rule`` is rebuilt into a
ScheduleRule (:func:`_rule_from_request`, validated by the model).
An explicit ``null`` ``rule``/``windows`` reaches the core as None
and is rejected there (422), while an explicit ``null``
window set in the core, a supplied ``assignee_child_ids`` list
replaces the WHOLE assignee set in the same core transaction, and a
supplied ``rule`` is rebuilt into a ScheduleRule
(:func:`_rule_from_request`, validated by the model). An explicit
``null`` ``rule``/``windows``/``assignee_child_ids`` reaches the
core as None and is rejected there (422), while an explicit ``null``
``description``/``icon`` clears the stored value — the core edit
path supports clearing, unlike the children edit. An unknown
definition id is mapped to 404 and any other core ``ValueError``