-
Notifications
You must be signed in to change notification settings - Fork 92
chore: amend dynamic field values #10866
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
Conversation
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greptile Overview
Important Files Changed
File Analysis
| Filename | Score | Overview |
|---|---|---|
| packages/commons/src/events/CompositeFieldValue.ts | 0/5 | Refactored address field schemas to use discriminated unions and added nested data structure for QueryParamReader; contains critical syntax error on line 136 |
| packages/commons/src/events/FieldValue.ts | 4/5 | Refactored DataFieldValue from record to nested object structure, removed StreetLevelDetailsValue from union |
| packages/commons/src/events/FieldConfig.ts | 5/5 | Changed DefaultAddressFieldValue to extend DomesticAddressFieldValue instead of AddressFieldValue |
3 files reviewed, 1 comment
makelicious
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very good, thank you 🙏 . Some type related comments. Let's review it once we are finished
packages/client/src/v2-events/features/events/registered-fields/Address.tsx
Outdated
Show resolved
Hide resolved
packages/client/src/v2-events/features/events/registered-fields/Address.tsx
Show resolved
Hide resolved
packages/commons/src/events/utils.ts
Outdated
| return omitHiddenFields( | ||
| annotationFields, | ||
| { ...declaration, ...annotation }, | ||
| { ...declaration, ...annotation } as EventState, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check if we really need to cast this? If we do, ActionUpdate is the truthful one. At least stripping nulls from annotation (or the combination) should make it EventState
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{ ...declaration, ...annotation }, declaration and annotation together can be treated as ActionUpdate since annotation is ActionUpdate and it's values are nullish values(FieldUpdateValue) which can not be EventState(FieldValue)
| streetLevelDetails: { | ||
| province: 'a45b982a-5c7b-4bd9-8fd8-a42d0994054c', | ||
| district: '5ef450bc-712d-48ad-93f3-8da0fa453baa', | ||
| urbanOrRural: 'RURAL' as const, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think urbanOrRural is not used anymore. In the best case, this should throw an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const StreetLevelDetailsValue = z
.record(z.string(), z.string())
.optional()streetLevelDetails accepts any objects with a string as a key and a value, right? On that basis, i dont think it should throw errors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't we validate them against whatever countryconfig specifies?
// src/form/street-address-configuration.ts
export const defaultStreetAddressConfiguration = [
{
id: 'town',
required: false,
parent: field('country'),
label: {
id: 'field.address.town.label',
defaultMessage: 'Town',
description: 'This is the label for the field'
},
conditionals: [
{
type: ConditionalType.SHOW,
conditional: and(
isDomesticAddress(),
not(field('district').isUndefined())
)
}
],
type: FieldType.TEXT
},
{
id: 'residentialArea',
required: false,
parent: field('country'),
label: {
id: 'field.address.residentialArea.label',
defaultMessage: 'Residential Area',
description: 'This is the label for the field'
},
conditionals: [
{
type: ConditionalType.SHOW,
conditional: and(
isDomesticAddress(),
not(field('district').isUndefined())
)
}
],
type: FieldType.TEXT
},
{
id: 'street',
required: false,
parent: field('country'),
label: {
id: 'field.address.street.label',
defaultMessage: 'Street',
description: 'This is the label for the field'
},
conditionals: [
{
type: ConditionalType.SHOW,
conditional: and(
isDomesticAddress(),
not(field('district').isUndefined())
)
}
],
type: FieldType.TEXT
},
{
id: 'number',
required: false,
parent: field('country'),
label: {
id: 'field.address.number.label',
defaultMessage: 'Number',
description: 'This is the label for the field'
},
conditionals: [
{
type: ConditionalType.SHOW,
conditional: and(
isDomesticAddress(),
not(field('district').isUndefined())
)
}
],
type: FieldType.TEXT
},
{
id: 'zipCode',
required: false,
parent: field('country'),
label: {
id: 'field.address.postcodeOrZip.label',
defaultMessage: 'Postcode / Zip',
description: 'This is the label for the field'
},
conditionals: [
{
type: ConditionalType.SHOW,
conditional: and(
isDomesticAddress(),
not(field('district').isUndefined())
)
}
],
type: FieldType.TEXT
},
{
id: 'state',
conditionals: [
{
type: ConditionalType.SHOW,
conditional: isInternationalAddress()
}
],
parent: field('country'),
required: {
message: {
id: 'field.address.state.label.required',
description: 'State required message',
defaultMessage: 'State is required'
}
},
label: {
id: 'field.address.state.label',
defaultMessage: 'State',
description: 'This is the label for the field'
},
type: FieldType.TEXT
},
{
id: 'district2',
parent: field('country'),
conditionals: [
{
type: ConditionalType.SHOW,
conditional: isInternationalAddress()
}
],
required: {
message: {
id: 'field.address.district2.label.required',
description: 'District2 required message',
defaultMessage: 'District is required'
}
},
label: {
id: 'field.address.district2.label',
defaultMessage: 'District',
description: 'This is the label for the field'
},
type: FieldType.TEXT
},
{
id: 'cityOrTown',
parent: field('country'),
conditionals: [
{
type: ConditionalType.SHOW,
conditional: isInternationalAddress()
}
],
required: false,
label: {
id: 'field.address.cityOrTown.label',
defaultMessage: 'City / Town',
description: 'This is the label for the field'
},
type: FieldType.TEXT
},
{
id: 'addressLine1',
parent: field('country'),
conditionals: [
{
type: ConditionalType.SHOW,
conditional: isInternationalAddress()
}
],
required: false,
label: {
id: 'field.address.addressLine1.label',
defaultMessage: 'Address Line 1',
description: 'This is the label for the field'
},
type: FieldType.TEXT
},
{
id: 'addressLine2',
parent: field('country'),
conditionals: [
{
type: ConditionalType.SHOW,
conditional: isInternationalAddress()
}
],
required: false,
label: {
id: 'field.address.addressLine2.label',
defaultMessage: 'Address Line 2',
description: 'This is the label for the field'
},
type: FieldType.TEXT
},
{
id: 'addressLine3',
parent: field('country'),
conditionals: [
{
type: ConditionalType.SHOW,
conditional: isInternationalAddress()
}
],
required: false,
label: {
id: 'field.address.addressLine3.label',
defaultMessage: 'Address Line 3',
description: 'This is the label for the field'
},
type: FieldType.TEXT
},
{
id: 'postcodeOrZip',
parent: field('country'),
conditionals: [
{
type: ConditionalType.SHOW,
conditional: isInternationalAddress()
}
],
required: false,
label: {
id: 'field.address.postcodeOrZip.label',
defaultMessage: 'Postcode / Zip',
description: 'This is the label for the field'
},
type: FieldType.TEXT
}
]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greptile Overview
Important Files Changed
File Analysis
| Filename | Score | Overview |
|---|---|---|
| packages/commons/src/events/FieldValue.ts | 5/5 | Restructured FieldValue and FieldUpdateValue types to use explicit type annotations with z.ZodType, removed StreetLevelDetails as top-level types, and changed DataFieldValue to wrap data in an object structure |
| packages/commons/src/events/CompositeFieldValue.ts | 5/5 | Refactored AddressFieldValue to use discriminated unions for DOMESTIC vs INTERNATIONAL, and changed QueryParamReaderFieldValue to wrap params in an object structure |
| packages/client/src/v2-events/features/events/registered-fields/QueryParamReader.tsx | 5/5 | Updated to wrap params in params object property to match new QueryParamReaderFieldValue structure |
| packages/client/src/v2-events/features/events/registered-fields/Data.tsx | 5/5 | Updated to wrap data values in data object property and access via value.data[id] to match new DataFieldValue structure |
| packages/client/src/v2-events/features/events/registered-fields/Address.tsx | 5/5 | Added type guards checking addressType === AddressType.DOMESTIC before accessing administrativeArea to handle discriminated union properly |
| packages/commons/src/events/utils.ts | 5/5 | Added generic type parameters and updated return types to properly handle EventState vs ActionUpdate, added satisfies clause for type safety |
| packages/events/src/service/indexing/utils.ts | 5/5 | Updated to access administrativeArea only after checking addressType === DOMESTIC to properly handle discriminated union |
23 files reviewed, no comments
makelicious
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well done on the improvements 🏅 . Could you check the changes again: https://www.chromatic.com/review?appId=67862a3f4457d14c317e5cca&number=10866&type=linked&activeElementId=comparison-test-key-68b70a692b622cd342f08dd5-1200px&view=changes
If I read this right, we lose data on the address review. Is it due bad mock data? If so, could it be updated
| data: z.record(z.string(), z.string()) | ||
| }) | ||
|
|
||
| const ReadDataValue = z.object({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this still needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be. With this, FieldUpdateValue would not compile any values with this shape z.record(z.string(), z.string())
| 'child.details': { | ||
| nested: 'value' | ||
| } | ||
| 'child.details': 'value' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests were overwritten because typescript were complaining of these unknown keys e.g. - dob, nested being passed as keys of FieldValue. When a key was added to QueryParamReaderFieldValue, rather than being z.record(z.string(), z.string()), these were thrown.
| administrativeArea: '27160bbd-32d1-4625-812f-860226bfb92a', | ||
| streetLevelDetails: { | ||
| town: 'Example Town', | ||
| residentialArea: 'Example Residential Area', | ||
| street: 'Example Street', | ||
| number: '55', | ||
| zipCode: '123456', | ||
| state: 'Example State', | ||
| district2: 'Example District 2' | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we changing the data intentionally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! It's tightened by type here with EventState
packages/client/src/v2-events/features/events/registered-fields/Address.tsx
Outdated
Show resolved
Hide resolved
...ages/client/src/v2-events/features/events/registered-fields/IdReader.interaction.stories.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to revisit this as the the current mock values probably aren't aligned with the original intention of the test
| 'child.details': { | ||
| dob: new Date('2125-01-01').toISOString().split('T')[0] | ||
| } | ||
| 'child.details': new Date('2125-01-01').toISOString().split('T')[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test is validating the support for $now variable even in nested levels, so it should be passing with the previous value. Although as .object has been deprecated, what we could do it use .get('dob') instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
used .get('data')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep the nested tests intact
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah! with known keys from FieldValues
| // @NOTE: This happens to map to a valid location in events test environment. Updating it will break tests. | ||
| // @TODO: Find a way to give out context aware mock values in the future. | ||
| administrativeArea: '27160bbd-32d1-4625-812f-860226bfb92a' as UUID | ||
| administrativeArea: '27160bbd-32d1-4625-812f-860226bfb92a' as UUID, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove the todo comments now?
| it('allows optional middlename', () => { | ||
| const schema = getDynamicNameValue(NameField) | ||
| expect(() => | ||
| schema.parse({ | ||
| firstname: 'Jane', | ||
| surname: 'Doe' | ||
| }) | ||
| ).not.toThrow() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a middlename being passed tho
| return z.object({ | ||
| country: z.string(), | ||
| addressType: z.enum([AddressType.DOMESTIC, AddressType.INTERNATIONAL]), | ||
| administrativeArea: z | ||
| .string() | ||
| .uuid() | ||
| .optional() /* Leaf level admin structure */, | ||
| streetLevelDetails: StreetLevelDetailsUpdateValue.refine((arg) => { | ||
| const submittedKeys = Object.keys(arg ?? {}) | ||
| const configIds = | ||
| (streetAddressConfig && streetAddressConfig.map((a) => a.id)) ?? [] | ||
| const invalidKeys = submittedKeys.filter( | ||
| (key) => !configIds.includes(key) | ||
| ) | ||
| if (invalidKeys.length) { | ||
| // eslint-disable-next-line no-console | ||
| console.log( | ||
| 'Invalid streetLevelDetails: unknown keys', | ||
| JSON.stringify(invalidKeys, null, 2) | ||
| ) | ||
| return false | ||
| } | ||
|
|
||
| return true | ||
| }) | ||
| }) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's check if we can use .shape to reuse the one defined in CompositeValue.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can a country be nullish for FieldUpdateValue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
most likely not
|
Your environment is deployed to https://ocrvs-10634.e2e-k8s.opencrvs.dev |
Description
Country config PR: opencrvs/opencrvs-countryconfig#1138
Farajaland PR: opencrvs/opencrvs-farajaland#1811
Clearly describe what has been changed. Include relevant context or background.
Explain how the issue was fixed (if applicable) and the root cause.
Link this pull request to the GitHub issue (and optionally name the branch
ocrvs-<issue #>)Checklist