fix: prevent specific cases of duplicate program gropuing external id errors (#1651)

This commit is contained in:
Christian Benincasa
2026-02-17 14:31:25 -05:00
committed by GitHub
parent 7452cecdf0
commit eea1b4995a
2 changed files with 17 additions and 40 deletions

View File

@@ -2249,15 +2249,10 @@ export class ProgramDB implements IProgramDB {
const insertedExternalIds: ProgramGroupingExternalIdOrm[] = [];
if (externalIds.length > 0) {
insertedExternalIds.push(
...(await tx
.insert(ProgramGroupingExternalId)
.values(
externalIds.map((eid) =>
this.singleOrMultiProgramGroupingExternalIdToDao(eid),
),
)
.returning()
.execute()),
...(await this.upsertProgramGroupingExternalIdsChunkOrm(
externalIds,
tx,
)),
);
}
@@ -2313,37 +2308,6 @@ export class ProgramDB implements IProgramDB {
};
}
private singleOrMultiProgramGroupingExternalIdToDao(
externalId: NewSingleOrMultiProgramGroupingExternalId,
): NewProgramGroupingExternalId {
switch (externalId.type) {
case 'single':
return {
externalKey: externalId.externalKey,
groupUuid: externalId.groupUuid,
sourceType: externalId.sourceType,
uuid: externalId.uuid,
createdAt: externalId.createdAt,
externalFilePath: externalId.externalFilePath,
libraryId: externalId.libraryId,
updatedAt: externalId.updatedAt,
};
case 'multi':
return {
externalKey: externalId.externalKey,
groupUuid: externalId.groupUuid,
sourceType: externalId.sourceType,
uuid: externalId.uuid,
createdAt: externalId.createdAt,
externalFilePath: externalId.externalFilePath,
externalSourceId: externalId.externalSourceId,
libraryId: externalId.libraryId,
mediaSourceId: externalId.mediaSourceId,
updatedAt: externalId.updatedAt,
};
}
}
private async updateProgramGrouping(
{ programGrouping: incoming }: NewProgramGroupingWithRelations,
existing: ProgramGroupingOrmWithRelations,

View File

@@ -448,8 +448,15 @@ export class ProgramGroupingMinter {
identifiers: Nilable<Identifier[]>,
now: number = +dayjs(),
) {
const seen = new Set<string>();
return seq.collect(identifiers, (id) => {
if (isNonEmptyString(id.id) && isValidSingleExternalIdType(id.type)) {
// Deduplicate single-type external IDs by sourceType to avoid
// unique constraint violations on (group_uuid, source_type).
if (seen.has(id.type)) {
return;
}
seen.add(id.type);
return {
type: 'single',
externalKey: id.id,
@@ -460,6 +467,12 @@ export class ProgramGroupingMinter {
updatedAt: now,
} satisfies NewSingleOrMultiProgramGroupingExternalId;
} else if (isValidMultiExternalIdType(id.type)) {
// Deduplicate multi-type external IDs by sourceType|mediaSourceId.
const key = `${id.type}|${mediaSource.uuid}`;
if (seen.has(key)) {
return;
}
seen.add(key);
return {
type: 'multi',
externalKey: id.id,