Draft: feat(Conflict detection): #3589076 "Detect conflicts during auto-save polling"
The original branch with this work was merged in !1107 (merged) and reverted in !1205 (merged). In addition to the changes from 1107 this MR also now contains the commits from the !1199 (closed).
Original MR description is bellow
TL;DR: Adds HTTP 409 response to auto-save list endpoint when at least one "resolvable conflict" is detected.
For people with attention span or AI summary tools:
Ground work MR for "[META] Review of changes and Conflict resolution" #3587587. Adds "Detect conflicts during autosave polling" capability.
To keep the scope manageable, changes are limited to Page (canvas_page) entities. Effort is made to leave path open for other entity types.
List of changes:
- Expands
src/Controller/ErrorCodesEnum.phpby adding new error code4that is intended to distinguishHTTP 409responses the UI will able to handle gracefully in !945 - Updates the error (
#/components/schemas/Error) definition inopenapi.ymlby adding optionalconflict_idproperty. On the BE we usePagerevision id and cast it tostring. String is used here as we plan to use a hash of property values for Config entities when we add support for those. - Updates the auto-save entries list endpoint (
/canvas/api/v0/auto-saves/pending) definition inopenapi.ymlby addingHTTP 409response. This response returns body containingerrorsproperty that are described by updated the#/components/schemas/Errorand alsodatathat returns the auto-save entries as perHTTP 200response. This allows client side to update the UI and inform the user about the detection of a conflict(s) and in future MRs provide the user with ways of resolving the detected conflict. - Changes in
AutoSaveManager,ApiAutoSaveControllerandErrorCodesEnumto add functionality described above - Minor refactor/quality of life improvements:
- Moved some hardcoded auto-save properties that are not meant for client side from
ApiAutoSaveControllertoAutoSaveManager::AUTO_SAVE_INTERNAL_PROPERTIES - Added new
$with_conflictsargument to and made both arguments required (AutoSaveManager::getAllAutoSaveList(bool $with_entities = FALSE) to AutoSaveManager::getAllAutoSaveList(bool $with_entities, bool $with_conflicts)). Then updated usages of::getAllAutoSaveList()to use updated method and added named parameters to invocations.
- Moved some hardcoded auto-save properties that are not meant for client side from
- Added temporary e2e fix to
ui/tests/e2e/empty-canvas.cy.jsthat most likely can be removed in !945, commented that in !945 (comment 1069355).
Testing instructions
- Create
Pageentity in Canvas, make a change, publish the changes - Modify same
Pageentity, but do not publish your changes, observe auto-save polling (HTTP GETto/canvas/api/v0/auto-saves/pending) respond withHTTP 200 - Outside of Canvas resave the
Pageentity (usingdrush esav canvas_page <entity id> -yshould work just fine) - Observe next Canvas auto-save poll (
HTTP GETto/canvas/api/v0/auto-saves/pending) returnHTTP 409:-
Response should have
errorsanddataproperties -
The
dataproperty should have all auto-save items as perHTTP 200response -
The
errorsproperty should have an entry for thePageentity modified in step 3. -
The
errorsentry for the conflicting auto-save item must have propertycodewith value4, identifying theHTTP 409response as "resolvable in Canvas UI" as described in #3587587 -
The
errorsentry for the conflicting auto-save itemmust have
metaproperty and it must containconflict_idproperty set to string value of the current latest revision of Page entity (updated in step 3) that is stored in db
-
Closes #3589076