Summary
/api/v1/projects/<slug>/people/ nests a person object that carries name, url, url_name, thumbnail, and
image_original — but not current_title or current_school. Both are already on PersonSerializer and both are
already cached_property on the model, so this is a nested-serializer field list change, not new data.
Why
Project Sidewalk's About page (ProjectSidewalk/SidewalkWebpage#4664) renders the current-team cards from the project
roster. Each card wants the member's title and affiliation as they are today ("Professor · University of
Washington"), which is exactly current_title / current_school — the project row's position_title is frozen at the
position they held when the stint began, so it's only a fallback.
Because those two fields live only on the person-detail endpoint, the page has to issue one extra request per active
member just to fill in two strings. That's 11 requests today on top of the roster fetch, and it grows with the team:
GET /api/v1/projects/sidewalk/people/ (2 pages)
GET /api/v1/people/jonfroehlich/ ┐
GET /api/v1/people/mikeysaugstad/ │ 11 requests, 2 fields each
GET /api/v1/people/yochaieisenberg/ │
... ┘
They're issued concurrently and cached client-side, so this isn't urgent — but it's 11 round-trips to your server per
cold visit for data you already serialize elsewhere, and every one of them is a chance for a card to render without its
title.
This is the same shape as #1432, which added the cropped thumbnail to both the person endpoint and the nested
person object for exactly this reason.
Proposed change
Add current_title and current_school to whichever nested/summary person serializer
ProjectRoleSerializer.person uses. current_department would be free alongside them (Person.get_current_department
exists), though the About page doesn't need it.
If you'd rather not widen the nested object for every consumer, an alternative that also works: accept a
?expand=person (or similar) on the project-people endpoint. Either is fine on our end — the consumer change is a few
lines and deleting a Promise.allSettled block.
Consumer
public/js/aboutPage.js (#renderTeam) in ProjectSidewalk/SidewalkWebpage, covered by test/js/aboutPage.test.js,
which pins the payload shapes of /api/v1/projects/sidewalk/people/, /api/v1/people/<url_name>/,
/api/v1/projects/sidewalk/publications/, and /api/v1/projects/sidewalk/grants/. If any of those shapes change,
those tests are where it surfaces.
Follow-on to #1426 and #1432, both of which landed and are working well — the About page now renders contributor
credentials ("Undergrad, UW") and cropped headshots straight off this API.
Unrelated note, carried over from #1426
The per-project role is still blank for most of the 11 people currently active on Project Sidewalk, so their role line
falls back to current_title — which is why the page reads "Director" for Judy Shanley rather than anything about her
role on the project. That one's a data-entry fix in the admin, not code.
Summary
/api/v1/projects/<slug>/people/nests apersonobject that carriesname,url,url_name,thumbnail, andimage_original— but notcurrent_titleorcurrent_school. Both are already onPersonSerializerand both arealready
cached_propertyon the model, so this is a nested-serializer field list change, not new data.Why
Project Sidewalk's About page (ProjectSidewalk/SidewalkWebpage#4664) renders the current-team cards from the project
roster. Each card wants the member's title and affiliation as they are today ("Professor · University of
Washington"), which is exactly
current_title/current_school— the project row'sposition_titleis frozen at theposition they held when the stint began, so it's only a fallback.
Because those two fields live only on the person-detail endpoint, the page has to issue one extra request per active
member just to fill in two strings. That's 11 requests today on top of the roster fetch, and it grows with the team:
They're issued concurrently and cached client-side, so this isn't urgent — but it's 11 round-trips to your server per
cold visit for data you already serialize elsewhere, and every one of them is a chance for a card to render without its
title.
This is the same shape as #1432, which added the cropped
thumbnailto both the person endpoint and the nestedpersonobject for exactly this reason.Proposed change
Add
current_titleandcurrent_schoolto whichever nested/summary person serializerProjectRoleSerializer.personuses.current_departmentwould be free alongside them (Person.get_current_departmentexists), though the About page doesn't need it.
If you'd rather not widen the nested object for every consumer, an alternative that also works: accept a
?expand=person(or similar) on the project-people endpoint. Either is fine on our end — the consumer change is a fewlines and deleting a
Promise.allSettledblock.Consumer
public/js/aboutPage.js(#renderTeam) in ProjectSidewalk/SidewalkWebpage, covered bytest/js/aboutPage.test.js,which pins the payload shapes of
/api/v1/projects/sidewalk/people/,/api/v1/people/<url_name>/,/api/v1/projects/sidewalk/publications/, and/api/v1/projects/sidewalk/grants/. If any of those shapes change,those tests are where it surfaces.
Follow-on to #1426 and #1432, both of which landed and are working well — the About page now renders contributor
credentials ("Undergrad, UW") and cropped headshots straight off this API.
Unrelated note, carried over from #1426
The per-project
roleis still blank for most of the 11 people currently active on Project Sidewalk, so their role linefalls back to
current_title— which is why the page reads "Director" for Judy Shanley rather than anything about herrole on the project. That one's a data-entry fix in the admin, not code.