fix(downloads): rederive show rule download links before cleanup

Return initialized show and season rules from the backfill query so their
coverage is recomputed from download ancestry. Rule execution links only the
unwatched episodes it inspected, so the cached flag let a sibling list
cleanup delete episodes the show rule covers.
This commit is contained in:
edde746
2026-07-27 17:44:52 +02:00
parent ea7dfe6e1e
commit 841d336cb8
4 changed files with 61 additions and 7 deletions
+8 -1
View File
@@ -18,6 +18,7 @@ import '../services/credential_vault.dart';
import '../utils/app_logger.dart';
import '../utils/serial_future_queue.dart';
import '../utils/global_key_utils.dart';
import '../utils/content_utils.dart';
part 'app_database.g.dart';
@@ -1057,12 +1058,18 @@ class AppDatabase extends _$AppDatabase {
);
}
/// Returns uninitialized collection/playlist rules and every show/season
/// rule whose local ancestry-derived links must be refreshed before cleanup.
Future<List<SyncRuleItem>> getUninitializedSyncRulesForServer({
required String profileId,
required ServerId serverId,
}) {
return (select(syncRules)..where(
(t) => t.profileId.equals(profileId) & t.serverId.equals(serverId) & t.downloadLinksInitialized.equals(false),
(t) =>
t.profileId.equals(profileId) &
t.serverId.equals(serverId) &
(t.downloadLinksInitialized.equals(false) |
t.targetType.isIn(const [ContentTypes.show, ContentTypes.season])),
))
.get();
}
+3 -3
View File
@@ -3568,9 +3568,9 @@ class SyncRuleItem extends DataClass implements Insertable<SyncRuleItem> {
final String downloadFilter;
final bool includeSpecials;
/// Whether every currently-owned candidate has been associated in
/// [SyncRuleDownloads]. Existing rules start false and are backfilled before
/// destructive cleanup.
/// Gates collection/playlist backfill into [SyncRuleDownloads] before
/// destructive cleanup. Show/season coverage is re-derived from
/// [DownloadedMedia] ancestry at cleanup time regardless of this value.
final bool downloadLinksInitialized;
const SyncRuleItem({
required this.id,
+3 -3
View File
@@ -106,9 +106,9 @@ class SyncRules extends Table {
TextColumn get downloadFilter => text().withDefault(const Constant('unwatched'))();
BoolColumn get includeSpecials => boolean().withDefault(const Constant(true))();
/// Whether every currently-owned candidate has been associated in
/// [SyncRuleDownloads]. Existing rules start false and are backfilled before
/// destructive cleanup.
/// Gates collection/playlist backfill into [SyncRuleDownloads] before
/// destructive cleanup. Show/season coverage is re-derived from
/// [DownloadedMedia] ancestry at cleanup time regardless of this value.
BoolColumn get downloadLinksInitialized => boolean().withDefault(const Constant(false))();
}