Skip to content

Emit changemaker IDs to make permissions easier#274

Merged
bickelj merged 1 commit into
mainfrom
list-changemaker-ids-on-lookup-from-pdc
Jul 17, 2026
Merged

Emit changemaker IDs to make permissions easier#274
bickelj merged 1 commit into
mainfrom
list-changemaker-ids-on-lookup-from-pdc

Conversation

@bickelj

@bickelj bickelj commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

When doing a lookupFromPdc command, try to emit the permissions.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the charityNavigator CLI commands to surface which PDC changemakers correspond to Charity Navigator results, making it easier to act on/verify permissions by ID during lookupFromPdc, and it adjusts the updateAll upload loop to iterate over validated nonprofits.

Changes:

  • Add lookupFromPdc logging of changemaker IDs derived from Charity Navigator nonprofitsPublic.edges.
  • Add an early return when the Charity Navigator GraphQL response contains no data.
  • Change updateAll to iterate over nonprofits (post-validation) instead of raw edges.
Comments suppressed due to low confidence (1)

src/charityNavigator.ts:392

  • The async work inside nonprofits.map(async ...) (and the nested Object.entries(...).map(async ...)) is never awaited. That means the command can finish before all field posts complete, and any rejections become unhandled. Collect and await the promises (e.g., via Promise.all) so the CLI only exits after uploads finish and errors propagate.
    nonprofits.map(async (e) => {
      const changemaker = getChangemakerByEin(e.ein, changemakers);
      if (changemaker !== null) {
        Object.entries(baseFieldMap).map(async ([cnAttributeName, baseFieldShortCode]) => {
          const cnAttribute = e[cnAttributeName as keyof NonprofitPublic];

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/charityNavigator.ts Outdated
Comment on lines +298 to +302
const { edges } = charityNavResponse.data.nonprofitsPublic;
const nonprofits = edges.filter((e): e is NonprofitPublic => isNonprofitPublic(e));
const changemakerIds = nonprofits.map(
(e) => getChangemakerByEin(e.ein, changemakers),
).filter((c) => c !== null).map((c) => c.id);
@bickelj
bickelj force-pushed the list-changemaker-ids-on-lookup-from-pdc branch from 8ada522 to 1262d46 Compare July 17, 2026 18:17

@bickelj-agent bickelj-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GLM-5.2: More than two important issues here; the two inline are the most important — unawaited nonprofits.map(async…) in updateAll (writes may not finish, rejections swallowed) and the new !data guard skipping the --output-file write on API errors. Also notable: getCharityNavigatorProfiles fetches only page 1 with a resultSize the query never uses, so the emitted IDs can be silently truncated.

Comment thread src/charityNavigator.ts
Comment thread src/charityNavigator.ts
@bickelj
bickelj force-pushed the list-changemaker-ids-on-lookup-from-pdc branch from 1262d46 to c90f42d Compare July 17, 2026 18:58

@bickelj-agent bickelj-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GLM-5.2: Re-review after force-push. The unawaited-map issue is fixed (now await Promise.all), so I resolved that thread. The guard-before-output-file issue is unchanged and left open. Two new notes below: a concurrency burst in updateAll and possible truncation of the emitted changemaker IDs.

Comment thread src/charityNavigator.ts Outdated
const fieldBatch = await postChangemakerFieldValueBatch(args.pdcApiBaseUrl, token, { sourceId: source.id, notes: `data-scripts charityNavigator.ts execution ${Date.now()}` });
// Last, for each nonprofit, for each field, post the field
edges.map(async (e) => {
await Promise.all(nonprofits.map(async (e) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GLM-5.2: Promise.all here fires every nonprofit's field POSTs at once (and, via the inner Promise.all, all fields per nonprofit), which can burst the PDC API; any single rejection also aborts the batch, leaving it partially posted. Consider bounded concurrency or a sequential loop.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bro, you were the one who suggested Promise.all

Comment thread src/charityNavigator.ts
@bickelj
bickelj force-pushed the list-changemaker-ids-on-lookup-from-pdc branch from c90f42d to e967bf4 Compare July 17, 2026 19:25
When doing a `lookupFromPdc` command, try to emit the permissions.
@bickelj
bickelj force-pushed the list-changemaker-ids-on-lookup-from-pdc branch from e967bf4 to 67ea78d Compare July 17, 2026 20:10
@bickelj

bickelj commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

As imperfect as this is, and the pagination handling needs to be improved, this is still an improvement and should be merged.

@bickelj
bickelj merged commit 8ea9c1a into main Jul 17, 2026
4 checks passed
@bickelj
bickelj deleted the list-changemaker-ids-on-lookup-from-pdc branch July 17, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants