Resolve #3589076 "Detect conflicts during autosave polling"

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.php by adding new error code 4 that is intended to distinguish HTTP 409 responses the UI will able to handle gracefully in !945
  • Updates the error (#/components/schemas/Error) definition in openapi.yml by adding optional conflict_id property. On the BE we use Page revision id and cast it to string. 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 in openapi.yml by adding HTTP 409 response. This response returns body containing errors property that are described by updated the #/components/schemas/Error and also data that returns the auto-save entries as per HTTP 200 response. 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, ApiAutoSaveController and ErrorCodesEnum to add functionality described above
  • Minor refactor/quality of life improvements:
    • Moved some hardcoded auto-save properties that are not meant for client side from ApiAutoSaveController to AutoSaveManager::AUTO_SAVE_INTERNAL_PROPERTIES
    • Added new $with_conflicts argument 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.
  • Added temporary e2e fix to ui/tests/e2e/empty-canvas.cy.js that most likely can be removed in !945, commented that in !945 (comment 1069355).

Testing instructions

  1. Create Page entity in Canvas, make a change, publish the changes
  2. Modify same Page entity, but do not publish your changes, observe auto-save polling (HTTP GET to /canvas/api/v0/auto-saves/pending) respond with HTTP 200
  3. Outside of Canvas resave the Page entity (using drush esav canvas_page <entity id> -y should work just fine)
  4. Observe next Canvas auto-save poll (HTTP GET to /canvas/api/v0/auto-saves/pending) return HTTP 409:
    • Response should have errors and data properties

    • The data property should have all auto-save items as per HTTP 200 response

    • The errors property should have an entry for the Page entity modified in step 3.

    • The errors entry for the conflicting auto-save item must have property code with value 4 , identifying the HTTP 409 response as "resolvable in Canvas UI" as described in #3587587

    • The errors entry for the conflicting auto-save item

      must have meta property and it must contain conflict_id property set to string value of the current latest revision of Page entity (updated in step 3) that is stored in db

Closes #3589076 (closed)

Edited by Feliksas Mazeikis

Merge request reports

Loading