As a tool builder I want to be able to edit parts of aliases of a property so that the work in my tool can be saved back to Wikidata.
PATCH /entities/properties/{property_id}/aliases
**Notes: **
- The request contains a JSON body with a mandatory `patch` key containing a JSON Patch document plus optional metadata: `tags`, `bot`, `comment`.
- Response body containing the updated labels data, using the similar structure as `GET /entities/properties/{property_id}/aliases`.
- Handle HTTP conditional request headers as in PATCH /entities/properties/{property_id}/aliases
- Handle user authentication/authorization like in PATCH /entities/properties/{property_id}/aliases
- duplicate aliases are not allowed per language
- cross-language "collision detection" does not apply for aliases
Autocomments:
* should mimic the `wbeditentity` behavior when editing aliases:
* If the change results in changing aliases in not more than 50 languages: `/* wbeditentity-update-languages-short:0||LANGS */`
* If the change results in changing aliases in 51 or more languages: `/* wbeditentity-update-languages:0||LANG_COUNT */`
* where `LANGS` is a comma separated list of alphabeticall-sorted language codes of relevant languages (e.g. `de, en, es, fi, fr, it`). `LANG_COUNT` is a number of languages with changed aliases
* the boundary number of 50 languages is defined in `ChangedLanguagesCounter::SHORTENED_SUMMARY_MAX_EDIT` constant (not configurable)
Error cases considered:
<table>
<tr>
<th>error type</th>
<th> HTTP Response code</th>
<th>Response content</th>
</tr>
<tr>
<td>Property with the given ID does not exist</td>
<td>404</td>
<td>
`"code": "property-not-found",`
`"message": "Could not find a property with the ID: '{property_id}'"`
</td>
</tr>
<tr>
<td>ID provided is not a valid property ID</td>
<td>400</td>
<td>
` "code": "invalid-property-id",`
`"message": "Not a valid property ID: '{item_id}'"`
</td>
</tr>
<tr>
<td>Property with the provided ID has been redirected to another property (unsure if properties have redirects?)</td>
<td>409</td>
<td>
`"code": "redirected-property"`
`"message": "Property {property_id} has been merged into {other_id}." `
</td>
</tr>
<tr>
<td>Invalid JSON patch (general error)</td>
<td>400</td>
<td>
`"code": "invalid-patch"`
`"message": "The provided patch is invalid"`
</td>
</tr>
<tr>
<td>incorrect JSON patch operation</td>
<td>400</td>
<td>
`"code": "invalid-patch-operation"`
`"message": "Incorrect JSON patch operation: '<op>'"`
`"context": { "operation": <operation_object> }`
</td>
</tr>
<tr>
<td>
invalid field type in JSON patch
(either of `op`, `path`, `from` is not a string)
</td>
<td>400</td>
<td>
`"code": "invalid-patch-field-type"`
`"message": "The value of '<field>' must be of type string"`
`"context": { "operation": <operation_object>, "field": <field> }`
</td>
</tr>
<tr>
<td>
missing mandatory field in JSON patch
(`op`, `path`, `value`, also `from` on copy/move patches)
</td>
<td>400</td>
<td>
`"code": "missing-json-patch-field"`
`"message": "Missing '<field>' in JSON patch"`
`"context": { "operation": <operation_object>, "field": <field> }`
</td>
</tr>
<tr>
<td>Target of JSON Patch not found on the object</td>
<td>409</td>
<td>
`"code": "patch-target-not-found",`
`"message": "Target '<target>' not found on the resource",`
`"context": {`
` "operation": <operation_object>,`
` "field": <path>`
`}`
</td>
</tr>
<tr>
<td>JSON Patch test operation failed</td>
<td>409</td>
<td>
`"code": "patch-test-failed",`
`"message": "Test operation in the provided patch failed. At path '{path}' expected '{expected}', actual: '{actual}'",`
`"context": {`
` "operation": <operation_object>,`
` "actual-value": <actual>`
`}`
</td>
</tr>
<tr>
<td>After changes an invalid language code is used</td>
<td>422</td>
<td>
`"code": "patched-labels-invalid-language-code"`
`"message": "Not a valid language code '{language_code}' in changed aliases"`
`"context": {`
` "language": <language_code>`
`}`
</td>
</tr>
<tr>
<td>After changes a description is invalid (empty, too long)</td>
<td>422</td>
<td>
`"code": "patched-label-empty"/"patched-description-too-long"`
`"message": "Changed description for '{lang_code}' cannot be empty" / "Changed description for '{lang_code}' must not be more than '{limit}' characters long"`
`"context": {`
` "language": <language_code>`
` "value": <label>` (too long label case only)
` "character-limit": <limit>` (too long label case only)
`}`
</td>
</tr>
<tr>
<td>After changes a description is invalid (not allowed characters used)</td>
<td>422</td>
<td>
`"code": "patched-description-invalid"`
`"message": "Changed description for '{lang_code}' is not valid; '{description-text}'"`
`"context": {`
` "language": <language_code>`
` "value": <description>`
`}`
</td>
</tr>
<tr>
<td>After changes the property has the exact same label and description in a given language</td>
<td>422</td>
<td>
`"code": "patched-property-label-description-same-value"`
`"message": "Label and description for language code {language} can not have the same value.`
`"context": {`
` "language": <language>`
`}`
</td>
</tr>
<tr>
<td>After changes the property has the same label and description in a given language as an existing property</td>
<td>422</td>
<td>
`"code": "patched-property-label-description-duplicate"`
`"message": "Property {dupe_id} already has description "{description}" associated with language code {language}, using the same description text."`
`"context": {`
` "language": <language>`
` "label": <label>`
` "description": <description>`
` "matching-item-id": <dupe_property_id>`
`}`
</td></tr>
</table>
Additional notes:
* How Action API handles it (somewhat): https://www.wikidata.org/w/api.php?action=help&modules=wbesetaliases
* REST API proposal: https://wmde.github.io/wikibase-rest-api-proposal/#/labels/patch_entities__entity_type___entity_id__aliases