Managed profile team access and invitation feature - #1364
Conversation
✅ Deploy Preview for vortexfi canceled.
|
✅ Deploy Preview for vortex-sandbox ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for vrtx-dashboard ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
🟡 Changes recommended
The new deferred database invariant can break managed-profile provisioning during a rolling deployment.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds managed-profile team memberships, invitation acceptance, role-aware authorization, dashboard controls, and corresponding contracts/security documentation.
Changes:
- Introduces manager/read-only memberships with audited invitations.
- Enforces membership capabilities across sessions and credentials.
- Adds Team management UI, tests, OpenAPI, and security documentation.
Review finding: Migration 069’s owner-membership trigger is incompatible with older API instances during rolling deployment and must be staged separately.
File summaries
| File | Description |
|---|---|
apps/api/src/database/migrations/069-create-managed-profile-memberships.ts |
Adds membership schema and invariants. |
apps/api/src/database/migrations/070-email-notification-direct-recipients.ts |
Supports invitation-email recipients. |
apps/api/src/database/managed-profile-memberships-schema.test.ts |
Tests database membership constraints. |
apps/api/src/api/services/managed-profile-membership.service.ts |
Implements invitations and membership lifecycle. |
apps/api/src/api/services/managed-profile-lifecycle.service.ts |
Returns membership-aware managed profiles. |
apps/api/src/api/middlewares/managedProfileAuth.ts |
Enforces delegated capabilities. |
apps/api/src/api/routes/v1/managed-profile-memberships.route.ts |
Exposes membership endpoints. |
apps/api/src/api/routes/v1/ramp.route.ts |
Enforces child ramp authentication. |
apps/api/src/api/services/email/managed-profile-membership-invitation.ts |
Creates invitation emails. |
apps/api/src/api/services/email/notification.service.ts |
Delivers direct-recipient notifications. |
apps/dashboard/src/components/managed-profiles/Team.tsx |
Adds Team management UI. |
apps/dashboard/src/routes/member-invitations.$invitationId.tsx |
Adds invitation acceptance flow. |
apps/dashboard/src/hooks/useManagedProfileBootstrap.ts |
Refreshes live membership state. |
docs/api/openapi/vortex.openapi.json |
Documents the public API contract. |
docs/security-spec/01-auth/managed-profile-memberships.md |
Defines membership security invariants. |
docs/security-spec/03-ramp-engine/recipient-transfers.md |
Documents delegated recipient permissions. |
docs/security-spec/07-operations/client-observability.md |
Defines invitation telemetry restrictions. |
docs/security-spec/07-operations/notifications.md |
Documents direct invitation email behavior. |
docs/README.md |
Updates the documentation index. |
Review details
- Files reviewed: 144/146 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| affected_member_profile_ids := ARRAY[OLD.id, NEW.id]; | ||
| END IF; | ||
| END IF; | ||
|
|
||
| IF EXISTS ( |
There was a problem hiding this comment.
Stale, migration was modified. Must be rechecked.
There was a problem hiding this comment.
🟡 Changes recommended
The migration breaks managed-profile provisioning during rolling deployment, and invitation creation holds database locks across an external authentication request.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
apps/api/src/database/migrations/069-create-managed-profile-memberships.ts:353
- This deferred trigger makes migration 069 incompatible with still-running pre-PR API instances. After the migration commits, a legacy provisioning transaction still inserts an active
managed_profilesrow but does not insertmanaged_profile_memberships; its commit therefore fails with23514. Because migrations run at API startup, a rolling deployment can break managed-profile creation until every old instance is drained. Stage the invariant (for example, deploy dual-writing code before enabling the trigger, or add the constraint in a later gated migration) so old and new instances can coexist during rollout.
- Files reviewed: 151/157 changed files
- Comments generated: 1
- Review effort level: Balanced
| // Local email is only a hint: it may belong to someone else since the member | ||
| // changed their login. An unconfirmed lookup must not veto an email-bound invite; | ||
| // acceptance still requires the current verified principal and checks membership. | ||
| const current = await SupabaseAuthService.getUserProfile(existingProfile.id).catch(() => null); |
Summary