Skip to content

feat(backend): add delete-file action node - #25

Open
LukasHirt wants to merge 2 commits into
mainfrom
feat/action-delete-file
Open

feat(backend): add delete-file action node#25
LukasHirt wants to merge 2 commits into
mainfrom
feat/action-delete-file

Conversation

@LukasHirt

Copy link
Copy Markdown
Collaborator

Summary

Adds a new "Delete File" action node, end to end. Move/copy/rename already exist as file-operation actions; delete was the one basic operation conspicuously missing — the natural terminal step for cleanup workflows like "if a temp file is older than N days, delete it."

  • Backend: new delete action type issues a WebDAV DELETE against the current resource path.
    • webdavfile.Client.Delete (mirrors copyOrMove's auth-header handling, minus the Destination header).
    • FileClient interface in executor.go gains Delete.
    • runAction's new case "delete" sets result.Output to the deleted path and resets currentPath to "", so any later file-needing action in the same chain fails with the existing "no target file" error shape (same pattern tag/comment/move/copy already use).
    • Note: oCIS's WebDAV DELETE typically moves the resource to the space's trash rather than hard-deleting it — platform behavior, not something this action implements or overclaims.
  • Frontend: new action-delete entry in NODE_TYPES under ACTION_CATEGORY (icon delete-bin), 'delete' added to the ActionType union. It's a no-config action like tag/comment (no destination/newName param) — NodeDetailsPanel.vue needed no changes since none of its actionType branches match delete, so only the generic "Run only if" condition field renders.

Test plan

  • Backend: new TestRunDeleteAction in backend/pkg/executor/executor_test.go — asserts Delete is called with the correct path, result.Output is the deleted path, and a chained tag action after delete fails because currentPath is now empty. Written first, confirmed it failed for the right reason (missing Delete call), then implemented.
  • cd backend && go build ./... && go vet ./... && go test ./... — all pass.
  • Frontend: tests/unit/nodeTypes.spec.ts (new) — asserts action-delete exists under ACTION_CATEGORY and is discoverable via findNodeTypeForNode.
  • Frontend: tests/unit/NodeDetailsPanel.spec.ts and tests/unit/ActionNode.spec.ts (new, first component-mount tests in this package) — assert the delete action renders its label/icon with zero action-specific fields, contrasted against tag (one field) and move (destination field).
  • cd frontend && npm run test:unit — 5 files / 11 tests pass.
  • cd frontend && npm run check:types — clean.
  • cd frontend && npm run lint — clean.

🤖 Generated with Claude Code

@LukasHirt
LukasHirt requested a review from a team as a code owner July 24, 2026 16:15
@LukasHirt LukasHirt self-assigned this Jul 24, 2026
@LukasHirt
LukasHirt force-pushed the feat/action-delete-file branch from 71bbc01 to d89c340 Compare July 24, 2026 20:54
LukasHirt and others added 2 commits July 27, 2026 16:37
Adds a `delete` action type that issues a WebDAV DELETE against the
current resource path — the natural terminal step for cleanup
workflows (e.g. removing files older than N days). Mirrors move/copy's
existing shape: FileClient gains a Delete method, webdavfile.Client
implements it against the same DAV endpoint used by copyOrMove, and
runAction's new "delete" case sets result.Output to the deleted path
and resets currentPath to "" so any subsequent file-needing action
fails with the same "no target file" error tag/comment/move/copy
already produce.

Note: oCIS's WebDAV DELETE typically moves the resource to the
space's trash rather than hard-deleting it (platform behavior).

Covered by a new executor test asserting Delete is called with the
right path, result.Output is set, and a chained action after delete
fails because currentPath is now empty.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Lukas Hirt <info@hirt.cz>
Registers a new "Delete File" entry under the Actions picker category
(actionType: 'delete', icon: delete-bin). Like tag/comment, it's a
no-config action — it operates implicitly on the current file, so it
needs no destination/newName param the way move/copy/rename do.
NodeDetailsPanel already renders a no-config action correctly with no
extra changes needed: none of its actionType branches match 'delete',
so only the generic "Run only if" condition field shows.

Adds Vitest coverage: nodeTypes.spec.ts asserts the action-delete
entry exists under ACTION_CATEGORY and is discoverable via
findNodeTypeForNode; NodeDetailsPanel.spec.ts and ActionNode.spec.ts
add the first component-mount tests in this package, asserting the
delete action renders its label/icon with zero action-specific fields
(contrasted against tag's one field and move's destination field).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Lukas Hirt <info@hirt.cz>
@LukasHirt
LukasHirt force-pushed the feat/action-delete-file branch from d89c340 to 9eaa660 Compare July 27, 2026 14:37

@dj4oC dj4oC left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: feat(backend): add delete-file action node

Stats: +206/-2 across 8 files (backend + frontend)

Overview

Adds a delete action: issues a WebDAV DELETE against currentPath, sets result.Output to the deleted path, and — correctly — resets currentPath to "" afterward, so any later file-needing action in the same chain fails with the existing "no target file" error rather than silently operating on a stale/deleted path. This is the cleanest of the recent action-node PRs I've looked at in this repo: small, honest about platform behavior, and its test directly proves the currentPath-reset consequence rather than just asserting the happy path.

Code quality & style

  • webdavfile.Client.Delete mirrors copyOrMove's structure closely (resolve user → build request → set auth header → check status), which keeps the file internally consistent rather than introducing a new shape for HTTP calls.
  • The doc comment on Delete — "this typically moves the resource to the space's trash rather than hard-deleting it — platform behavior, not something this method implements or relies on" — is a responsible, appropriately hedged claim about behavior this code doesn't control. Good instinct not to overclaim data-safety guarantees it can't actually make.
  • runAction's new case "delete" correctly orders the currentPath == "" guard before calling Delete, matching the validation-then-act pattern every other file action already uses.

Minor observations (non-blocking)

  • Consistency gap with the vars-based output convention: like the currently-open createFolder PR (#24), this action sets result.Output but never writes a vars["delete.output"] entry, so a later node couldn't reference {{delete.output}} (e.g., a notify action saying "Deleted {{delete.output}}") even though that'd be a reasonable thing to want. Unlike #24, this PR's description doesn't claim that capability exists, so it's not a broken promise — just worth folding in if/when the vars["<actionType>.output"] convention from PR #23 gets applied consistently across the newer action types.
  • PR-description accuracy: the claim that NodeDetailsPanel.spec.ts is among the "first component-mount tests in this package" doesn't hold — that file already had mount()-based tests using a real createGettext() plugin prior to this PR (it's a modified file, not a new one, per the diff). ActionNode.spec.ts genuinely is new, so the claim is accurate for that file specifically. I flagged this same over-claim pattern on PR #23's description — might be worth double-checking this boilerplate phrase before it goes into future PR descriptions from this branch of work.
  • Shared-file churn (FYI, not blocking): this PR, #24 (createFolder), and others all insert their new NODE_TYPES entry at the same spot (immediately before action-notify) and extend the same ActionType union line in types/workflow.ts. Not a defect in this PR, just a heads-up that whichever of these merges later will need a small, mechanical conflict resolution.

Test coverage

Good. TestRunDeleteAction is the standout — it doesn't just assert the delete call happened, it chains a tag action afterward and asserts it fails specifically because currentPath is now empty, which is exactly the behavior worth locking in given how easy it'd be to regress (e.g., accidentally not clearing currentPath, or clearing it but not surfacing a clear error downstream). Frontend coverage across nodeTypes.spec.ts, NodeDetailsPanel.spec.ts, and the new ActionNode.spec.ts appropriately proves the "zero config fields" claim by contrast against tag (one field) and move (destination field), rather than just asserting delete's own shape in isolation.

Security

The soft-delete-to-trash caveat is the right thing to flag rather than silently rely on. One open question worth a quick platform-level confirmation rather than a code change: does this hold for every oCIS space type (e.g., are there project-space or admin configurations where WebDAV DELETE is a hard delete)? If trash-recoverability isn't universal, this is the one action in the current palette where that distinction actually matters to an end user relying on it, and might be worth a one-line UI caveat rather than only a backend code comment.

Summary

Well-scoped, honestly documented, and the test suite specifically targets the behavior most likely to regress. Nothing here blocks merge.


🤖 Generated with Claude Code

@dj4oC
dj4oC self-requested a review July 28, 2026 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants