fix: properly recalculate channel duration in RegenerateChannelLineupCommand

This commit is contained in:
Christian Benincasa
2026-03-04 07:21:09 -05:00
parent cbde1d477a
commit 6035284ac4
3 changed files with 15 additions and 21 deletions

View File

@@ -1,6 +1,7 @@
import { isNonEmptyString, seq } from '@tunarr/shared/util';
import { ChannelProgram } from '@tunarr/types';
import { inject, injectable, interfaces } from 'inversify';
import { sum } from 'lodash-es';
import { match, P } from 'ts-pattern';
import { LineupItem } from '../db/derived_types/Lineup.ts';
import { IChannelDB } from '../db/interfaces/IChannelDB.ts';
@@ -57,6 +58,10 @@ export class RegenerateChannelLineupCommand {
// Regenerate schedule at the new start time.
await this.channelDB.replaceChannelPrograms(channelId, programIds);
await this.channelDB.saveLineup(channelId, { items: lineupItems });
await this.channelDB.updateChannelDuration(
channelId,
sum(lineupItems.map((item) => item.durationMs)),
);
} else if (channelAndLineup.lineup.schedule.type === 'random') {
const { result } = await this.workerPoolProvider().queueTask({
type: 'schedule-slots',
@@ -82,6 +87,10 @@ export class RegenerateChannelLineupCommand {
// Regenerate schedule at the new start time.
await this.channelDB.replaceChannelPrograms(channelId, programIds);
await this.channelDB.saveLineup(channelId, { items: lineupItems });
await this.channelDB.updateChannelDuration(
channelId,
sum(lineupItems.map((item) => item.durationMs)),
);
}
}

View File

@@ -34,15 +34,7 @@ import {
} from '@tunarr/types';
import { UpdateChannelProgrammingRequest } from '@tunarr/types/api';
import { ContentProgramType } from '@tunarr/types/schemas';
import {
and,
asc,
count,
countDistinct,
sum as dbSum,
eq,
isNotNull,
} from 'drizzle-orm';
import { and, asc, count, countDistinct, eq, isNotNull } from 'drizzle-orm';
import { inject, injectable, interfaces } from 'inversify';
import { Kysely } from 'kysely';
import { jsonArrayFrom } from 'kysely/helpers/sqlite';
@@ -1165,18 +1157,6 @@ export class ChannelDB implements IChannelDB {
.insert(ChannelPrograms)
.values(c.map((id) => ({ channelUuid: channelId, programUuid: id })));
}
// This can probably be done in a single query.
const sumResult = await tx
.select({ duration: dbSum(Program.duration).mapWith(Number) })
.from(ChannelPrograms)
.where(eq(ChannelPrograms.channelUuid, channelId))
.innerJoin(Program, eq(Program.uuid, ChannelPrograms.programUuid));
await tx
.update(Channel)
.set({
duration: sum(sumResult.map((r) => r.duration)),
})
.where(eq(Channel.uuid, channelId));
});
}

View File

@@ -112,6 +112,11 @@ export interface IChannelDB {
limit?: number,
): Promise<CondensedChannelProgramming | null>;
/**
* Replace associations between channel and programs completely
* @param channelId
* @param programIds
*/
replaceChannelPrograms(
channelId: string,
programIds: string[],