-
Notifications
You must be signed in to change notification settings - Fork 84
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
feat(mrf): backend validation for field locking #7143
Conversation
14890fd
to
9f4bdb3
Compare
9f4bdb3
to
1d7695c
Compare
MultirespondentSubmissionMiddleware.validateUpdateMultirespondentSubmissionParams, | ||
MultirespondentSubmissionMiddleware.createFormsgAndRetrieveForm, | ||
MultirespondentSubmissionMiddleware.scanAndRetrieveAttachments, | ||
// EncryptSubmissionMiddleware.validateStorageSubmission, | ||
MultirespondentSubmissionMiddleware.validateMultirespondentSubmission, | ||
MultirespondentSubmissionMiddleware.setCurrentWorkflowStep, | ||
MultirespondentSubmissionMiddleware.encryptSubmission, | ||
updateMultirespondentSubmission, |
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 was hoping that we could use ensures here as rejections in any of these middlewares will not be grouped correctly on datadog. This can result in us having difficulty tracing back why this request failed.
I would consider these (MultirespondentSubmissionMiddleware.createFormsgAndRetrieveForm
onwards) middlewares to be high-information spans that should be grouped together. high-info as they provide more contextual information instead of just plain celebrate/joi
validations.
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, this is going to be quite a bit of refactoring. can clarify what in particular we gain out of this change? Encrypt works the same way - i feel like if we're going to change it, we should change everything at once go
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.
#4216 the middleware spans are no longer tracked causing errors originating from the middlewares to no longer be registered under the same span / trace.
This results in difficulty in tracing bugs as what we'll see on Datadog is simply an error with no further traceble logs. In order to find out what happened, we'll have to search for errors within a short window, which isn't very efficient, or robust, or making good use of DD with the amount of $$ we're paying.
I tried doing something like this locally but I didn't see any change in terms of the dd context object that's attached on the request lifecycle. Didn't try exploring this further since we're running on tight timeline.
+import tracer from 'dd-trace'
- MultirespondentSubmissionMiddleware.validateMultirespondentSubmissionParams,
+ tracer.wrap(
+ 'MultirespondentSubmissionMiddleware.validateMultirespondentSubmissionParams',
+ MultirespondentSubmissionMiddleware.validateMultirespondentSubmissionParams,
+ ),
cc: @timotheeg since we happened to discuss about this in the EngOps earlier.
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.
Would be good to open a linear ticket for this! Thanks for bringing it up
frontend/src/features/public-form/components/FormFields/FormFieldsContainer.tsx
Show resolved
Hide resolved
src/app/modules/submission/multirespondent-submission/multirespondent-submission.middleware.ts
Outdated
Show resolved
Hide resolved
src/app/modules/submission/multirespondent-submission/multirespondent-submission.middleware.ts
Outdated
Show resolved
Hide resolved
src/app/modules/submission/multirespondent-submission/multirespondent-submission.middleware.ts
Outdated
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.
LGTM! Merging this in as the attachment PR also needs some parts of this validation!
Problem
Field locking currently only has frontend validation, but we need to implement backend validation for this as well.
Closes FRM-1640
Solution
This PR implements the
MultirespondentSubmissionMiddleware.validateMultirespondentSubmission
function as it's main focus. Everything else is auxiliary and enables this function to be defined.Shared logic functions are used to replicate evaluation of submission logic. A logic adaptor is built for the backend to make use of these shared functions. It uses the client version of the schema since
FieldResponseV3
is more similar to frontendFormFieldValues
than they are to the older backendFieldResponse
.Additionally, most notably, as a result of needing to validate that non-editable fields are untouched, a notion of "response equality" is defined in
shared/utils/response-v3.ts
. Additionally, as the submission secret key is required for the backend to decrypt the existing submission in the database, the submission secret key is now sent to the backend from the frontend. This accounts for the frontend modifications seen in this PR.Note that this PR does not account for field-level validation. This has been marked as a TODO in code, where each visible and editable field itself needs to be validated with it's own validation rules (e.g. required/optional, etc).
Breaking Changes
Tests
Create a multirespondent form with a simple workflow (e.g. two respondents). Make sure there are a mix of shared and unshared fields (in this case "shared" means editable by both respondent 1 and respondent 2). In this example, I created a Q1 radio, Q2 dropdown, Q3 email, Q4 checkbox, Q5 yes/no, Q6 short answer. Respondent 1 is assigned Q1-4 and respondent 2 is assigned Q3-6, so that Q3 and Q4 are shared.
Initial submission
Respondent 2 submission
(if you're copying cURL from a browser network tab, don't forget to change the submissionId in the URL, the response itself, and the submission secret key in the data section)
Now, add logic to the form and make some fields optional.
Initial submission
Respondent 2 submission
(take note that form fields and logic are saved with a submission lifetime, so you if you change the form logics you will need to make a new initial submission to generate a new edit link)