feat(routes): ownership-based edit/delete permissions - #336
Merged
Conversation
Replace visibility-tier-based write permissions with ownership-based: operators can only edit/delete routes they created; admins can modify any route and take ownership on edit. Each route stores the creator's OIDC user_id (created_by column). Legacy routes with NULL created_by are admin-only. The creator's friendly name is resolved from UserProfile and displayed on the route card with a profile link. Edit/delete buttons are hidden per-route based on ownership rather than a flat role check. - Migration: add nullable routes.created_by (batch mode, SQLite-safe) - _assert_route_modifiable: dual-check visibility (404) + ownership (403) - create_route: stamps created_by, ensures profile exists - update_route: admin edits transfer ownership (logged) - RouteOwner schema mirrors AdoptedByUser pattern - Batch owner resolution in list endpoint (avoids N+1) - Frontend: per-route canEdit gate, owner badge with profile link - Tests: 20+ backend ownership tests, 5 frontend gating tests, e2e assertions - Docs: routes.md + auth.md updated for ownership model
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Admins editing an operator-created route no longer steal ownership. Ownership transfer now happens only for legacy (NULL created_by) routes. This ensures operators retain edit access to their routes after an admin makes a small tweak.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the visibility-tier-based write permission model with ownership-based permissions:
created_by(legacy, pre-tracking) are admin-onlyPermission Matrix
Changes
Database
da69304d8106: adds nullablecreated_by String(255)toroutes(batch mode, SQLite-safe)Backend (
routes.py)_assert_route_modifiable: dual-layer check — visibility (404, hides existence) + ownership (403, transparent rejection)create_route: stampscreated_by=user_id, ensures UserProfile exists viaget_or_create_profileupdate_route: admin edits transfer ownership (route.created_by = admin_id, logged);RouteUpdateschema has nocreated_byfield so clients can't inject it_resolve_owner(single) +_resolve_owners_batch(list, avoids N+1)Schema
RouteOwnermodel (user_id,name,callsign,profile_id) — mirrorsAdoptedByUserpatterncreated_by+owneradded to bothRouteReadandRouteDetailFrontend (
Routes.tsx)RouteCardrenamedcanManagetocanEdit(per-route ownership gate)canEditRoute(r) = isAdmin || r.created_by === config.user?.subcreated_byis setTests
Docs
routes.md+auth.mdupdated for ownership modelTest Results