CCM-15562: Add campaignId check to update routing config#899
CCM-15562: Add campaignId check to update routing config#899m-salaudeen wants to merge 2 commits intomainfrom
Conversation
| // get the letter templateIds from the validated and make sure they are the same type | ||
| const templateIds = | ||
| validated.cascade | ||
| ?.map((c) => c.conditionalTemplates?.map((t) => t.templateId)) |
There was a problem hiding this comment.
you're missing the non-conditional templates, those would come from the 'defaultTemplateId' field
There was a problem hiding this comment.
agree with @alexnuttall
only conditionalTemplates IDs are extracted here, we also need the defaultTemplateId on each cascade item
the repository layer already has an extractTemplateIds helper that handles both here
| // fetch all the templates of these templateIds | ||
| const templates = await Promise.all( | ||
| templateIds.map((templateId) => | ||
| this.templateClient.getTemplate(templateId as string, user) |
There was a problem hiding this comment.
I think using BatchGetItem would be better than many concurrent individual get requests
| private readonly routingConfigRepository: RoutingConfigRepository, | ||
| private readonly clientConfigRepository: ClientConfigRepository | ||
| private readonly clientConfigRepository: ClientConfigRepository, | ||
| private readonly templateClient: TemplateClient |
There was a problem hiding this comment.
you haven't updated the 'container' file which constructs this class, so this can't work currently.
I also think it might not be possible for the two repositories to mutually depend on each other?
| ); | ||
| } | ||
|
|
||
| // if the payload (validateResult) has a campaignId, check it matches with the template campaignId |
There was a problem hiding this comment.
Since we're blocking all updates to a routing config's campaign ID soon, it might not be worth us implementing stuff specific to handling updates which combine campaignId and templates in the payload. What do you think @nicki-nhs ?
If we are handling those cases, this doesn't seem correct. If there is a new campaignId in the payload, we can't expect the existing database entry to have a matching ID already. The expect condition should only be applied if the payload is not updating the campaignId
There was a problem hiding this comment.
I agree
we should just be fetching the routing config from the ID and using the campaign ID on that to validate against
There was a problem hiding this comment.
I don't think there's necesarily any need to fetch the routing config. A conditional update is sufficient - it's just the (current) support for patching campaign which makes things more complicated
Then again the code might be a little simpler with pre-fetching, at a perfomance cost
There was a problem hiding this comment.
@nicki-nhs since we're already coverting conditional update errors into failure codes I don't see the problem with adding 'campaign mismatch' there?
There was a problem hiding this comment.
yeah could do, what are you thinking the condition would be that we'd be able to use to differentiate it?
I think its equally valid in this file too, with the other campaign ID validation on L137+
but dont feel strongly either way
There was a problem hiding this comment.
You would need to pass through expectedCampaign into handleError, similarly to expectedLockNumber.
There would still be a need to return a similar error from the client layer, because you need to handle a patch payload where some template campaigns don't match others.
There was a problem hiding this comment.
poss a monday discussion but I think I dont understand the need to catch that specifically tho, if they dont match the routing config, its irrelevant if they match each other isnt it?
There was a problem hiding this comment.
You need select one to use as the condition, if there are multiple, you already know the update is invalid
| private readonly routingConfigRepository: RoutingConfigRepository, | ||
| private readonly clientConfigRepository: ClientConfigRepository | ||
| private readonly clientConfigRepository: ClientConfigRepository, | ||
| private readonly templateClient: TemplateClient |
There was a problem hiding this comment.
should be using TemplateRepository rather than the client
| // check all the templates have campaignIds if they don't have campaignIds, reject the request | ||
| if (templates.some((template) => !template.data?.campaignId)) { | ||
| return failure( | ||
| ErrorCase.VALIDATION_FAILED, | ||
| 'One or more templates do not have a campaign ID' | ||
| ); | ||
| } | ||
|
|
||
| // if they do check that those campaignIds are the same if not reject the request | ||
| const uniqueCampaignIds = [ | ||
| ...new Set(templates.map((t) => t.data?.campaignId)), | ||
| ]; | ||
| if (uniqueCampaignIds.length > 1) { | ||
| return failure( | ||
| ErrorCase.VALIDATION_FAILED, | ||
| 'All templates must have the same campaign ID' | ||
| ); | ||
| } |
There was a problem hiding this comment.
I'm happy to discuss this but I'm not sure we need these additional checks, given if we check if each one matches the campaign ID on the routing config, the case where its missing or they dont all match each other would be caught anyway. feels like a lot of code to add for not much benefit imo
| const expectedCampaignId = | ||
| validated.campaignId === templates[0]?.data?.campaignId | ||
| ? validated.campaignId | ||
| : templates[0]?.data?.campaignId; |
There was a problem hiding this comment.
the source of truth for the expected campaignId should be the routing config already in the database, not the templates being added. the approach should be: fetch the existing routing config first, get its campaignId then validate that the templates match it
| user, | ||
| lockNumberValidation.data | ||
| lockNumberValidation.data, | ||
| expectedCampaignId as string |
There was a problem hiding this comment.
I dont think we want this
| UpdateRoutingConfig, | ||
| } from 'nhs-notify-web-template-management-types'; | ||
| import { ClientConfigRepository } from '../../infra/client-config-repository'; | ||
| import { TemplateClient } from '@backend-api/app/template-client'; |
There was a problem hiding this comment.
needs updating to be the repository
and tests missing in here
| } else { | ||
| update.expectCampaignId(expectedCampaignId); |
There was a problem hiding this comment.
shouldnt need this, can revert this file
| expectCampaignId(expectedCampaignId: string) { | ||
| this.updateBuilder.conditions.and('campaignId', '=', expectedCampaignId); | ||
| return this; | ||
| } | ||
|
|
There was a problem hiding this comment.
can revert this, shouldnt be needed
Description
Context
Type of changes
Checklist
Sensitive Information Declaration
To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including PII (Personal Identifiable Information) / PID (Personal Identifiable Data) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter.