mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-14 03:52:26 +08:00
userRepository.Delete used the r.client.Tx(ctx)+ErrTxStarted pattern, which only reuses a transaction when r.client is itself a tx-bound client. With the singleton base client (how Wire injects repos), r.client.Tx() always starts a NEW independent transaction and ignores any tx carried in the context. As a result, AdminService.DeleteUser's transaction (added in #3047) only covered the API-key deletions; the user soft-delete escaped into a separate, immediately-committed transaction. If the outer commit failed after the user tx had committed, the user was deleted while its API keys stayed active, reintroducing the unrecoverable state of #3021. Add a leading dbent.TxFromContext check (mirroring DeleteWithAudit) so Delete joins an externally-provided transaction and lets the caller commit/rollback. Extract the deletion body into deleteUser(ctx, exec, id). All three original paths are preserved; callers passing a plain ctx are unaffected. Add user_repo_delete_atomicity_integration_test.go: builds repos with the base client and a manual outer tx, asserting that delete-keys and delete-user roll back together on abort and commit together on success.