Skip to content

Resolved multiple Iru users sharing an email#2

Merged
bawdo merged 13 commits into
mainfrom
feature/multi-user-by-email
May 27, 2026
Merged

Resolved multiple Iru users sharing an email#2
bawdo merged 13 commits into
mainfrom
feature/multi-user-by-email

Conversation

@bawdo

@bawdo bawdo commented May 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • internal/iru.FindUserByEmail was renamed to FindUsersByEmail, dropped the hardcoded limit=1, and now paginates via WalkCursor so every user record sharing an email is returned. ErrNotFound is returned only on zero matches.
  • user show <email> now disambiguates multi-match emails: a numbered prompt on a TTY, or a single-line error with every matching user ID and a re-run hint on a pipe / CI. The new helpers (resolveSelectedUser, userStatusLabel, userOneLine, promptForUser, buildBundleForUser) live in cmd/user.go; tests cover single match, multi-match TTY pick, invalid-then-valid, three-strike exhaustion, abort, non-TTY error, and ErrNotFound.
  • users send-email expands each input email into N users via the same lookup and processes each user independently. Per-row stderr lines gain a user=<id> segment when an input maps to more than one Iru user; single-match inputs are unchanged. Summary counters reflect user-level outcomes, not input rows. The consent prompt now reads "to N input address(es)" so it doesn't overstate the granularity.
  • overview and overview --per-user --send-email need no production change because the roster is already keyed by user ID; two regression tests in cmd/overview_test.go pin that behaviour.
  • README updated in three places (per-user view, bulk send, overview) to document the new behaviour.

Test plan

  • make pre-ci is green (9/9 checks, coverage 81.1%, govulncheck clean).
  • go test ./... is green across all 9 packages.
  • Verified against the live Iru tenant: jellyfish user show aravinth@flipgroup.com.au now lists both matching users instead of silently picking the first.
  • Reviewer to sanity-check the prompt wording on a real two-user account.

bawdo added 13 commits May 27, 2026 22:02
Renamed FindUserByEmail to FindUsersByEmail and dropped the
hardcoded limit=1. The walk now paginates via WalkCursor so every
user record sharing the same email is returned. Both production
callers were updated to compile against the new signature; the
cmd layer still uses the first match for now (multi-match
disambiguation lands in a follow-up task) with an explicit
empty-slice guard.
Extracted the device + detection bucketing into a helper that
takes an already-resolved iru.User. resolveBundleForUser keeps
its existing behaviour by calling the new helper. The user-show
disambiguation work depends on being able to build a bundle from
a chosen user without re-running the identifier lookup.
Reworded the doc comment so it does not name resolveSelectedUser
before that function exists. The intent is unchanged: once the
multi-user disambiguation work lands, user show will call
buildBundleForUser directly with a pre-selected user.
Introduced resolveSelectedUser plus the userStatusLabel,
userOneLine, and promptForUser helpers. On TTY the user is
shown a numbered menu and picks one of the matches; on
non-TTY a structured error names every match and prints a
re-run hint. The new helper is not wired into runUserShow
yet — that lands in the next task.
Added a direct unit test for the zero-match case so the path is
not only exercised indirectly through resolveBundleForUser.
userShowOpts gained PromptReader and stdinIsTTY hooks for
tests. On a real TTY a numbered menu is shown; on non-TTY the
command errors with a re-run hint listing every match. A clean
q / EOF prints "aborted: no user shown" and exits 0.
The bulk recipient loop now resolves each input email to every
matching Iru user and processes them independently. When one
input maps to more than one user, stderr lines gain a
user=<id> segment so each fanout is auditable; single-match
inputs are unchanged. The temporary resolveBundleForUser bridge
was removed; the test fake's ListDevices now honours UserID so
per-user bundles isolate cleanly.
Added a doc comment on the iruClient method declaring that an
empty result must come back as ErrNotFound, never (nil, nil),
and added a defensive guard in the bulk send loop so a future
implementation that violates the contract still produces a
user-not-found log line rather than silently dropping input.
Added two regression tests confirming that two Iru users
sharing an email both appear in the overview roster with their
own ranks, and that overview --per-user --send-email fans out
to each of them independently. No production code change.
The shared on-disk detection cache survives across cmd tests in
one run; a sibling test populates it with unrelated fixtures.
This test passes noCache=true so it sees its own fakeClient data
and not the stale cache.
Added one short paragraph each to the user show, users
send-email, and overview sections describing how duplicate
emails are handled, including the new prompt / non-TTY
re-run hint, the user=<id> stderr segment for bulk fanouts,
and the fact that the overview roster is keyed by user ID.
Dropped the internal endpoint path from the user-facing
description and reworded the non-TTY error description so it
reflects the single-line message that actually prints.
The prompt previously said "to N users" using the input-row
count, but one input email can now expand to multiple Iru-user
sends. Reworded to "to N input address(es)" so operator consent
matches what is actually being counted.
@bawdo bawdo self-assigned this May 27, 2026
@bawdo
bawdo merged commit 502b004 into main May 27, 2026
5 checks passed
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 82.14286% with 25 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/users.go 76.00% 9 Missing and 3 partials ⚠️
cmd/user.go 86.76% 5 Missing and 4 partials ⚠️
internal/iru/users.go 81.81% 2 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

@bawdo
bawdo deleted the feature/multi-user-by-email branch May 27, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants