Skip to content

MEMBERS-DIRECTORY-001F — Review and confirm a profile photo before upload #629

Description

@daliu

Parent: #504. Follows released frontend-hardening child #627. This is a source-only interface child; #507 retains backend connection and release.

Officer impact: No live officer duty changes. In the preserved future My Account flow, a person will review a locally held centered-square photo preview and explicitly choose Save or Cancel before any photo bytes are sent. The officer People finder behavior does not change.

Officer documentation: Update docs/officers/EVENTS_SHOP_MEMBERS.md with source-only review steps plus the matching Mermaid diagram/text alternative. Update the separately named current-source boundaries in SYSTEM_DESIGN.md, IMPLEMENTATION_PLAN.md, and SECURITY.md.

Deployment evidence: None at issue creation. The source-controlled availability value remains false; production remains the inert #623 deploy. This issue authorizes no website publication, Firebase/Rules/index/Function deployment, provider configuration, account/sign-in action, or production-data action.

Atomic outcome

Replace the preserved connected Account branch's immediate-on-selection photo upload with an explicit local review step:

  1. Validate and read a selected JPG, PNG, or WebP locally.
  2. Show a centered-square draft preview labeled not uploaded yet.
  3. Create a request ID and call the existing upload service only after Save profile photo.
  4. Let Cancel selected photo discard the local draft and send nothing.
  5. Refetch and display only the authoritative processed thumbnail after confirmed Save.

The default unavailable branch stays inert and makes zero directory calls. This issue changes no server contract and does not connect the backend.

Invariants

  • Selecting or previewing a file sends nothing and creates no request ID.
  • The local filename is not copied into React state, logs, analytics, errors, documentation evidence, or tests.
  • The draft bytes remain component-memory only and are discarded on Cancel, successful confirmation, unmount, app/account change, or unknown outcome.
  • A stale FileReader completion after reselection, Cancel, unmount, app change, or account change cannot render or upload.
  • Unsupported, empty, oversized, unreadable, or browser-unrenderable selections get fixed control-associated errors and cannot be saved.
  • The current processed thumbnail/no-photo state remains visibly distinct and authoritative until Save succeeds and the profile is refetched.
  • Uploading/replacing never changes finder visibility. The independent default-off finder choice and officer name search are unchanged.
  • Save and Cancel are keyboard-operable, screen-reader-described, at least 44 pixels high, and contained at 320 pixels.
  • No photo-as-query, face recognition, embedding, similarity, biometric processing, result-count, membership, or authorization behavior is added.
  • memberDirectoryAvailability.ts remains byte-for-byte false.

Exact ownership

  • src/pages/account/MemberDirectoryProfile.tsx: connected-branch local draft/read/render/Save/Cancel/fencing only; truthful unavailable-preview copy only if needed.
  • src/pages/account/MemberDirectoryProfile.test.tsx: separately named 001F local review, explicit Save, Cancel, invalid/unrenderable, stale-read, accessibility, and narrow-layout coverage.
  • src/pages/account/Account.css: only scoped draft-preview/action/320px styles.
  • SYSTEM_DESIGN.md: one separately named MEMBERS-DIRECTORY-001F source-only boundary.
  • IMPLEMENTATION_PLAN.md: one separately named MEMBERS-DIRECTORY-001F current-source boundary.
  • SECURITY.md: one separately named MEMBERS-DIRECTORY-001F/RISK-042 source ledger row.
  • docs/officers/EVENTS_SHOP_MEMBERS.md: one separately named 001F source-review procedure and the existing optional-directory diagram/text-alternative hunk.

Acceptance criteria

  • A valid generated synthetic file produces a local unsaved preview and no request-ID/service call.
  • Save sends the exact selected content type/bytes once with the current revision, refetches authoritative state, and leaves visibility unchanged.
  • Cancel discards the draft, sends nothing, and leaves the saved thumbnail/no-photo state unchanged.
  • Selecting a replacement leaves the current saved thumbnail authoritative until Save.
  • Unsupported, empty, oversized, unreadable, and unrenderable selections expose fixed associated errors and cannot be saved.
  • Older reads after reselection, Cancel, unmount, app change, or UID change are inert.
  • Definitive rejection refetches current state without losing a retryable local draft; unknown outcome hides controls and discards the draft.
  • Default unavailable rendering remains disabled and zero-read/zero-upload/zero-request-ID.
  • Keyboard, semantic status/error, 44px interaction, explicit contrast, and actual/synthetic 320px containment evidence pass.
  • Focused and full frontend tests, TypeScript, diagnostic build, lint baseline, workflow checks, diff-check, and independent security/frontend/backup-officer reviews pass.

Explicit exclusions

Claim protocol

Assign and post a UTC timestamped CLAIMED marker naming the branch and exact base before any edit. The claim remains active through reviewed merge, exact-main CI/deployment audit, closure, and explicit release.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:membershipMembership lifecycle and reconciliationarea:privacyPersonal data, consent, minimization, retention, and privacy operationsarea:webWeb application and hostingpriority:P1High-priority follow-upsize:MMedium multi-file issuetype:featureProduct capabilitytype:securitySecurity or privacy boundarytype: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