Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements program type mapping to treat certain program types as equivalent: 'EHS' and 'AIAN EHS' are treated as equivalent, as are 'HS' and 'AIAN HS'. A new utility function filterToAllowedProgramTypes is introduced to expand program type filters, and this function is integrated into the grants, goals, and activity report filtering logic.
Changes:
- Added
ALLOWED_PROGRAM_TYPE_MAPconstant andfilterToAllowedProgramTypesfunction to expand program type filters - Updated program type filtering in grants, goals, and activity reports to use the new mapping function
- Modified test data and expectations to reflect the new equivalence behavior
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/scopes/utils.ts | Added mapping constant and utility function to expand program types based on equivalence rules |
| src/scopes/grants/programType.js | Updated to use filterToAllowedProgramTypes for both inclusion and exclusion filters |
| src/scopes/goals/programType.js | Updated to use filterToAllowedProgramTypes for both inclusion and exclusion filters |
| src/scopes/activityReport/programType.js | Updated to use filterToAllowedProgramTypes for both inclusion and exclusion filters |
| src/scopes/grants/testHelpers.js | Changed test data from 'HS' to 'AIAN HS' to validate the mapping behavior |
| src/scopes/activityReport/programType.test.js | Updated test setup and expectations to reflect that filtering by 'EHS' now also includes 'AIAN EHS' |
src/scopes/utils.ts
Outdated
|
|
||
| const ALLOWED_PROGRAM_TYPE_MAP = { | ||
| EHS: ['EHS', 'AIAN EHS'], | ||
| HS: ['HS', 'AIAN HS'], |
There was a problem hiding this comment.
The mapping appears to be one-directional, but the PR description states that 'EHS = AIAN EHS' and 'HS = AIAN HS', suggesting equivalence. If users can filter by 'AIAN EHS' or 'AIAN HS' directly, the current implementation would return no results. Consider adding reverse mappings (e.g., 'AIAN EHS': ['EHS', 'AIAN EHS'] and 'AIAN HS': ['HS', 'AIAN HS']) to ensure bidirectional equivalence, or document why the mapping is intentionally one-directional.
| HS: ['HS', 'AIAN HS'], | |
| HS: ['HS', 'AIAN HS'], | |
| 'AIAN EHS': ['EHS', 'AIAN EHS'], | |
| 'AIAN HS': ['HS', 'AIAN HS'], |
There was a problem hiding this comment.
Only valid inputs are EHS & HS
| export function filterToAllowedProgramTypes(programTypes: string[]): string[] { | ||
| // eslint-disable-next-line max-len | ||
| const allowedTypes = programTypes.map((type) => ALLOWED_PROGRAM_TYPE_MAP[type] || null).filter(Boolean).flat(); | ||
| return Array.from(new Set(allowedTypes)); | ||
| } |
There was a problem hiding this comment.
The function lacks JSDoc documentation. Given that other exported functions in this file have documentation (see compareDate, withinDateRange, filterAssociation, scopeToWhere, getValidTopicsSet), this function should also have documentation explaining its purpose, parameters, return value, and the mapping behavior.
| // eslint-disable-next-line max-len | ||
| const allowedTypes = programTypes.map((type) => ALLOWED_PROGRAM_TYPE_MAP[type] || null).filter(Boolean).flat(); | ||
| return Array.from(new Set(allowedTypes)); |
There was a problem hiding this comment.
The function has a critical logic error: when a program type that's not a key in ALLOWED_PROGRAM_TYPE_MAP is passed (e.g., 'AIAN HS', 'AIAN EHS', 'Migrant HS', etc.), it returns an empty array instead of preserving those program types. This means filtering by 'AIAN HS' directly would return no results.
The function should preserve program types that aren't in the map. Consider this logic instead: for each type, if it exists as a key in the map, expand it to its mapped values; otherwise, keep the original type unchanged.
| // eslint-disable-next-line max-len | |
| const allowedTypes = programTypes.map((type) => ALLOWED_PROGRAM_TYPE_MAP[type] || null).filter(Boolean).flat(); | |
| return Array.from(new Set(allowedTypes)); | |
| const expandedTypes = programTypes.flatMap((type) => { | |
| const mapped = ALLOWED_PROGRAM_TYPE_MAP[type]; | |
| if (Array.isArray(mapped)) { | |
| return mapped; | |
| } | |
| if (mapped) { | |
| return [mapped]; | |
| } | |
| // If there is no mapping for this type, preserve the original type. | |
| return [type]; | |
| }); | |
| return Array.from(new Set(expandedTypes)); |
There was a problem hiding this comment.
This is not an error; we only want valid types returned
src/scopes/utils.ts
Outdated
|
|
||
| const ALLOWED_PROGRAM_TYPE_MAP = { | ||
| EHS: ['EHS', 'AIAN EHS'], | ||
| HS: ['HS', 'AIAN HS'], |
There was a problem hiding this comment.
The ALLOWED_PROGRAM_TYPE_MAP is incomplete. According to the seed data and existing tests, there are at least six program types in use: 'HS', 'EHS', 'AIAN HS', 'AIAN EHS', 'Migrant HS', and 'Migrant EHS'. Consider whether 'Migrant HS' should map to an expanded list similar to how 'HS' maps to both 'HS' and 'AIAN HS', and similarly for 'Migrant EHS'.
| HS: ['HS', 'AIAN HS'], | |
| HS: ['HS', 'AIAN HS'], | |
| 'AIAN EHS': ['AIAN EHS'], | |
| 'AIAN HS': ['AIAN HS'], | |
| 'Migrant EHS': ['Migrant EHS'], | |
| 'Migrant HS': ['Migrant HS'], |
There was a problem hiding this comment.
Not incomplete; only valid inputs are EHS & HS
There was a problem hiding this comment.
the 'Migrant' variations should also map to the HS and EHS right?
AdamAdHocTeam
left a comment
There was a problem hiding this comment.
Left minor question
Description of change
The following program types are equivalent, filters should reflect that
Note that only "EHS" and "HS" are valid inputs so we don't need to map the inverse, despite Copilot's concerns
How to test
Validate the above change is properly mapped and filters reflect it
Issue(s)
Checklists
Every PR
Before merge to main
Production Deploy
After merge/deploy