Member portal: fetch raw identity for save path (preserve birthday)#246
Merged
Conversation
The member portal's profile save path was reading identity via get_full_member_info (which returns data from the v_member_info view, json_build_object'd into a fixed set of keys) and POSTing the result back to /v1/member/identity/. Since add_update_identity REPLACES the entire identity JSONB, this silently dropped any identity fields the view doesn't surface — most notably birthday — and polluted the stored identity with view-only keys like member_id, primary_email, nametag_subtitle, theme_song_url, theme_song_duration. Switch to get_member_identity, which returns the raw identity column from the member row. apply_form_fields only touches keys listed in UPDATABLE_FIELDS["identity"], so unknown fields are preserved across the round-trip. The display path (_get_authenticated_member_info) still uses get_full_member_info — the view-shaped dict is what the dashboard templates expect for rendering. Only the edit/save path is changed. Fixes #245. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rubin110
added a commit
that referenced
this pull request
Apr 27, 2026
Brings 28 commits from dev — most relevantly: - #244/#246 member_id-based identity updates and raw-JSONB profile save - #252/#253 case-insensitive email + username lookups - #249/#250 seed_data rename + reseed/drift tooling - #256 dedupe of duplicate primary emails in seed template - #258 dev_login int validation - #259 root-anchored Backlog gitignore - #237-#240 dispatcher race fix, RFID throttle/timeout, trigger-row-per-column Single conflict resolved in pg/sql/seed_data.sql.example: kept this branch's banned-26-27 / pending-28-30 ordering (so pending members appear at the top of admin portal's default desc-by-id sort during onboarding), but adopted dev's deduped pending names (Niels Bohr in ID 28, Lise Meitner in ID 30) to preserve the unique-primary-email invariant from #256. Also stripped active_directory_username from all three pending rows — pending = pre-onboarding, AD usernames are assigned during the activation flow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Apr 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #245. The member portal's profile save path was round-tripping identity through the
v_member_infoview, silently dropping fields that the view doesn't surface (birthday, etc.) and adding view-shape keys (member_id,primary_email,nametag_subtitle,theme_song_url,theme_song_duration) into the source-of-truth JSONB on every save.Change
One narrow change in
member_update_profile(code/DHMemberPortal/app.py:506-510): fetch the raw identity viadhservices.get_member_identity()(which hits/v1/member/identity/and returns the raw JSONB from thememberrow) instead ofget_full_member_info()(which returns the view-shaped subset).apply_form_fieldsonly writes keys listed inUPDATABLE_FIELDS["identity"], so unknown fields likebirthdayare preserved across the round-trip. The display path (_get_authenticated_member_info) still usesget_full_member_info— unchanged — because the dashboard templates expect the view-shaped dict.Test plan
Verified on dev against ps1-member.mime.starset.net:
birthday: 1995-03-23): saved nickname change, confirmedbirthdaypreserved and no view-only keys addedbirthday,active_directory_username) and noprimary_email/member_id/nametag_subtitle/theme_song_*pollution🤖 Generated with Claude Code