Summary
`collectionToSchemaPrefix` in `packages/contracts/src/validation/openapi-loader.js` incorrectly treats the trailing 's' in non-plural words as a plural suffix and strips it.
Example: The collection name `application-review-progress` produces the schema prefix `ApplicationReviewProgres` instead of `ApplicationReviewProgress`. The word "progress" ends in 's' but is not a plural noun.
Root cause
The function applies `.slice(0, -1)` to the last segment when it ends in 's', unconditionally:
```js
else if (s.endsWith('s')) s = s.slice(0, -1);
```
This correctly singularizes `members → member` and `applications → application` but incorrectly strips `progress → progres`.
Impact
Seed files that contain `ReviewProgressEntry` records must use the key prefix `ApplicationReviewProgres` (misspelled) for the seeder to pick them up. Keys starting with the intuitively correct `ApplicationReviewProgress` would fail to match — though they would be matched as a substring of `ApplicationReviewProgres`, so in practice they work, but the function output is confusing and wrong.
Fix
Add an allow-list of known non-plural words that end in 's', or use a more sophisticated singularization heuristic. At minimum, add "progress" to a skip list:
```js
const NON_PLURAL_ENDINGS = new Set(['progress', 'status', 'access', 'address', 'process']);
if (!NON_PLURAL_ENDINGS.has(s) && s.endsWith('s')) s = s.slice(0, -1);
```
How to validate
```js
import { collectionToSchemaPrefix } from '@codeforamerica/safety-net-blueprint-contracts/loader';
collectionToSchemaPrefix('application-review-progress');
// Before fix: 'ApplicationReviewProgres'
// After fix: 'ApplicationReviewProgress'
```
Summary
`collectionToSchemaPrefix` in `packages/contracts/src/validation/openapi-loader.js` incorrectly treats the trailing 's' in non-plural words as a plural suffix and strips it.
Example: The collection name `application-review-progress` produces the schema prefix `ApplicationReviewProgres` instead of `ApplicationReviewProgress`. The word "progress" ends in 's' but is not a plural noun.
Root cause
The function applies `.slice(0, -1)` to the last segment when it ends in 's', unconditionally:
```js
else if (s.endsWith('s')) s = s.slice(0, -1);
```
This correctly singularizes `members → member` and `applications → application` but incorrectly strips `progress → progres`.
Impact
Seed files that contain `ReviewProgressEntry` records must use the key prefix `ApplicationReviewProgres` (misspelled) for the seeder to pick them up. Keys starting with the intuitively correct `ApplicationReviewProgress` would fail to match — though they would be matched as a substring of `ApplicationReviewProgres`, so in practice they work, but the function output is confusing and wrong.
Fix
Add an allow-list of known non-plural words that end in 's', or use a more sophisticated singularization heuristic. At minimum, add "progress" to a skip list:
```js
const NON_PLURAL_ENDINGS = new Set(['progress', 'status', 'access', 'address', 'process']);
if (!NON_PLURAL_ENDINGS.has(s) && s.endsWith('s')) s = s.slice(0, -1);
```
How to validate
```js
import { collectionToSchemaPrefix } from '@codeforamerica/safety-net-blueprint-contracts/loader';
collectionToSchemaPrefix('application-review-progress');
// Before fix: 'ApplicationReviewProgres'
// After fix: 'ApplicationReviewProgress'
```