Repository navigation
feat(store): project delete keeps the row - #2007
Conversation
The project row now gets deleted_at instead of being removed. The project.deleted audit record is written in the same transaction, with the row's delete time. Deleting a project that is already deleted, or does not exist, returns not found. An e2e test checks that everyone who had access loses it and that every policy on the project is marked deleted.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Summary
Merge Risk: ⚪ Minimal · up to
|
Coverage Report for CI Build 39411055393Warning Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes. Coverage increased (+0.3%) to 55.587%Details
Uncovered Changes
Coverage Regressions245 previously-covered lines in 6 files lost coverage.
Coverage Stats
💛 - Coveralls |
There was a problem hiding this comment.
Left a few comments. The main one is that a second delete now errors where it used to succeed. Most of these touch files outside this diff, so they are listed here.
-
core/deleter/service.go:226: the comment saying the project row is removed for good is now wrong. ThePurgecomments ininternal/store/postgres/resource_repository.go:289andcore/resource/service.go:505say a resource row cannot outlive its project row, which is also no longer true. Can you update them? -
core/deleter/service.go:242: see the inline comment on the repository change, which explains the second delete and the org cascade. Treatingproject.ErrNotExistfromDeleteModelas success inDeleteProjectfixes both. -
core/deleter/service_test.go:113: can we add a test that pins the order, policies, then resources, then the project row last? The delete order must not change, and nothing checks it now. The steps recorder used in the org tests below would work. -
core/project/service.go:83: a failed create used to leave no project row, because the rollback hard deleted it. Now the rollback soft deletes, so a deleted row stays behind. Theproject.createdandproject.deletedrecords were already written before this PR. It only happens when the SpiceDB link or the owner policy fails, so it is rare. Could you open a ticket to track it? Purging the row on rollback would fix the leftover row. Removing the audit pair would need one transaction around the create and the membership step.
DeleteProject ignores project.ErrNotExist from DeleteModel, so a second delete, and a project deleted during an org delete, succeed as before. A test now pins the order: policies, then resources, then the project row. The comments that said the project row is removed for good are updated.
|
In 5f4dcb0:
|
rohilsurana
left a comment
There was a problem hiding this comment.
Looks good. The second delete and the org cascade now treat a project that is already gone as deleted, the order is pinned by the test, the comments are updated, and the create rollback is tracked in #2009.
Summary
DeleteProjectnow keeps the project row and setsdeleted_aton it, instead of removing it. Project reads already skip deleted rows, and the name is free again becauseuq_projects_name_livecovers live rows only. Theproject.deletedaudit record is written in the same transaction, with the row's delete time.The rest of the delete is unchanged: the project's policies are marked deleted, its SpiceDB tuples are removed, and its resources are still purged.
Changes
internal/store/postgres/project_repository.go:DeleteusessoftDeletewithRETURNING. The audit record takes the returneddeleted_at. When no live row matches, it returnsproject.ErrNotExist; it returned nil before.internal/store/postgres/project_repository_test.go:TestDeletecovers the kept row, the audit record, a second delete, an unknown id, and reusing the name.test/e2e/regression/api_test.go: newTestProjectDeleteKeepsTheRowAndRemovesAccess.Technical Details
project.ErrNotExistfrom the repository. Through the API it is refused earlier, at the permission check, because the project's tuples are already gone.Test Plan
TestDelete: the row stays withdeleted_atset and reads no longer find it; one audit record is written; a second delete and an unknown id returnproject.ErrNotExistwithout an audit record; a new project can take the name.TestProjectDeleteKeepsTheRowAndRemovesAccess: an org owner, a user with a project policy, a group member, and a service user can all get the project before the delete, and none of them can after. Every policy that was on the project answers not found and hasdeleted_atset, and no live policy is left on the project. The project row hasdeleted_atset, a second delete is refused, and a new project can take the name.go test ./internal/store/postgres/...passes.TestEndToEndAPIRegressionTestSuite,TestEndToEndServiceUsersRegressionTestSuiteandTestEndToEndPATRegressionTestSuitepass.golangci-lint run ./internal/store/postgres/... ./test/e2e/regression/...reports no issues.SQL Safety
goqu.Ex{}. The onlygoqu.Lisnow()insidesoftDelete, with no values.ToSQL()callers capture and forward params (query, params, err := stmt.ToSQL(); db.…Context(ctx, …, query, params...)). Neverquery, _, err := ….?placeholders inside single-quoted SQL literals ingoqu.L.//nolint:forbidigoor// #nosec G20xannotations.