Skip to content

Commit 7cf9a25

Browse files
committed
fix: Fetch the wrong element to know if the screening is needed
1 parent 7d0b6f5 commit 7cf9a25

File tree

5 files changed

+63
-10
lines changed

5 files changed

+63
-10
lines changed

mocks/continuous_screening_repository.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,10 @@ func (m *ContinuousScreeningRepository) GetContinuousScreeningByObjectId(
101101
objectId string,
102102
objectType string,
103103
orgId uuid.UUID,
104+
status *models.ScreeningStatus,
105+
inCase bool,
104106
) (*models.ContinuousScreeningWithMatches, error) {
105-
args := m.Called(ctx, exec, objectId, objectType, orgId)
107+
args := m.Called(ctx, exec, objectId, objectType, orgId, status, inCase)
106108
if args.Get(0) == nil {
107109
return nil, args.Error(1)
108110
}

repositories/continuous_screening_repository.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,8 @@ func (repo *MarbleDbRepository) GetContinuousScreeningByObjectId(
405405
objectId string,
406406
objectType string,
407407
orgId uuid.UUID,
408+
status *models.ScreeningStatus,
409+
inCase bool,
408410
) (*models.ContinuousScreeningWithMatches, error) {
409411
if err := validateMarbleDbExecutor(exec); err != nil {
410412
return nil, err
@@ -414,11 +416,16 @@ func (repo *MarbleDbRepository) GetContinuousScreeningByObjectId(
414416
Where(squirrel.Eq{"cs.org_id": orgId}).
415417
Where(squirrel.Eq{"cs.object_type": objectType}).
416418
Where(squirrel.Eq{"cs.object_id": objectId}).
417-
Where(squirrel.Eq{"cs.status": models.ScreeningStatusInReview.String()}).
418-
Where(squirrel.NotEq{"cs.case_id": nil}).
419419
OrderBy("cs.created_at DESC").
420420
Limit(1)
421421

422+
if status != nil {
423+
query = query.Where(squirrel.Eq{"cs.status": status.String()})
424+
}
425+
if inCase {
426+
query = query.Where("cs.case_id IS NOT NULL")
427+
}
428+
422429
return SqlToOptionalModel(ctx, exec, query, dbmodels.AdaptContinuousScreeningWithMatches)
423430
}
424431

repositories/dbmodels/db_continuous_screening.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ func AdaptContinuousScreeningMatch(dto DBContinuousScreeningMatches) (models.Con
7474
Status: models.ScreeningMatchStatusFrom(dto.Status),
7575
Payload: dto.Payload,
7676
ReviewedBy: dto.ReviewedBy,
77+
CreatedAt: dto.CreatedAt,
78+
UpdatedAt: dto.UpdatedAt,
7779
}, nil
7880
}
7981

usecases/continuous_screening/worker.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ type repository interface {
3535
objectId string,
3636
objectType string,
3737
orgId uuid.UUID,
38+
status *models.ScreeningStatus,
39+
inCase bool,
3840
) (*models.ContinuousScreeningWithMatches, error)
3941
}
4042

@@ -163,6 +165,8 @@ func (w *DoScreeningWorker) Work(ctx context.Context, job *river.Job[models.Cont
163165
monitoredObject.ObjectId,
164166
job.Args.ObjectType,
165167
config.OrgId,
168+
nil,
169+
false,
166170
)
167171
if err != nil {
168172
return err
@@ -201,8 +205,27 @@ func (w *DoScreeningWorker) Work(ctx context.Context, job *river.Job[models.Cont
201205

202206
skipCaseCreation := false
203207
// Only in case of Object updated by the user, check if the screening result is the same as the existing one (if exists)
204-
if job.Args.TriggerType == models.ContinuousScreeningTriggerTypeObjectUpdated && existingScreeningWithMatches != nil {
205-
skipCaseCreation = areScreeningMatchesEqual(*existingScreeningWithMatches, screeningWithMatches)
208+
if job.Args.TriggerType == models.ContinuousScreeningTriggerTypeObjectUpdated {
209+
// This time, we fetch the latest screening result in review and attached to a case to determine if we can skip case creation
210+
// In case of same matches, we don't need to create a new case for the same result
211+
lastScreeningWithMatchesInReviewAndInCase, err := w.repo.GetContinuousScreeningByObjectId(
212+
ctx,
213+
exec,
214+
monitoredObject.ObjectId,
215+
job.Args.ObjectType,
216+
config.OrgId,
217+
utils.Ptr(models.ScreeningStatusInReview),
218+
true,
219+
)
220+
if err != nil {
221+
return err
222+
}
223+
if lastScreeningWithMatchesInReviewAndInCase != nil {
224+
skipCaseCreation = areScreeningMatchesEqual(
225+
*lastScreeningWithMatchesInReviewAndInCase,
226+
screeningWithMatches,
227+
)
228+
}
206229
}
207230

208231
return w.transactionFactory.Transaction(ctx, func(tx repositories.Transaction) error {

usecases/continuous_screening/worker_test.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,13 @@ func (suite *DoScreeningWorkerTestSuite) TestWork_ObjectUpdated_ScreeningResultU
167167
suite.usecase.On("DoScreening", suite.ctx, mock.Anything, ingestedObject, mapping, config,
168168
"transactions", "test-object-id").Return(screeningWithMatches, nil)
169169
suite.repository.On("GetContinuousScreeningByObjectId", suite.ctx, mock.Anything,
170-
suite.objectId, suite.objectType, suite.orgId).Return(&existingContinuousScreening, nil)
170+
suite.objectId, suite.objectType, suite.orgId, mock.MatchedBy(func(status *models.ScreeningStatus) bool {
171+
return status == nil
172+
}), false).Return(&existingContinuousScreening, nil)
173+
suite.repository.On("GetContinuousScreeningByObjectId", suite.ctx, mock.Anything,
174+
suite.objectId, suite.objectType, suite.orgId, mock.MatchedBy(func(status *models.ScreeningStatus) bool {
175+
return status != nil && *status == models.ScreeningStatusInReview
176+
}), true).Return(&existingContinuousScreening, nil)
171177
suite.repository.On("InsertContinuousScreening", suite.ctx, mock.Anything,
172178
screeningWithMatches, config, suite.objectType, suite.objectId, ingestedObjectInternalId,
173179
models.ContinuousScreeningTriggerTypeObjectUpdated).Return(continuousScreeningWithMatches, nil)
@@ -281,7 +287,13 @@ func (suite *DoScreeningWorkerTestSuite) TestWork_ObjectUpdated_ScreeningResultC
281287
suite.usecase.On("DoScreening", suite.ctx, mock.Anything, ingestedObject, mapping, config,
282288
"transactions", "test-object-id").Return(screeningWithMatches, nil)
283289
suite.repository.On("GetContinuousScreeningByObjectId", suite.ctx, mock.Anything,
284-
suite.objectId, suite.objectType, suite.orgId).Return(&existingContinuousScreening, nil)
290+
suite.objectId, suite.objectType, suite.orgId, mock.MatchedBy(func(status *models.ScreeningStatus) bool {
291+
return status == nil
292+
}), false).Return(&existingContinuousScreening, nil)
293+
suite.repository.On("GetContinuousScreeningByObjectId", suite.ctx, mock.Anything,
294+
suite.objectId, suite.objectType, suite.orgId, mock.MatchedBy(func(status *models.ScreeningStatus) bool {
295+
return status != nil && *status == models.ScreeningStatusInReview
296+
}), true).Return((*models.ContinuousScreeningWithMatches)(nil), nil)
285297
suite.repository.On("InsertContinuousScreening", suite.ctx, mock.Anything,
286298
screeningWithMatches, config, suite.objectType, suite.objectId, ingestedObjectInternalId,
287299
models.ContinuousScreeningTriggerTypeObjectUpdated).Return(continuousScreeningWithMatches, nil)
@@ -369,7 +381,9 @@ func (suite *DoScreeningWorkerTestSuite) TestWork_IngestedObjectBeforeLatestScre
369381
ingestedObject, ingestedObjectInternalId, nil)
370382
// Existing screening is more recent than ingested object
371383
suite.repository.On("GetContinuousScreeningByObjectId", suite.ctx, mock.Anything,
372-
suite.objectId, suite.objectType, suite.orgId).Return(&existingContinuousScreening, nil)
384+
suite.objectId, suite.objectType, suite.orgId, mock.MatchedBy(func(status *models.ScreeningStatus) bool {
385+
return status == nil
386+
}), false).Return(&existingContinuousScreening, nil)
373387

374388
// Execute
375389
worker := suite.makeWorker()
@@ -381,6 +395,8 @@ func (suite *DoScreeningWorkerTestSuite) TestWork_IngestedObjectBeforeLatestScre
381395
suite.usecase.AssertNotCalled(suite.T(), "DoScreening")
382396
// Verify that InsertContinuousScreening is NOT called
383397
suite.repository.AssertNotCalled(suite.T(), "InsertContinuousScreening")
398+
// Verify that GetContinuousScreeningByObjectId is NOT called a second time (with ScreeningStatusInReview filter)
399+
suite.usecase.AssertNotCalled(suite.T(), "HandleCaseCreation")
384400
suite.AssertExpectations()
385401
}
386402

@@ -468,7 +484,9 @@ func (suite *DoScreeningWorkerTestSuite) TestWork_ObjectAdded_CallCaseCreation()
468484
ingestedObject, ingestedObjectInternalId, nil)
469485
// For ObjectAdded trigger, there should be no existing screening
470486
suite.repository.On("GetContinuousScreeningByObjectId", suite.ctx, mock.Anything,
471-
suite.objectId, suite.objectType, suite.orgId).Return(
487+
suite.objectId, suite.objectType, suite.orgId, mock.MatchedBy(func(status *models.ScreeningStatus) bool {
488+
return status == nil
489+
}), false).Return(
472490
(*models.ContinuousScreeningWithMatches)(nil), nil)
473491
suite.usecase.On("DoScreening", suite.ctx, mock.Anything, ingestedObject, mapping, config,
474492
"transactions", "test-object-id").Return(screeningWithMatches, nil)
@@ -484,7 +502,8 @@ func (suite *DoScreeningWorkerTestSuite) TestWork_ObjectAdded_CallCaseCreation()
484502

485503
// Assert
486504
suite.NoError(err)
487-
suite.AssertExpectations()
505+
// For ObjectAdded trigger, the second GetContinuousScreeningByObjectId call is NOT made
506+
suite.usecase.AssertExpectations(suite.T())
488507
}
489508

490509
// Tests for CheckIfObjectsNeedScreeningWorker

0 commit comments

Comments
 (0)