feat(store): role names are unique over live rows only - #1961
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: raystack/frontier/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review. 📝 SummarySummary by CodeRabbit
WalkthroughThe migration changes role-name uniqueness to apply only to non-deleted roles. Role upserts use the partial unique index as their conflict target. Tests cover reuse of deleted names, deleted-ID conflicts, and updates to live roles. ChangesRole Upsert
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~12 minutes Change: Feature Suggested reviewers: Merge Risk: ⚪ Minimal · up to The change allows a soft-deleted role's name to be reused and keeps current behavior for live roles. The author documents the brief window between migration and binary deploy in which role creates fail. No merge-blocking risk is evident from the supplied context. Security Architecture ReviewSecurity architecture risk: 🟡 Moderate · up to The live-role uniqueness rule preserves role identity and existing ownership controls. However, removing the old constraint breaks role creation by older application versions, including during rollback. Startup can also fail when default roles are missing. Deployment sequencing and schema-aware recovery need explicit coordination. Retained concerns
Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Coverage Report for CI Build 36680719484Coverage increased (+0.006%) to 52.866%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
f166d73 to
5f23fbc
Compare
Replace the plain unique constraint on roles (org_id, name) with a unique index over rows where deleted_at is null, and have the role upsert repeat that filter in its conflict target. The upsert's update branch now also sets updated_at.
A deleted name gets a new row, a reused id still conflicts, and a live duplicate updates in place and moves updated_at.
5f23fbc to
7f48580
Compare
What
roles_org_id_name_keyconstraint is replaced by the partial unique indexuq_roles_org_id_name_liveover rows wheredeleted_at IS NULL.liveConflictTargethelper from feat(resource): soft-delete resources and keep the URN unique over live rows only #1937. Migration and query change ship together.updated_at.Why
Soft-deleted rows keep their values. With the plain constraint, an org that deleted a custom role could never create one with the same name again. Names are reusable once the old row is deleted. Role reads already skip deleted rows on
main(#1938).Behaviour change
None today, because nothing sets
deleted_aton a role yet. Once role rows are soft-deleted, a deleted name can be reused by a new role in the same org, and the deleted row stays as history. A create with the name of a live role still updates it in place, and now movesupdated_at.Rollout
Between the migration running and the new binary starting, the old binary's
ON CONFLICT (org_id, name)no longer matches an index, so role creates fail for that window. Boot only creates default roles that are missing, so an environment that already has them boots on the old binary; an empty database does not. The down migration fails if a deleted and a live role share a name by then.Tested
updated_at. The fixture has duplicate role names, so it exercises the update branch on every run.42P10.golangci-lintreports no issues on the package.SQL Safety
goqu.Record{}. The conflict target andnow()are constants with no caller input.ToSQL()params are forwarded unchanged.?placeholders inside quoted SQL literals.//nolintor#nosecannotations.