-
Notifications
You must be signed in to change notification settings - Fork 3
CHI-3500: Make address values for USCH into filterable paths #950
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
a41eec4
8b6abef
b6a74a6
0c33d63
287b65b
8f8860e
7f1cb59
b733370
92d372f
dd7496f
83d9406
a273bb8
15841df
57a9a88
e10f6e6
c1c639e
6a78def
9916608
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,69 @@ import type { AccountSID } from '@tech-matters/types'; | |
| import type { FlatResource } from '@tech-matters/resources-types'; | ||
| import { parse } from 'date-fns'; | ||
|
|
||
| // https://gist.github.com/mshafrir/2646763 | ||
| const US_STATE_CODE_MAPPING = { | ||
| AL: 'Alabama', | ||
| AK: 'Alaska', | ||
| AS: 'American Samoa', | ||
| AZ: 'Arizona', | ||
| AR: 'Arkansas', | ||
| CA: 'California', | ||
| CO: 'Colorado', | ||
| CT: 'Connecticut', | ||
| DE: 'Delaware', | ||
| DC: 'District Of Columbia', | ||
| FM: 'Federated States Of Micronesia', | ||
| FL: 'Florida', | ||
| GA: 'Georgia', | ||
| GU: 'Guam', | ||
| HI: 'Hawaii', | ||
| ID: 'Idaho', | ||
| IL: 'Illinois', | ||
| IN: 'Indiana', | ||
| IA: 'Iowa', | ||
| KS: 'Kansas', | ||
| KY: 'Kentucky', | ||
| LA: 'Louisiana', | ||
| ME: 'Maine', | ||
| MH: 'Marshall Islands', | ||
| MD: 'Maryland', | ||
| MA: 'Massachusetts', | ||
| MI: 'Michigan', | ||
| MN: 'Minnesota', | ||
| MS: 'Mississippi', | ||
| MO: 'Missouri', | ||
| MT: 'Montana', | ||
| NE: 'Nebraska', | ||
| NV: 'Nevada', | ||
| NH: 'New Hampshire', | ||
| NJ: 'New Jersey', | ||
| NM: 'New Mexico', | ||
| NY: 'New York', | ||
| NC: 'North Carolina', | ||
| ND: 'North Dakota', | ||
| MP: 'Northern Mariana Islands', | ||
| OH: 'Ohio', | ||
| OK: 'Oklahoma', | ||
| OR: 'Oregon', | ||
| PW: 'Palau', | ||
| PA: 'Pennsylvania', | ||
| PR: 'Puerto Rico', | ||
| RI: 'Rhode Island', | ||
| SC: 'South Carolina', | ||
| SD: 'South Dakota', | ||
| TN: 'Tennessee', | ||
| TX: 'Texas', | ||
| UT: 'Utah', | ||
| VT: 'Vermont', | ||
| VI: 'Virgin Islands', | ||
| VA: 'Virginia', | ||
| WA: 'Washington', | ||
| WV: 'West Virginia', | ||
| WI: 'Wisconsin', | ||
| WY: 'Wyoming', | ||
| } as Record<string, string>; | ||
|
|
||
| /* | ||
| * This defines all the mapping logic to convert Childhelp resource to an Aselo resource. | ||
| * The mapping is defined as a tree of nodes. | ||
|
|
@@ -93,6 +156,20 @@ export type UschExpandedResource = Partial< | |
| } | ||
| >; | ||
|
|
||
| const lookupUsStateNameFromCode = ({ | ||
| Country: country, | ||
| StateProvince: stateProvince, | ||
| }: UschExpandedResource): string | undefined => { | ||
| if ( | ||
| ['us', 'usa', 'unitedstates'].includes( | ||
| (country ?? '').toLowerCase().replace(/[.\s]/, ''), | ||
| ) | ||
| ) { | ||
| return US_STATE_CODE_MAPPING[stateProvince ?? ''] ?? stateProvince; | ||
| } | ||
| return stateProvince; | ||
| }; | ||
|
|
||
| export const expandCsvLine = (csv: UschCsvResource): UschExpandedResource => { | ||
| const expanded = { | ||
| ...csv, | ||
|
|
@@ -113,8 +190,27 @@ export const USCH_MAPPING_NODE: MappingNode = { | |
| Name: resourceFieldMapping('name'), | ||
| AlternateName: translatableAttributeMapping('alternateName', { language: 'en' }), | ||
| Address: attributeMapping('stringAttributes', 'address/street'), | ||
| City: attributeMapping('stringAttributes', 'address/city'), | ||
| StateProvince: attributeMapping('stringAttributes', 'address/province'), | ||
| City: attributeMapping('stringAttributes', 'address/city', { | ||
| value: ({ currentValue, rootResource }) => | ||
| [ | ||
| (rootResource as UschExpandedResource).Country, | ||
| (rootResource as UschExpandedResource).StateProvince, | ||
| currentValue, | ||
| ].join('/'), | ||
| info: ({ currentValue, rootResource }) => ({ | ||
| country: (rootResource as UschExpandedResource).Country, | ||
| stateProvince: lookupUsStateNameFromCode(rootResource as UschExpandedResource), | ||
| name: currentValue, | ||
| }), | ||
| }), | ||
| StateProvince: attributeMapping('stringAttributes', 'address/province', { | ||
| value: ({ currentValue, rootResource }) => | ||
| `${(rootResource as UschExpandedResource).Country}/${currentValue}`, | ||
| info: ({ rootResource }) => ({ | ||
| country: (rootResource as UschExpandedResource).Country, | ||
| name: lookupUsStateNameFromCode(rootResource as UschExpandedResource), | ||
| }), | ||
| }), | ||
| PostalCode: attributeMapping('stringAttributes', 'address/postalCode'), | ||
| Country: attributeMapping('stringAttributes', 'address/country'), | ||
| HoursOfOperation: translatableAttributeMapping('hoursOfOperation'), | ||
|
|
@@ -189,7 +285,16 @@ export const USCH_MAPPING_NODE: MappingNode = { | |
| Coverage: { | ||
| children: { | ||
| '{coverageIndex}': translatableAttributeMapping('coverage/{coverageIndex}', { | ||
| value: ({ currentValue }) => currentValue, | ||
| value: ({ currentValue }) => | ||
| `United States/${currentValue.replace(/\s+-\s+/, '/')}`, | ||
|
||
| info: ({ currentValue }) => { | ||
| const [stateProvince, city] = currentValue.toString().split(/\s+-\s+/); | ||
| return { | ||
| country: 'United States', | ||
| stateProvince, | ||
| city, | ||
| }; | ||
| }, | ||
| language: 'en', | ||
| }), | ||
| }, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,9 +22,9 @@ const referenceAttributeRoutes = () => { | |
| const router: IRouter = Router(); | ||
| const { getResourceReferenceAttributeList } = referenceAttributeService(); | ||
|
|
||
| router.get('/:list', async (req, res) => { | ||
| router.get('/*', async (req, res) => { | ||
| const { valueStartsWith, language } = req.query; | ||
| const { list } = req.params; | ||
| const list = (req as any).params[0]; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we document what's this doing? Is
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes /* returns a list, which is documented in Express, I'm not sure we should document standard API behaviour |
||
| const result = await getResourceReferenceAttributeList( | ||
| req.hrmAccountId as AccountSID, | ||
| list, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,8 +63,10 @@ const resourceRoutes = () => { | |
| res.json(suggestions); | ||
| }); | ||
|
|
||
| router.get('/list-string-attributes', async (req, res) => { | ||
| const { key, language } = req.query; | ||
| const listStringAttributesHandler = async (req: any, res: any) => { | ||
| const { key: queryKey, language, valueStartsWith } = req.query; | ||
| console.debug('PATH PARAMS', req.params); | ||
| const key = req.params[0] || queryKey; | ||
stephenhand marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (!key || typeof key !== 'string') { | ||
| res.status(400).json({ | ||
|
|
@@ -84,10 +86,14 @@ const resourceRoutes = () => { | |
| <AccountSID>req.hrmAccountId, | ||
| key, | ||
| language, | ||
| valueStartsWith, | ||
| ); | ||
|
|
||
| res.json(attributes); | ||
| }); | ||
| }; | ||
|
|
||
| router.get('/list-string-attributes/*', listStringAttributesHandler); | ||
| router.get('/list-string-attributes', listStringAttributesHandler); | ||
|
Comment on lines
+99
to
+100
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the difference of this two endpoints, when should each be used?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One specifies the key on the path, the other in a query item. I prefer using the path because it's more consistent with the Just being indecisive really, and it wasn't much extra code to support both forms |
||
|
|
||
| return router; | ||
| }; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| /** | ||
| * Copyright (C) 2021-2025 Technology Matters | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU Affero General Public License as published | ||
| * by the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU Affero General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Affero General Public License | ||
| * along with this program. If not, see https://www.gnu.org/licenses/. | ||
| */ | ||
|
|
||
| import { db } from '../../src/connection-pool'; | ||
|
|
||
| export const clearDb = async () => { | ||
| await db.none(` | ||
| TRUNCATE resources."ResourceReferenceStringAttributeValues" CASCADE; | ||
| `); | ||
| await db.none(` | ||
| TRUNCATE resources."Resources" CASCADE; | ||
| `); | ||
| await db.none(` | ||
| TRUNCATE resources."Accounts"; | ||
| `); | ||
| }; | ||
stephenhand marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Uh oh!
There was an error while loading. Please reload this page.