feat(members): add aliases as the display name across the app - #50
Merged
Conversation
Members get an optional short handle — "Paramesh", "Sandeep", "Bunny" —
that replaces their full name wherever they are rendered: chart axes,
ledger tables, poll results, meeting attendees and the Member × Month
grid. The canonical members.name stays the record, and admins can still
search by either half when recording a loan or a contribution.
Schema (055): members.alias, a 2–20 char format check (letters, digits
and spaces only) and a partial unique index on lower(alias). Writes go
through two SECURITY DEFINER functions rather than direct UPDATEs,
because members is admin-write under RLS but a member has to be able to
change their own alias:
* fn_set_member_alias — admin, or the member themselves
* fn_set_member_aliases — admin-only bulk save, all-or-nothing
The bulk function clears the batch before applying it, so two members
swapping aliases in one save doesn't trip the unique index mid-UPDATE —
an expression index can't back a DEFERRABLE constraint, so the check
can't be postponed to COMMIT. It also rejects rows with no member_id:
a single NULL makes the `id not in (batch)` collision check evaluate to
NULL for every row, which would let a real collision through to a raw
23505 instead of a sentence the admin can act on.
The four read-side views gain the alias appended at the END of their
select lists — create or replace view may only add columns after the
existing ones, never re-order them.
Admin screen at /admin/aliases sets the whole roster in one submit, with
each box pre-filled from the member's name. The roster is written
surname-first ("Korrakuti Paramesh"), so the suggester takes the given
name — normally the second token — and skips family suffixes shared
across the batch (Reddy, Kumar, Gupta) that six members would otherwise
all want. GIVEN_NAME_OVERRIDES covers the one entry stored the other way
round. Suggestions are proposals: nothing is written until save.
Members change their own alias later from their profile page.
Verified by replaying migrations 001→055 on a local Postgres with the
real seed (23 members, 1,283 transactions) and Supabase's privilege
model, so RLS is the gate: a non-admin's direct UPDATE changes 0 rows,
the same member sets their own alias through the function, and the
admin's bulk save writes all 23 with no case-insensitive duplicates.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The suggestion was only a placeholder, so the admin had to click "Fill empty with suggestions" before it became real text — an extra step on a screen whose whole purpose is not typing 23 names by hand. Seed the draft state from the suggestion instead, falling back to the saved alias where one exists. Pre-filled is still not saved: these are form values only, nothing reaches the database until Save, and Reset drops every unsaved suggestion. The counter now separates the two so the distinction is visible — "12 of 23 members have a saved alias · 23 filled in below, not saved yet". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Members get an optional short handle — "Paramesh", "Sandeep", "Bunny" — that replaces their full name wherever they're rendered: chart axes, ledger tables, poll results, meeting attendees and the Member × Month grid. The canonical
members.namestays the record, and admins can search by either half when recording a loan or contribution.Run
scripts/prod/migrations/055_member_aliases.sqlin the Supabase SQL Editor. Nothing works until it lands.Schema (055)
members.alias+ a 2–20 char format check (letters, digits and spaces only — no dots, underscores or hyphens) + a partial unique index onlower(alias).Writes go through two SECURITY DEFINER functions rather than direct UPDATEs, because
membersis admin-write under RLS but a member has to be able to change their own alias:fn_set_member_alias(member, alias)fn_set_member_aliases(rows)Two details worth a reviewer's eye:
DEFERRABLEconstraint, so the check can't be postponed to COMMIT.member_idare rejected up front. A single NULL makes theid not in (batch)collision check evaluate to NULL for every row, which would let a real collision through to a raw 23505 instead of a readable message.The four read-side views gain the alias appended at the end of their select lists —
create or replace viewmay only add columns after the existing ones, never re-order them.UI
/admin/aliases— set the whole roster in one submit, each box pre-filled, live duplicate/format flagging.Alias · Full Nameand match on either half (filterByadded toPrDropdown/PrMultiSelect).On the suggestions
The roster is written surname-first (
Korrakuti Paramesh), so taking the first token proposed the family name for all 23 members. The suggester now takes the given name — normally the second token — and skips suffixes shared across the batch (Reddy, Kumar, Gupta) that six members would otherwise all want.GIVEN_NAME_OVERRIDEScoversPrakash Policherla, the one entry stored the other way round with no signal in the string. Suggestions are proposals only; nothing is written until save.Testing
385 unit tests pass (48 new), plus typecheck, lint and build.
Migrations
001→055were replayed on a local Postgres with the real seed (23 members, 1,283 transactions) under Supabase's privilege model, so RLS is the gate:UPDATE members SET alias→ 0 rows changedNot verified: no live Supabase run — the keys in
.envare placeholders — so this hasn't been exercised in a browser.🤖 Generated with Claude Code