Member Person Lookup
Lets a desk operator find an existing member of the current organisation from a few known details — date of birth, ID/passport number, phone, or email — and open a record showing who they are plus their membership history.
This page is the as-built reference for the delivered contract. For the screen designs and flows see Member Add and the M03 / M04 use-case specifications; for the security rationale of returning person data directly (rather than progressive-match tokens) see ADR-0007.
Overview
The feature is delivered as:
-
A Member Person Lookup screen (M03) — an auto-detecting search box plus an explicit Search by selector.
-
A membership-centric Person Detail screen (M04) — an identity summary plus the person’s membership history.
-
A new org-scoped, direct-data backend endpoint (below).
-
A frontend
OrgContextServicethat supplies the current organisation id.
Only people who hold a non-draft membership in the current organisation are returned. Non-members and global-only persons never appear; global (non-member) search remains on progressive-match.
API: POST /api/people/member-search
Finds members of the resolved organisation and returns their demographic summary directly.
-
Authentication: required (
isAuthenticated()). -
Deprecates nothing you should still call: prefer this over the deprecated
/api/people/query,/api/people/matchand/api/people/idsearch. -
Responses:
200with the matching members (an empty array when none match);403when the caller may not read the resolved organisation;406when the value is below the minimum searchable length — note406also carries an empty array, so callers must branch on the status code, not on emptiness.
Request
Body:
{
"field": "AUTO",
"value": "9001015800086"
}
| Field | Type | Notes |
|---|---|---|
|
|
One of |
|
string |
The search value. For |
Query parameters:
| Parameter | Notes |
|---|---|
|
Optional hint. The organisation is resolved server-side (JWT |
Standard paging ( |
The candidate set and response are capped server-side. |
Field resolution
AUTO infers the field from the value:
-
contains
@→ email (person_email); -
a parseable 6/8-digit date → date of birth (
date_of_birth); -
other numeric → ID number and phone (
id_number∪contact_number); -
other text → first / last name.
Every explicit field searches only its own meta key. In particular ID_NUMBER searches id_number only — never other_number and never names.
Response — PersonSummaryDTO[]
A deliberately lightweight summary. It carries no medical, emergency-contact, parent, doctor, scheme/billing or free identity fields (ADR-0007).
[
{
"id": 1234,
"name": "Mary Member",
"firstName": "Mary",
"lastName": "Member",
"dateOfBirth": "1990-01-01",
"gender": "FEMALE",
"phone": "0821234567",
"email": "[email protected]",
"membershipNumber": "HNR-00421"
}
]
membershipNumber is the person’s current membership number in the resolved organisation. It is populated only by the member-search mapping (PersonMapper.toDtoMemberSummary) and is annotated @JsonInclude(NON_EMPTY), so it is absent from the JSON entirely — not null — when the person has none. phone and email are likewise populated only by this mapping; other consumers of PersonSummaryDTO leave them null.
An empty array is returned when nothing matches. Every result is guaranteed to be a non-draft member of the resolved organisation.
Organisation context (frontend)
OrgContextService (membership-ui) is the single source of truth for the current organisation id. It derives the organisation from the authenticated principal’s JWT orgId claim, falling back to a configured default (Helderberg Nature Reserve) when the token carries no such claim. New features must obtain the organisation from this service — for the member search the screen passes organisationId = OrgContextService.getOrgId() — rather than hard-coding a literal.
The service exposes a synchronous getOrgId(): number, an orgId$ observable, and a refresh() that re-resolves the claim and republishes it (called after login, since the org is read from the JWT). It is intentionally forward-compatible with a future multi-organisation / org-switching model even though a single active organisation is delivered today.