Batch-load and validate campaign sources before merging
MergeByCampaignID joined access_review_sources directly from coredata to resolve live sources, so unrecognized or out-of-scope IDs were silently dropped instead of erroring, and in the worst case (every ID invalid) the NOT MATCHED BY SOURCE clause deleted every existing campaign source. The syncCampaignSources ErrResourceNotFound check was therefore unreachable dead code. Add AccessReviewSources.LoadByIDs, matching the existing scoped LoadByIDs pattern (id = ANY(@ids) plus a resolved-count check), and have CreateCampaign, AddCampaignSource, and syncCampaignSources resolve and validate sources up front. MergeByCampaignID now takes the already-loaded sources and builds its desired-state CTE from an unnest() of their values instead of joining access_review_sources, keeping the merge inside the campaign-source entity boundary. Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
@@ -59,16 +59,16 @@ func (s *Service) CreateCampaign(
|
||||
return fmt.Errorf("cannot insert access review campaign: %w", err)
|
||||
}
|
||||
|
||||
for _, sourceID := range req.AccessReviewSourceIDs {
|
||||
source := &coredata.AccessReviewSource{}
|
||||
if err := source.LoadByID(ctx, conn, scope, sourceID); err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return coredata.ErrResourceNotFound
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot load access source: %w", err)
|
||||
var sources coredata.AccessReviewSources
|
||||
if err := sources.LoadByIDs(ctx, conn, scope, req.AccessReviewSourceIDs); err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return coredata.ErrResourceNotFound
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot load access sources: %w", err)
|
||||
}
|
||||
|
||||
for _, source := range sources {
|
||||
if err := s.upsertCampaignSource(ctx, conn, scope, campaign.ID, source); err != nil {
|
||||
return fmt.Errorf("cannot snapshot scope source: %w", err)
|
||||
}
|
||||
@@ -308,12 +308,17 @@ func (s *Service) syncCampaignSources(
|
||||
campaign *coredata.AccessReviewCampaign,
|
||||
sourceIDs []gid.GID,
|
||||
) error {
|
||||
var campaignSources coredata.AccessReviewCampaignSources
|
||||
if err := campaignSources.MergeByCampaignID(ctx, conn, scope, campaign.ID, sourceIDs); err != nil {
|
||||
var sources coredata.AccessReviewSources
|
||||
if err := sources.LoadByIDs(ctx, conn, scope, sourceIDs); err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return coredata.ErrResourceNotFound
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot load access sources: %w", err)
|
||||
}
|
||||
|
||||
var campaignSources coredata.AccessReviewCampaignSources
|
||||
if err := campaignSources.MergeByCampaignID(ctx, conn, scope, campaign.ID, sources); err != nil {
|
||||
return fmt.Errorf("cannot merge campaign sources: %w", err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user