Task 401cffb2, feature-level remediation on de76b6e. Resolves feature review NQ-ICON-02 (MEDIUM): a definition stored with a legacy/unknown icon (e.g. mdi:tooth, read back as lucide:mdi:tooth) could not be edited because the unchanged icon was PATCHed and the strict validator rejected it. Fix mirrors the existing keepsAssignees pattern: on edit, an unchanged icon is omitted from the PATCH body (absent means unchanged; verified in api/routes_admin.py model_dump(exclude_unset=True)); a new lucide:/fa:/emoji: choice or null clear is still sent; create still sends icon.
Evidence at e810243: cd admin && npm test = 297 passed; TZ=UTC uv run pytest -q = 2100 passed; admin build ok. Regression test uses lucide:mdi:tooth with the fake API returning 422 for a second colon.
Task 401cffb2, feature-level remediation on de76b6e. Resolves feature review NQ-ICON-02 (MEDIUM): a definition stored with a legacy/unknown icon (e.g. mdi:tooth, read back as lucide:mdi:tooth) could not be edited because the unchanged icon was PATCHed and the strict validator rejected it. Fix mirrors the existing keepsAssignees pattern: on edit, an unchanged icon is omitted from the PATCH body (absent means unchanged; verified in api/routes_admin.py model_dump(exclude_unset=True)); a new lucide:/fa:/emoji: choice or null clear is still sent; create still sends icon.
Evidence at e810243: cd admin && npm test = 297 passed; TZ=UTC uv run pytest -q = 2100 passed; admin build ok. Regression test uses lucide:mdi:tooth with the fake API returning 422 for a second colon.
A definition stored with a legacy icon (e.g. mdi:tooth) reads back as
lucide:mdi:tooth, which the API's strict validate_icon rejects, so any
edit that echoed the icon back failed. Mirror the keepsAssignees
pattern: keep the loaded icon and delete `icon` from the PATCH body
while the draft icon is unchanged. The edit route dumps the body with
exclude_unset, so an absent icon leaves the stored value untouched;
a new choice is sent and No icon still sends null. Create always
sends icon.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Task 401cffb2, feature-level remediation on
de76b6e. Resolves feature review NQ-ICON-02 (MEDIUM): a definition stored with a legacy/unknown icon (e.g. mdi:tooth, read back as lucide:mdi:tooth) could not be edited because the unchanged icon was PATCHed and the strict validator rejected it. Fix mirrors the existing keepsAssignees pattern: on edit, an unchanged icon is omitted from the PATCH body (absent means unchanged; verified in api/routes_admin.py model_dump(exclude_unset=True)); a new lucide:/fa:/emoji: choice or null clear is still sent; create still sends icon.Evidence at
e810243: cd admin && npm test = 297 passed; TZ=UTC uv run pytest -q = 2100 passed; admin build ok. Regression test uses lucide:mdi:tooth with the fake API returning 422 for a second colon.Independent Codex gpt-5.6-terra review completed for this exact commit.