Skip to content

Add workspace state check and per-workspace delete commands - #100

Closed
jirkasemmler wants to merge 1 commit into
mainfrom
jirka/workspace-state-check-and-delete-by-id
Closed

Add workspace state check and per-workspace delete commands#100
jirkasemmler wants to merge 1 commit into
mainfrom
jirka/workspace-state-check-and-delete-by-id

Conversation

@jirkasemmler

Copy link
Copy Markdown
Contributor

Changes:

  • New command manage:check-project-workspaces-state — read-only classifier. Input: headerless CSV projectId,workspaceSchema[,componentId,configurationId]. For each row it checks the live API across all dev branches and reports the state (live / config_in_trash / config_live_workspace_gone / purged_or_orphan / access_denied) with a suggested cleanup action, workspaceId, branch and loginType. Makes no changes.
  • New command manage:delete-project-workspaces-by-id — deletes single workspaces by id, keeping the parent configuration and its other workspaces (unlike manage:mass-delete-project-workspaces, which deletes the whole configuration and only works via editor sessions, i.e. sandboxes only). With --with-configuration it deletes the whole configuration (trash + purge; handles configurations that are live, already in trash, or fully purged).
  • Safety rails: dry-run by default (-f to write); refuses workspaces whose loginType is not a password login unless --any-login-type (protects key-pair siblings of migrated sandboxes); optional expectedSchema CSV column must match the live schema; --with-configuration refuses configurations owning more than the one listed workspace.
  • Both commands take a manage token and mint short-lived (30 min) per-project storage tokens (canManageBuckets, plus canPurgeTrash for configuration deletes), dropping them after each project — no interactive token pasting.

Built for the SLSP LEGACY_SERVICE cleanup (DMD-1565), where they executed 215 deletions with zero failures; the tooling is stack-agnostic and reusable for any password-login workspace cleanup.

phpstan level 9 and phpcs clean.


Additional notes

⚠️ Don't forget to release new version after merge

🤖 Generated with Claude Code

manage:check-project-workspaces-state — read-only classifier: for a CSV of
projectId,schema[,componentId,configId] it checks the live API (all dev
branches) and reports whether each workspace is live, its configuration is
in trash, or fully purged, with a suggested cleanup action per row.

manage:delete-project-workspaces-by-id — deletes single workspaces by id
(keeps the parent configuration and its other workspaces), or with
--with-configuration the whole configuration (trash + purge). Dry-run by
default; refuses non-password-login (key-pair) workspaces unless
--any-login-type; optional expectedSchema column cross-check; with
--with-configuration refuses configurations owning more than the one
listed workspace.

Both mint short-lived per-project storage tokens from a manage token, so
no interactive token pasting. Built for LEGACY_SERVICE workspace-user
cleanups (DMD-1565).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jirkasemmler added a commit that referenced this pull request Jul 30, 2026
…ting

Consolidates the outstanding workspace tooling into this branch, replacing
PRs #92, #98 and #100. Adds three commands and documents them; no existing
command is modified.

manage:check-project-workspaces-state (read-only)
  Triage step for a known list of workspaces: reports whether each is still
  live and whether its configuration is live, trashed or gone, and suggests
  the follow-up command. Configuration state is resolved per branch, because
  branches hold independent copies under the same id and merging them
  misclassifies a config that is live in one branch and trashed in another.
  Also reports each configuration's most recent job from the Queue API, which
  is usually what decides whether it is still in use, and runs a sanity query
  for any job in the project first so that blank lastJob columns are not
  misread as "never used".

manage:delete-project-workspaces-by-id
  List-driven deletion with layered guards: password-login only unless
  --any-login-type, optional expected-schema verification, and configuration
  deletion only behind --with-configuration and only when that configuration
  owns exactly the listed workspace. Deletes the workspace without touching
  the configuration by default. A purge refused with
  storage.components.cannotDeleteConfiguration is counted as failed rather
  than deleted, since in that case the configuration is still in the trash and
  its workspace and backend user still exist.

manage:list-external-buckets (read-only)
  Stack-wide CSV audit of external buckets with created date, isReadOnly and
  whether KBC.description metadata is set. Drops its temporary token even when
  listing fails, and continues past projects it cannot reach.

README gains entries for all three, and the "Which command should I use?"
table now points at the by-id command as the preferred list-driven option over
manage:mass-delete-project-workspaces, which needs an interactively pasted
token per project and always purges the configuration.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jirkasemmler

Copy link
Copy Markdown
Contributor Author

Closing in favour of #106, which carries both of these commands.

They are carried over in newer versions than what was on this branch, including two fixes made after this PR was opened:

  • DeleteProjectWorkspacesById — a purge refused with storage.components.cannotDeleteConfiguration was swallowed and the row still counted as deleted++. It is now reported and counted as failed, because in that case the configuration is still sitting in the trash and its workspace and backend user still exist. The old behaviour told you a workspace was gone when it was not, which is exactly the failure mode that produced the DMD-1565 / DMD-1594 leftovers.
  • CheckProjectWorkspacesState — configuration state was merged across branches, so a configuration live in one branch and trashed in another was misclassified. State is now resolved per branch, with other branches reported in the note column. It also now reports each configuration's most recent job from the Queue API, plus a sanity query so that empty lastJob* columns are not misread as "never used".

Nothing from this PR is dropped. The branch stays, so this is reversible.

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.

1 participant