Skip to content

fix(projects,environments): finish project delete after client disconnect; audit env var writes - #1543

Merged
dviejokfs merged 2 commits into
mainfrom
fix/service-delete-disconnect-and-env-var-audit
Oct 15, 2026
Merged

dviejokfs merged 2 commits into
mainfrom
fix/service-delete-disconnect-and-env-var-audit

Conversation

@dviejokfs

Copy link
Copy Markdown
Contributor

Summary

Project delete survives a client disconnect (#1539)

DELETE /projects/{id} awaited every teardown step in the request future. Axum drops that future when the client disconnects, so the project stayed fenced (is_deleted = true) with its environment, deployments and containers intact: still listed, still serving, and refused by write endpoints.

The teardown (fence, deletion hook, cancel deployments, container cleanup, archive cleanup, row delete, audit entry) now lives in run_project_teardown and runs on a tokio::spawned task that the handler awaits. Dropping the request drops only the JoinHandle, which detaches the task. Errors and the response contract are unchanged; a panic in the task is reported as a 500 that tells the caller to retry.

Not changed: the read-side items in the issue's checklist (#2 and #3, a fenced project still returned by list/get). Happy to follow up if wanted.

Audit env var create / update / delete (#1537)

  • New audit operations ENVIRONMENT_VARIABLE_CREATED, ENVIRONMENT_VARIABLE_UPDATED and ENVIRONMENT_VARIABLE_DELETED, emitted from the three handlers like the existing promote entry (an audit failure is logged and does not fail the write).
  • Payload: actor/IP/UA, project id, var id, key, environment ids, is_secret, and for updates changed_fields (key, value, environments, include_in_preview, is_secret). The value, old or new, is never recorded; value only means a new value was supplied.
  • EnvVarService::delete_environment_variable now returns a DeletedEnvVar (id, key, is_secret, environment ids) and UpdateEnvVarOutcome gains changed_fields, both computed inside the existing locked transaction, so there is no extra read outside it.
  • "Import .env" in the console calls the create handler once per variable, so each imported variable gets its own entry. There is no separate bulk route.
  • The existing ENVIRONMENT_VARIABLE_PROMOTED_TO_SECRET entry is kept; a promotion now also produces an UPDATED entry with is_secret in changed_fields.

Testing

  • cargo test --lib -p temps-environments: 125 passed (new: changed-field reporting, delete reporting, audit payloads carry no value).
  • cargo test --lib -p temps-projects handlers::: 81 passed (new: teardown runs on a detached task and none of its steps are inline in the handler; a spawned task outlives a dropped awaiter).
  • cargo clippy --lib --tests -p temps-environments -p temps-projects: clean. python3 scripts/source_attribution.py check: passes.
  • The custom_domains tests in temps-projects need a Docker socket, which was not available locally, so they were not exercised.
  • No end-to-end run of the delete against a live server (curl --max-time repro) was done.

Fixes #1539
Fixes #1537

🤖 Generated with Claude Code

…nect; audit env var writes

Project delete: the DELETE /projects/{id} teardown ran inside the request
future, so a client disconnect dropped it right after the is_deleted fence,
leaving the project listed, serving and refused by write endpoints. The
teardown now runs on a spawned task that the handler awaits; a dropped
request no longer cancels it.

Env vars: create, update and delete were not written to the audit log (only
reveal and promote-to-secret were). Add ENVIRONMENT_VARIABLE_CREATED,
ENVIRONMENT_VARIABLE_UPDATED (with changed_fields) and
ENVIRONMENT_VARIABLE_DELETED entries. The value, old or new, is never
recorded. .env import goes through the create handler, so it is covered.

Fixes #1539
Fixes #1537

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: David Viejo <dviejokfs@temps.sh>
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

📓 Changelog preview

This is what your commits will add to the generated CHANGELOG.md at release time (via git-cliff). Do not edit CHANGELOG.md by hand — it is generated from your Conventional Commit messages.

## [Unreleased]

### Fixed

- **projects,environments:** Finish project delete after client disconnect; audit env var writes
- **projects:** Log project deletion failures from the detached teardown task

@greptile-apps

greptile-apps Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Critical impact] The PR appears safe to merge; the previous finding is fixed and no new actionable issues remain.

Summary

Project deletion now runs on a separate task so cleanup can finish after the client disconnects. Environment variable writes also gain audit entries without recording their values.

  • Project deletion keeps running after the client disconnects.
  • Environment-variable writes now leave value-free audit records.

Diagram

sequenceDiagram
  participant Client
  participant Handler
  participant Task as Teardown task
  participant Services
  Client->>Handler: DELETE project
  Handler->>Handler: Check access and load project
  Handler->>Task: Spawn teardown
  Task->>Services: Fence project and run deletion hook
  Task->>Services: Cancel deployments and clean up resources
  Task->>Services: Delete project rows
  alt Deletion step fails
    Task->>Task: Log failure with project ID
  else Rows deleted
    Task->>Services: Write audit entry
  end
  Note over Handler,Task: Client disconnect drops the awaiter, not the task
Loading

Reviews (2) · Last reviewed commit: "fix(projects): log project deletion fail..." · Reviewed by Greptile

Comment thread crates/temps-projects/src/handlers/handlers.rs
…wn task

After a client disconnect nobody awaits the teardown result, so errors from
begin_project_deletion and the final row delete were returned but never
logged, leaving a fenced project with no trace of why cleanup stopped. Log
both inside the task with the project id, and log successful completion.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: David Viejo <dviejokfs@temps.sh>
@dviejokfs
dviejokfs enabled auto-merge (squash) October 15, 2026 17:56
@dviejokfs
dviejokfs merged commit 8feca0a into main Oct 15, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant