The GitHub Actions job "Direct Backport Push" on texera.git/main has succeeded. Run started by GitHub user github-merge-queue[bot] (triggered by github-merge-queue[bot]).
Head commit for run: 51b6af3574f41fa3f477a50eee7c7c0c5bc7bee4 / Ryan Zhang <[email protected]> feat(python-notebook-migration): add backend endpoint to delete a workflow's stored notebook and mapping (#7132) ### What changes were proposed in this PR? Adds a single backend REST endpoint to the notebook-migration service that deletes a workflow's stored notebook and its workflow-to-notebook mapping. Until now the service could store and fetch a workflow's notebook (`store-notebook-and-mapping`, `fetch-notebook-and-mapping`) but had no way to remove one. Once stored, a notebook and its mapping stayed in the database with no server-side operation to clear them. This left the persisted rows behind whenever a user closed or discarded a migrated notebook, and it blocked the end-to-end deletion flow, which needs a backend call to remove the notebook before the UI can reset the state that reflects whether a notebook exists. New endpoint: `POST /notebook-migration/delete-notebook-and-mapping`. Behavior: - Reads `wid` from the JSON body. `vid` is not required: `notebook.wid` is UNIQUE (one notebook per workflow), so `wid` alone identifies the row. - Requires write access to the workflow. Returns 403 when the caller lacks it, consistent with the store and fetch endpoints. - Deletes the `notebook` row for the workflow. The `workflow_notebook_mapping` rows are removed by the existing `ON DELETE CASCADE` foreign key, so a single delete clears both tables and cannot leave them inconsistent. - Returns `{"success": true, "deleted": <count>}`, where the count is 1 when a notebook was removed and 0 when nothing was stored, so the caller can tell a real deletion from a no-op. - Idempotent: deleting when nothing is stored returns success with `deleted: 0`. POST with a JSON body is used to stay consistent with the existing store and fetch endpoints, which already read `wid` from a JSON body. This is backend only. The frontend service method, the close-panel wiring, and any Jupyter-server cleanup are intentionally left to the follow-on end-to-end deletion work that consumes this endpoint. Note: if the workflow itself is deleted, the notebook and mapping are already removed by existing cascades, so this endpoint targets the case where the workflow survives but its notebook should be discarded. ### Any related issues, documentation, discussions? Closes #7131 Parent issue #4301 ### How was this PR tested? Added resource spec cases in `NotebookMigrationResourceSpec` covering: - Deleting a workflow that has a stored notebook removes both the notebook row and its mapping rows (cascade verified) and reports `deleted: 1`. - Idempotent delete: returns success with `deleted: 0` when nothing is stored. - Returns 403 and deletes nothing when the caller has only read access. - Returns 500 on a malformed JSON body. ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Claude Opus 4.8) Report URL: https://github.com/apache/texera/actions/runs/30589289837 With regards, GitHub Actions via GitBox
