Skip to content

fix(otel): remove project placements in the project deletion transaction - #74

Merged
muzamilkm merged 5 commits into
arbisoft:main-arbisoftfrom
muzamilkm:otel-lifecycle-hook
Sep 29, 2026
Merged

muzamilkm merged 5 commits into
arbisoft:main-arbisoftfrom
muzamilkm:otel-lifecycle-hook

Conversation

@muzamilkm

@muzamilkm muzamilkm commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Ports the transactional project deletion hook from apache#9091 and uses it in the Claude Code OTel plugin, so a deleted project's OTel placements are always removed with it. Previously a project linked to a revoked and hidden OTel connection could be deleted while its placement row was left behind.

Why placements could be left behind

Placements were cleaned up by the Config UI after the project was deleted, and only for connections the project page could see. Hidden connections are excluded from that lookup, so for a project whose only connection was revoked and hidden, the UI skipped both the preflight and the cleanup:

OTel connection state Before After
Active and visible, linked to two projects Project and placement deleted; the connection stays active on the other project Same
Revoked and visible Project and placement deleted; the connection and its telemetry remain Same
Revoked and hidden Project deleted, placement left behind Project and placement deleted; the connection stays revoked and hidden

Project deletion hook (from apache#9091)

  • New plugin.ProjectDeleteHook interface. BeforeDeleteProject runs inside the core deletion transaction, before the project's records are deleted. Returning an error aborts the deletion and rolls everything back.
  • DeleteProject now deletes the blueprint in the same transaction, instead of committing it separately first. A failure later in the deletion no longer leaves a project without its blueprint.
  • BlueprintManager.DeleteBlueprintInTransaction does the blueprint deletion using the caller's transaction. DeleteBlueprint uses it and still owns its own transaction.
  • Our fork's existing behaviour is kept: the default project blueprint still has no TimeAfter cutoff, and deleting a project still removes its user_project_mapping rows, now inside the same transaction.

Claude Code OTel

  • The plugin implements the hook. It removes the project's placements inside the deletion transaction, including placements of hidden connections.
  • The hook still refuses to delete the final project of an active connection, so a live credential can't be left without an owning project. This is now enforced by the backend, not only by the UI preflight.
  • The project settings page no longer cleans up placements after deleting. It still runs the preflight so the error shows before anything is attempted.
  • Removed the DELETE /plugins/claude_otel/projects/:projectName/placements endpoint and its service function, which only the old UI cleanup used.

AI Throughput Overview: defect coverage

  • Defect-Rate Coverage now counts only issues created within the selected time range, instead of all time. The description is updated to match.

Test plan

  • Unit tests for the hook runner, veto and rollback, single-transaction deletion, blueprint deletion in a transaction, and the OTel placement cleanup (shared active, revoked and hidden, and final-active rejection).
  • Deleted projects through the Config UI on the local stack for each connection state in the table above and checked the database afterwards: the project, blueprint, metric settings and placement are removed, and the connection and credential remain.
  • Deleted the final project of an active connection through the API, bypassing the UI preflight: rejected with a 400, and the project, blueprint, metric settings, placement and user mapping were all left intact.
  • Confirmed a project's user_project_mapping rows are still removed on deletion.

Notes for reviewers

  • The OTel hook releases the plugin's lifecycle lock before the core transaction commits. If an admin changes that connection's projects in the moment between the hook running and the deletion committing, a placement for the deleted project can be re-added and left behind. It needs two admins acting within milliseconds of each other on the same connection, so it isn't handled here.

@muzamilkm
muzamilkm merged commit dcf2b80 into arbisoft:main-arbisoft Sep 29, 2026
5 checks passed
@muzamilkm
muzamilkm deleted the otel-lifecycle-hook branch October 1, 2026 18:17
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