-
Notifications
You must be signed in to change notification settings - Fork 0
feat(data-access): add scopeType and scopeId to Opportunity model #1576
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
base: main
Are you sure you want to change the base?
Changes from all commits
eb7dac2
fa9dcea
f9ddca7
7d48e2a
6136d91
aba6037
7eeb083
df0394b
6b0e10a
577b6d3
57d91d8
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 |
|---|---|---|
|
|
@@ -12,7 +12,9 @@ | |
|
|
||
| /* c8 ignore start */ | ||
|
|
||
| import { isIsoDate, isNonEmptyObject, isValidUrl } from '@adobe/spacecat-shared-utils'; | ||
| import { | ||
| isIsoDate, isNonEmptyObject, isValidUrl, isValidUUID, | ||
| } from '@adobe/spacecat-shared-utils'; | ||
|
|
||
| import SchemaBuilder from '../base/schema.builder.js'; | ||
| import Opportunity from './opportunity.model.js'; | ||
|
|
@@ -64,6 +66,15 @@ const schema = new SchemaBuilder(Opportunity, OpportunityCollection) | |
| .addAttribute('lastAuditedAt', { | ||
| type: 'string', | ||
| validate: (value) => !value || isIsoDate(value), | ||
| }); | ||
| }) | ||
| .addAttribute('scopeType', { | ||
|
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. Important - no co-presence validation, and strict enum may reject existing NULL rows. Two issues at No co-presence enforcement. Both attributes are independently optional. A record can be saved with Strict enum may break hydration of legacy rows. |
||
| type: 'string', | ||
| validate: (value) => !value || Object.values(Opportunity.SCOPE_TYPES).includes(value), | ||
| }) | ||
| .addAttribute('scopeId', { | ||
|
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. Critical - missing composite index AND no format constraint on Two issues at this attribute declaration: Missing index for No format constraint on import { isValidUUID } from '@adobe/spacecat-shared-utils';
.addAttribute('scopeId', {
type: 'string',
validate: (value) => !value || isValidUUID(value),
}) |
||
| type: 'string', | ||
| validate: (value) => !value || isValidUUID(value), | ||
| }) | ||
| .addIndex({ composite: ['scopeId'] }, { composite: ['scopeType'] }); | ||
|
|
||
|
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. Co-presence gap: there is no cross-field validator enforcing that |
||
| export default schema.build(); | ||
|
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. Hot partition: .addIndex({ composite: ['scopeId'] }, { composite: ['scopeType'] })Fix while no production data exists yet. |
||
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.
This
create()override guards a single write entry point. Three paths inherited fromBaseCollectionstill bypass both this guard and the newOpportunity.save()override:updateByKeys(keys, { scopeId: '<other-brand-uuid>' })- patches viaentity.patch(keys).set(...).go()without model instantiation. Can also re-attribute an existing opportunity to a different brand'sscopeIdwithout touchingscopeType.createMany([...])- callsentity.put(item).params()per item, does not delegate tothis.create().saveMany(items)/_saveMany(items)- callsentity.put(updates).go()directly.Preferred fix: mark
scopeTypeandscopeIdasreadOnly: trueinopportunity.schema.js. Post-create mutation becomes impossible by construction, co-presence only needs to live increate(), and all three bulk paths are closed at once - without adding more overrides.