feat(accounts): surface email-duplicate pairs in /api/accounts#829
feat(accounts): surface email-duplicate pairs in /api/accounts#829ozpool wants to merge 2 commits into
Conversation
Addresses Soju06#787 (B). After an OAuth token-invalidation cascade (Codex/ChatGPT 'Revoke all sessions' or upstream-side mass invalidation), the dashboard re-add flow can leave the load-balancer pool with two account rows that share the same email: one carries a stale refresh token that upstream now rejects, the other is the fresh re-import. Both have status=active in the local view, the older one keeps generating 401s through the proxy, and the operator has no way to spot the pair without grouping the /api/accounts payload by email themselves. Add 'is_email_duplicate' to AccountSummary, defaulted False, set True when another account row in the same response carries the same email. Computed once per request from the loaded account list, no extra queries. Empty emails are excluded so the legacy DEFAULT_EMAIL placeholder used by malformed imports doesn't get flagged. Frontend zod schema mirrors the new field as optional so existing test fixtures and direct-literal AccountSummary constructions don't need churn updates; the dashboard can pick this up in a follow-up to render the indicator on the /accounts list. Tests: - tests/integration/test_accounts_api.py::test_list_accounts_flags_email_duplicates pins True on both rows of a shared-email pair and False on a solo row.
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Merge hold from owner review:
Core duplicate detection for real non-empty emails looks fine; focused tests/typecheck/CI are green. |
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
One concern: one of my use cases is the same email being used across multiple workspaces/orgs as separate valid accounts. Since this PR appears to flag duplicates by email alone within the Should duplicate detection include workspace/org context, if available, or otherwise avoid treating same-email-across-workspaces as a stale duplicate pair? |
|
Following up on the merge-hold points:
Focused tests/typecheck/CI are green on the current head. Let me know if anything else needs adjusting. |
|
@KakatkarAkshay good catch, that is a real gap. As it stands the indicator groups by email alone, so two intentionally separate accounts that happen to share an email across different workspaces would both get Worth noting the field is advisory only — it does not delete or deduplicate anything, it just lets the dashboard surface "these rows share an email" so an operator can decide. So the downside today is a false-positive hint rather than data loss. But the hint should still be correct. There is a natural key for the fix already in the model: each account carries a I'd rather not change the semantics unilaterally since it is the maintainer's call on what the field should mean. @Soju06 if you'd prefer the stricter email+account_id grouping, I'm happy to fold it into this PR (with a regression test for the same-email/different-account_id case) or split it into a follow-up. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3efed3407d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
3efed34 to
12ad36a
Compare
|
@codex review |
12ad36a to
67d0777
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 12ad36abc3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
67d0777 to
fc9299a
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 67d0777339
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
Addresses #787 (B).
After an OAuth token-invalidation cascade, the dashboard re-add flow can leave the pool with two account rows that share the same email: one carries a stale refresh token that upstream now rejects, the other is the fresh re-import. Both show
status=activein the local view, the older one keeps generating 401s through the proxy, and the operator has no way to spot the pair without grouping the/api/accountspayload by email themselves.This PR adds
is_email_duplicatetoAccountSummary, defaultedFalse, setTruewhen another account row in the same response carries the same email. Computed once per request from the loaded account list (no extra queries). Blank/missing emails and the legacyDEFAULT_EMAILplaceholder are excluded from duplicate detection.The frontend zod schema mirrors the new field as optional so existing test fixtures and direct-literal
AccountSummaryconstructions don't need churn updates; the dashboard can pick this up in a follow-up to render the indicator on the/accountslist / dashboard tile.Behavior
email-> all such rows returnisEmailDuplicate: true.email->isEmailDuplicate: false.DEFAULT_EMAILplaceholder -> excluded from the count, never flagged.Tests
tests/integration/test_accounts_api.py::test_list_accounts_flags_email_duplicates:dup-stale+dup-freshsharingdup@example.comandsoloonsolo@example.comDEFAULT_EMAILGET /api/accountsisEmailDuplicate=trueon bothdup-*rows andfalseonsoloplus both placeholder rowsExisting accounts integration + repo + unit suites stay green (53 passed). Frontend
bun run typecheckclean and fullbun run testclean (446 passed).