44 lines
1.8 KiB
Markdown
44 lines
1.8 KiB
Markdown
|
|
---
|
||
|
|
kind: task
|
||
|
|
slug: disconnect-linked-email
|
||
|
|
title: Disconnect a linked email from a user's profile
|
||
|
|
plan_slug: multitenant-saas-hardening
|
||
|
|
epic_slug: tenant-lifecycle
|
||
|
|
status: draft
|
||
|
|
priority: P2
|
||
|
|
tenant_id: global
|
||
|
|
owner: unassigned
|
||
|
|
cursor_todo_id: null
|
||
|
|
updated_at: "2026-06-02"
|
||
|
|
---
|
||
|
|
|
||
|
|
# Task summary
|
||
|
|
|
||
|
|
Let a user remove a linked email from their profile. Sounds simple; isn't. Removing the wrong row can either lock the user out (no verified email = can't be matched on next sign-in) or strand an invite that was bound to that email.
|
||
|
|
|
||
|
|
## Why deferred from the invites convoy
|
||
|
|
|
||
|
|
`Task-multi-email-identity` ships the "Linked emails" list as **read-only**. Adding a remove action requires:
|
||
|
|
|
||
|
|
- Server-side guard: cannot remove the user's last verified identity. Cannot remove the `source='primary'` identity unless another verified identity is promoted to primary in the same transaction.
|
||
|
|
- UX for the "this email has 2 pending workspace invites — accept or revoke them first" case.
|
||
|
|
- Audit-log entry (overlaps with `Task-workspace-soft-delete-and-audit`).
|
||
|
|
- Confirmation modal with clear "this will affect: pending invites X, Y" copy.
|
||
|
|
|
||
|
|
## Scope (sketch — refine when scheduled)
|
||
|
|
|
||
|
|
- `identity.disconnectEmail({ identityId })` procedure with the guards above.
|
||
|
|
- Profile UI: confirmation modal that lists pending-invite impact before the destructive action.
|
||
|
|
- If the disconnected identity was `source='primary'`, prompt to choose a new primary from the remaining verified set.
|
||
|
|
|
||
|
|
## Acceptance criteria (draft)
|
||
|
|
|
||
|
|
- [ ] Cannot disconnect the only verified identity on an account.
|
||
|
|
- [ ] Disconnecting an email that has pending invites surfaces those invites in the confirmation flow.
|
||
|
|
- [ ] Audit-log row written for every disconnect.
|
||
|
|
|
||
|
|
## Links
|
||
|
|
|
||
|
|
- Epic: `./Epic-tenant-lifecycle.md`
|
||
|
|
- Depends on: `./Task-multi-email-identity.md`, `./Task-workspace-soft-delete-and-audit.md` (for audit log).
|