feat: Add includeKeywords and excludeKeywords nullable text columns to…

- "src/db/schema/channels.ts"
- "src/types/index.ts"
- "src/db/repositories/channel-repository.ts"
- "drizzle/0015_perfect_lethal_legion.sql"
- "src/__tests__/sources.test.ts"

GSD-Task: S03/T01
This commit is contained in:
jlightner 2026-04-04 05:35:13 +00:00
parent 3bfdb7b634
commit 8d133024a5
7 changed files with 1062 additions and 2 deletions

View file

@ -0,0 +1,2 @@
ALTER TABLE `channels` ADD `include_keywords` text;--> statement-breakpoint
ALTER TABLE `channels` ADD `exclude_keywords` text;

File diff suppressed because it is too large Load diff

View file

@ -106,6 +106,13 @@
"when": 1775279888856,
"tag": "0014_adorable_miek",
"breakpoints": true
},
{
"idx": 15,
"version": "6",
"when": 1775280800944,
"tag": "0015_perfect_lethal_legion",
"breakpoints": true
}
]
}

View file

@ -138,6 +138,8 @@ function makeChannel(overrides: Partial<Channel> = {}): Channel {
bannerUrl: null,
description: null,
subscriberCount: null,
includeKeywords: null,
excludeKeywords: null,
createdAt: '2024-01-01T00:00:00Z',
updatedAt: '2024-01-01T00:00:00Z',
lastCheckedAt: null,

View file

@ -9,17 +9,19 @@ import type { Channel, Platform, MonitoringMode } from '../../types/index';
/** Fields needed to create a new channel (auto-generated fields excluded). */
export type CreateChannelData = Omit<
Channel,
'id' | 'createdAt' | 'updatedAt' | 'lastCheckedAt' | 'lastCheckStatus' | 'monitoringMode' | 'bannerUrl' | 'description' | 'subscriberCount'
'id' | 'createdAt' | 'updatedAt' | 'lastCheckedAt' | 'lastCheckStatus' | 'monitoringMode' | 'bannerUrl' | 'description' | 'subscriberCount' | 'includeKeywords' | 'excludeKeywords'
> & {
monitoringMode?: Channel['monitoringMode'];
bannerUrl?: string | null;
description?: string | null;
subscriberCount?: number | null;
includeKeywords?: string | null;
excludeKeywords?: string | null;
};
/** Fields that can be updated on an existing channel. */
export type UpdateChannelData = Partial<
Pick<Channel, 'name' | 'checkInterval' | 'monitoringEnabled' | 'imageUrl' | 'formatProfileId' | 'lastCheckedAt' | 'lastCheckStatus' | 'monitoringMode' | 'bannerUrl' | 'description' | 'subscriberCount'>
Pick<Channel, 'name' | 'checkInterval' | 'monitoringEnabled' | 'imageUrl' | 'formatProfileId' | 'lastCheckedAt' | 'lastCheckStatus' | 'monitoringMode' | 'bannerUrl' | 'description' | 'subscriberCount' | 'includeKeywords' | 'excludeKeywords'>
>;
type Db = LibSQLDatabase<typeof schema>;
@ -200,5 +202,7 @@ function mapRow(row: typeof channels.$inferSelect): Channel {
updatedAt: row.updatedAt,
lastCheckedAt: row.lastCheckedAt,
lastCheckStatus: row.lastCheckStatus as Channel['lastCheckStatus'],
includeKeywords: row.includeKeywords ?? null,
excludeKeywords: row.excludeKeywords ?? null,
};
}

View file

@ -31,4 +31,6 @@ export const channels = sqliteTable('channels', {
bannerUrl: text('banner_url'),
description: text('description'),
subscriberCount: integer('subscriber_count'),
includeKeywords: text('include_keywords'), // nullable — pipe-separated patterns for auto-enqueue filtering
excludeKeywords: text('exclude_keywords'), // nullable — pipe-separated patterns for auto-enqueue filtering
});

View file

@ -77,6 +77,8 @@ export interface Channel {
bannerUrl: string | null;
description: string | null;
subscriberCount: number | null;
includeKeywords: string | null;
excludeKeywords: string | null;
createdAt: string;
updatedAt: string;
lastCheckedAt: string | null;