Skip to content

AUTH-006I — Hand off profile Edit focus to the full-name input #655

Description

@daliu

Foundation: released #531, #651/PR #652, and #653/PR #654.

Officer impact: No live workflow change is claimed at issue creation. In reviewed My Account source, a keyboard user whose exact current focused Edit opens the full-name editor will have otherwise-lost focus handed once to the existing Full name input.

Officer documentation: Update SYSTEM_DESIGN.md, IMPLEMENTATION_PLAN.md, SECURITY.md, and the existing My Account Mermaid/text alternative plus one no-terminal source-evidence procedure in docs/officers/EVENTS_SHOP_MEMBERS.md.

Deployment evidence: None at issue creation. Source/test review only. No website publication, Firebase deployment, provider configuration, account/sign-in action, production-data action, or live behavior is authorized or claimed.

Atomic outcome

When the exact connected current Edit button owns focus and its activation opens the profile-name editor, do not leave focus on body or the removed button. Consume one current-generation-only intent and hand otherwise-lost focus to the existing enabled Full name input. Preserve any other connected focus and never retain the intent for a later render.

Current defect

On exact released main 75a4f1ee3b20f61d375ed6d786e67e056a2206ef (tree 6036ac48fd2c28f0cc0c05d5b1be09a7d812783e), the Edit handler clears prior save results and calls setEditing(true). That removes the focused button and inserts the labeled input, but there is no input ref or focus handoff; native removal commonly leaves keyboard focus on body. Existing tests prove editor fields and save behavior but not entry focus. The input already inherits the reviewed global visible-focus rule, so no CSS change is needed.

Invariants and acceptance criteria

  • Keep Edit a native current-profile button and Full name a native labeled input with its existing value, description, autocomplete, disabled, and max-length behavior.
  • On every Edit activation, clear or replace the new intent. Arm it only when the exact event currentTarget is connected and is document.activeElement; retain only the opaque current profile generation number. Do not use autoFocus, timeout, animation frame, selection, or new React state.
  • Reuse the existing context generation. Application, Firestore, identity-service, UID, profile-load, reload, or unmount transitions clear the intent.
  • One layout effect consumes the intent before every check. Require the same current profile generation, mounted current ready profile, editor open, not saving, and the exact connected enabled Full name input.
  • Leave an already-focused input alone. Restore focus only from no active element, body, document root, or a disconnected element. Preserve every other connected deliberate focus, including Sign out or the in-Profile verification control.
  • Focus is one-shot. If the target is missing or disabled, context is obsolete, or another connected target owns focus, consume without moving focus; removing that target or rerendering later must not trigger delayed focus.
  • An unfocused or programmatic Edit activation still opens the editor and clears prior save feedback but moves no focus. A focused activation keeps the current name unchanged and places the input before Save and Cancel in keyboard order; the next ordinary Tab reaches Save.
  • Add no read, write, validation, request, retry, provider call, log, storage, payload, result copy, or data projection. Preserve AUTH-006F one-attempt/context fences and AUTH-006G/H save success/unconfirmed behavior and exact calls.

Trustworthy RED

On unchanged runtime at the exact base, add one minimal test-only witness: render a made-up current ready profile, focus the connected Edit button, activate it as a keyboard click, and require the existing Full name input to own focus while no extra service call occurs. The old source opens the editor but leaves focus on body or the disconnected Edit origin. Record test-only diff digest and focused output before runtime implementation.

Required GREEN coverage

  1. Focused keyboard Edit opens the editor, removes Edit, keeps the authoritative current name, and focuses the enabled labeled input.
  2. The input retains its accessible description, autocomplete, max length, native semantics, and existing global visible-focus rule; no Account.css or index.css edit.
  3. Body, null, document-root, and disconnected post-removal focus restore to the input; an already-focused input is not focused again.
  4. Unfocused or programmatic activation opens the editor without moving focus.
  5. Connected focus outside Profile and on the persistent in-Profile verification control is preserved; after it is removed, a later rerender cannot trigger delayed focus.
  6. A consumed intent moves focus at most once; same-context rerenders do not repeat it.
  7. App-only, Firestore-only, identity-service-only, UID-only, profile reload, unavailable-to-same-context generation, and unmount transitions cannot reuse an older intent.
  8. Entering Edit after AUTH-006G success still clears the old result, uses the reread name, and focuses only from the focused Edit origin.
  9. No save validation or updateMyProfile call occurs on entry; existing load/registration call counts, payloads, Save success, unconfirmed failure, validation, Cancel, Try-profile-again, and sign-out behavior remain unchanged.
  10. Run the named AUTH-006I block, full Account suite, full frontend, repository Node, type-check, scoped ESLint, unchanged lint baseline, diagnostic build, workflow/security checks, and diff-check.

Exact ownership

  • src/pages/account/Account.tsx
  • src/pages/account/Account.test.tsx
  • SYSTEM_DESIGN.md
  • IMPLEMENTATION_PLAN.md
  • SECURITY.md
  • docs/officers/EVENTS_SHOP_MEMBERS.md

Add a separate AUTH-006I design/plan boundary, a separate AUTH-006I/RISK-039 source-ledger row, and one no-terminal backup-officer procedure. Update the existing My Account diagram/text alternative to show focused Edit handing otherwise-lost focus to Full name before Save. Keep #651/#653 historical evidence intact while replacing only their Edit-to-input remains open references where current truth requires it.

src/pages/account/Account.css and src/index.css remain byte-for-byte unchanged; the existing global native-control focus rule supplies visible focus.

Explicit exclusions

  • Cancel-to-Edit focus; validation-error association, aria-invalid, error clearing, or error focus; Try-profile-again settlement focus; save-pending announcement.
  • Changes to Full name value, copy, label, description, max length, autocomplete, validation, payload, save calls, result truth, AUTH-006F/G/H, or profile recovery.
  • Functions, Rules, schemas, indexes, services, packages, workflows, directory runtime/availability/connection, Strava, provider configuration, Firebase deployment, accounts, sign-in, production data, publication, or live action.
  • Membership, dues, role, payment, entitlement, roster, photo query, facial recognition, matching, embeddings, similarity, or biometrics.
  • Active OAUTH-001A2L — Bound Strava activity/statistics JSON and cancel the unread statistics body #616 functions/strava.js, functions/strava.test.js, and its separate OAUTH-001A2L/RISK-024 SECURITY hunk.

Migration and residual risk

No migration. This same-commit browser focus handoff proves no profile write, persistence, identity ownership beyond existing authentication, deployment, membership, directory eligibility, or live behavior. Cancel, validation, retry-settlement, and pending-announcement outcomes remain separate.

Coordination and claim protocol

#651 and #653 are closed and their claims released. Open PRs are empty and no open issue claims Edit-to-input focus. #504 remains the directory coordinator and #507 retains every connection/release gate. #616 overlaps only the SECURITY file; its two Strava blobs and separately named RISK-024 hunk are immutable, so whichever merges later must controlled-refresh and preserve the earlier named hunk. Creation is not a claim: before editing, post and reread disjointness notices, create a unique worktree and branch from exact current main, assign the issue, post a timestamped exact-six-path claim, and hold it through reviewed merge, audit, closure, and explicit release.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:authAuthentication and authorizationarea:membershipMembership lifecycle and reconciliationarea:webWeb application and hostingpriority:P1High-priority follow-upsize:SSmall focused issuetype:reliabilityReliability and recoverytype:testingTest infrastructure and quality gates

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions