@aion2hub/shared-schemas 1.1.16 → 1.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,737 +0,0 @@
1
- "use strict";
2
- /**
3
- * Content Management Database Schema
4
- * This file contains ONLY content-related tables for the aion2hub_content database
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.youtubeFilterRulesRelations = exports.filterExecutionLogsRelations = exports.youtubeChannelFilterAssignmentsRelations = exports.rssFeedFilterAssignmentsRelations = exports.filterScoringConfigRelations = exports.filterRuleConditionsRelations = exports.filterRulesRelations = exports.filterKeywordsRelations = exports.filterProfilesRelations = exports.youtubeChannelSubscriptionsRelations = exports.youtubeChannelExtensionsRelations = exports.youtubeVideosRelations = exports.youtubeSourceConfigsRelations = exports.rssArticlesRelations = exports.rssFeedsRelations = exports.contentTranslationsRelations = exports.aiModelsRelations = exports.youtubeFilterRules = exports.youtubeChannelFilterAssignments = exports.youtubeChannelSubscriptions = exports.youtubeChannelExtensions = exports.youtubeQuotaUsage = exports.youtubeSearchQueries = exports.youtubeVideos = exports.youtubeSourceConfigs = exports.rssArticles = exports.rssFeeds = exports.newsArticles = exports.contentTranslations = exports.aiModels = exports.contentFilterKeywords = exports.classificationFilters = exports.filterExecutionLogs = exports.rssFeedFilterAssignments = exports.filterScoringConfig = exports.filterRuleConditions = exports.filterRules = exports.filterKeywords = exports.filterProfiles = exports.filterScoringMethodEnum = exports.filterConditionOperatorEnum = exports.filterOperatorEnum = exports.filterRuleTypeEnum = exports.filterContextScopeEnum = exports.filterMatchTypeEnum = exports.sourceTypeEnum = exports.scrapingTypeEnum = exports.jobStatusEnum = exports.contentStatusEnum = exports.translationStatusEnum = void 0;
8
- const pg_core_1 = require("drizzle-orm/pg-core");
9
- const drizzle_orm_1 = require("drizzle-orm");
10
- const crypto_1 = require("crypto");
11
- // =============================================================================
12
- // ENUMS
13
- // =============================================================================
14
- exports.translationStatusEnum = (0, pg_core_1.pgEnum)('TranslationStatus', [
15
- 'PENDING',
16
- 'PROCESSING',
17
- 'COMPLETED',
18
- 'FAILED',
19
- 'REVIEWED',
20
- 'REJECTED'
21
- ]);
22
- exports.contentStatusEnum = (0, pg_core_1.pgEnum)('ContentStatus', [
23
- 'PENDING',
24
- 'PROCESSING',
25
- 'COMPLETED',
26
- 'PUBLISHED',
27
- 'FAILED',
28
- 'REJECTED'
29
- ]);
30
- exports.jobStatusEnum = (0, pg_core_1.pgEnum)('JobStatus', [
31
- 'PENDING',
32
- 'RUNNING',
33
- 'COMPLETED',
34
- 'FAILED',
35
- 'CANCELLED'
36
- ]);
37
- exports.scrapingTypeEnum = (0, pg_core_1.pgEnum)('ScrapingType', [
38
- 'NEWS',
39
- 'RSS',
40
- 'YOUTUBE',
41
- 'MANUAL',
42
- 'BULK',
43
- 'API'
44
- ]);
45
- exports.sourceTypeEnum = (0, pg_core_1.pgEnum)('SourceType', [
46
- 'RSS_FEED',
47
- 'NEWS_WEBSITE',
48
- 'YOUTUBE_CHANNEL',
49
- 'MANUAL_INPUT'
50
- ]);
51
- exports.filterMatchTypeEnum = (0, pg_core_1.pgEnum)('FilterMatchType', [
52
- 'exact',
53
- 'partial',
54
- 'regex',
55
- 'fuzzy',
56
- 'stemmed'
57
- ]);
58
- exports.filterContextScopeEnum = (0, pg_core_1.pgEnum)('FilterContextScope', [
59
- 'title',
60
- 'content',
61
- 'description',
62
- 'any',
63
- 'url'
64
- ]);
65
- exports.filterRuleTypeEnum = (0, pg_core_1.pgEnum)('FilterRuleType', [
66
- 'keyword',
67
- 'regex',
68
- 'domain',
69
- 'category',
70
- 'language',
71
- 'date_range',
72
- 'content_length',
73
- 'quality_score'
74
- ]);
75
- exports.filterOperatorEnum = (0, pg_core_1.pgEnum)('FilterOperator', [
76
- 'AND',
77
- 'OR',
78
- 'NOT'
79
- ]);
80
- exports.filterConditionOperatorEnum = (0, pg_core_1.pgEnum)('FilterConditionOperator', [
81
- 'eq',
82
- 'gte',
83
- 'lte',
84
- 'gt',
85
- 'lt',
86
- 'in',
87
- 'not_in',
88
- 'contains',
89
- 'not_contains'
90
- ]);
91
- exports.filterScoringMethodEnum = (0, pg_core_1.pgEnum)('FilterScoringMethod', [
92
- 'weighted_sum',
93
- 'max_priority',
94
- 'category_bonus',
95
- 'exponential',
96
- 'logarithmic'
97
- ]);
98
- // =============================================================================
99
- // CONTENT MANAGEMENT SCHEMAS - AION2HUB_CONTENT DATABASE ONLY
100
- // =============================================================================
101
- // =============================================================================
102
- // UNIVERSAL CONTENT FILTERING SYSTEM
103
- // =============================================================================
104
- // Filter Profiles - Main configuration for content filtering
105
- exports.filterProfiles = (0, pg_core_1.pgTable)('filter_profiles', {
106
- id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
107
- name: (0, pg_core_1.text)('name').notNull().unique(),
108
- description: (0, pg_core_1.text)('description'),
109
- domain: (0, pg_core_1.text)('domain'), // e.g., 'gaming', 'tech', 'sports', 'general'
110
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
111
- // YouTube support
112
- supportsYoutube: (0, pg_core_1.boolean)('supports_youtube').notNull().default(false),
113
- youtubeSpecificRules: (0, pg_core_1.jsonb)('youtube_specific_rules'), // Additional YouTube-specific configuration
114
- createdBy: (0, pg_core_1.text)('created_by'),
115
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
116
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
117
- });
118
- // Filter Keywords - Keywords for content classification
119
- exports.filterKeywords = (0, pg_core_1.pgTable)('filter_keywords', {
120
- id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
121
- profileId: (0, pg_core_1.uuid)('profile_id').notNull().references(() => exports.filterProfiles.id, { onDelete: 'cascade' }),
122
- keyword: (0, pg_core_1.text)('keyword').notNull(),
123
- category: (0, pg_core_1.text)('category').notNull(),
124
- weight: (0, pg_core_1.decimal)('weight', { precision: 5, scale: 2 }).notNull().default('1.0'),
125
- matchType: (0, exports.filterMatchTypeEnum)('match_type').notNull().default('exact'),
126
- contextScope: (0, exports.filterContextScopeEnum)('context_scope').notNull().default('any'),
127
- language: (0, pg_core_1.text)('language').default('any'),
128
- isNegative: (0, pg_core_1.boolean)('is_negative').notNull().default(false),
129
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
130
- // YouTube-specific filtering options
131
- youtubeChannelId: (0, pg_core_1.text)('youtube_channel_id'), // Apply only to specific YouTube channel
132
- youtubeCategory: (0, pg_core_1.text)('youtube_category'), // YouTube category filter
133
- applyToTags: (0, pg_core_1.boolean)('apply_to_tags').notNull().default(true), // Apply to video tags
134
- applyToTranscript: (0, pg_core_1.boolean)('apply_to_transcript').notNull().default(false), // Apply to video transcript
135
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
136
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
137
- }, (table) => ({
138
- uniqueKeywordPerProfile: (0, pg_core_1.unique)().on(table.profileId, table.keyword, table.category)
139
- }));
140
- // Filter Rules - Advanced filtering rules
141
- exports.filterRules = (0, pg_core_1.pgTable)('filter_rules', {
142
- id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
143
- profileId: (0, pg_core_1.uuid)('profile_id').notNull().references(() => exports.filterProfiles.id, { onDelete: 'cascade' }),
144
- ruleName: (0, pg_core_1.text)('rule_name').notNull(),
145
- ruleType: (0, exports.filterRuleTypeEnum)('rule_type').notNull(),
146
- operator: (0, exports.filterOperatorEnum)('operator').notNull().default('AND'),
147
- priority: (0, pg_core_1.integer)('priority').notNull().default(1),
148
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
149
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
150
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
151
- });
152
- // Filter Rule Conditions - Conditions for filter rules
153
- exports.filterRuleConditions = (0, pg_core_1.pgTable)('filter_rule_conditions', {
154
- id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
155
- ruleId: (0, pg_core_1.uuid)('rule_id').notNull().references(() => exports.filterRules.id, { onDelete: 'cascade' }),
156
- conditionType: (0, pg_core_1.text)('condition_type').notNull(),
157
- targetCategory: (0, pg_core_1.text)('target_category'),
158
- targetValue: (0, pg_core_1.jsonb)('target_value'),
159
- operator: (0, exports.filterConditionOperatorEnum)('operator').notNull().default('gte'),
160
- thresholdValue: (0, pg_core_1.decimal)('threshold_value', { precision: 10, scale: 2 }),
161
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
162
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
163
- });
164
- // Filter Scoring Configuration
165
- exports.filterScoringConfig = (0, pg_core_1.pgTable)('filter_scoring_config', {
166
- id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
167
- profileId: (0, pg_core_1.uuid)('profile_id').notNull().references(() => exports.filterProfiles.id, { onDelete: 'cascade' }),
168
- scoringMethod: (0, exports.filterScoringMethodEnum)('scoring_method').notNull().default('weighted_sum'),
169
- baseScore: (0, pg_core_1.decimal)('base_score', { precision: 10, scale: 2 }).notNull().default('0.0'),
170
- categoryMultipliers: (0, pg_core_1.jsonb)('category_multipliers'),
171
- contextBonuses: (0, pg_core_1.jsonb)('context_bonuses'),
172
- minimumApprovalScore: (0, pg_core_1.decimal)('minimum_approval_score', { precision: 10, scale: 2 }).notNull().default('1.0'),
173
- maximumPossibleScore: (0, pg_core_1.decimal)('maximum_possible_score', { precision: 10, scale: 2 }).notNull().default('100.0'),
174
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
175
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
176
- });
177
- // RSS Feed Filter Assignments - Critical missing table!
178
- exports.rssFeedFilterAssignments = (0, pg_core_1.pgTable)('rss_feed_filter_assignments', {
179
- id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
180
- rssFeedId: (0, pg_core_1.text)('rss_feed_id').notNull().references(() => exports.rssFeeds.id, { onDelete: 'cascade' }),
181
- profileId: (0, pg_core_1.uuid)('profile_id').notNull().references(() => exports.filterProfiles.id, { onDelete: 'cascade' }),
182
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
183
- assignedAt: (0, pg_core_1.timestamp)('assigned_at').notNull().defaultNow(),
184
- assignedBy: (0, pg_core_1.text)('assigned_by'),
185
- }, (table) => ({
186
- uniqueAssignment: (0, pg_core_1.unique)().on(table.rssFeedId, table.profileId)
187
- }));
188
- // Filter Execution Logs
189
- exports.filterExecutionLogs = (0, pg_core_1.pgTable)('filter_execution_logs', {
190
- id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
191
- profileId: (0, pg_core_1.uuid)('profile_id').notNull().references(() => exports.filterProfiles.id),
192
- contentId: (0, pg_core_1.text)('content_id'),
193
- contentTitle: (0, pg_core_1.text)('content_title'),
194
- contentUrl: (0, pg_core_1.text)('content_url'),
195
- executionTimestamp: (0, pg_core_1.timestamp)('execution_timestamp').notNull().defaultNow(),
196
- matchedKeywords: (0, pg_core_1.jsonb)('matched_keywords'),
197
- appliedRules: (0, pg_core_1.jsonb)('applied_rules'),
198
- finalScore: (0, pg_core_1.decimal)('final_score', { precision: 10, scale: 2 }),
199
- approvalDecision: (0, pg_core_1.boolean)('approval_decision'),
200
- approvalReason: (0, pg_core_1.text)('approval_reason'),
201
- executionTimeMs: (0, pg_core_1.integer)('execution_time_ms'),
202
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
203
- });
204
- // Classification Filters
205
- exports.classificationFilters = (0, pg_core_1.pgTable)('classification_filters', {
206
- id: (0, pg_core_1.text)('id').primaryKey(), // Unique filter identifier (e.g., 'aion2-filter')
207
- name: (0, pg_core_1.text)('name').notNull(), // Human-readable filter name
208
- description: (0, pg_core_1.text)('description').notNull(), // Description of what this filter matches
209
- version: (0, pg_core_1.text)('version').notNull().default('1.0.0'), // Filter version for tracking changes
210
- // Filter configuration (stored as JSON)
211
- keywords: (0, pg_core_1.jsonb)('keywords').notNull(), // FilterKeywords object: {primary: [], secondary: [], contextual: [], exclusions: []}
212
- aiPrompt: (0, pg_core_1.text)('ai_prompt'), // Custom AI prompt for this filter
213
- aiModel: (0, pg_core_1.text)('ai_model'), // Preferred AI model for this filter
214
- // Filter behavior settings
215
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
216
- priority: (0, pg_core_1.integer)('priority').notNull().default(1), // Higher priority filters are checked first
217
- strictMode: (0, pg_core_1.boolean)('strict_mode').notNull().default(false), // Require all primary keywords vs any
218
- confidenceThreshold: (0, pg_core_1.decimal)('confidence_threshold', { precision: 4, scale: 3 }).default('0.7'), // Minimum confidence for AI classification
219
- // Statistics
220
- totalMatches: (0, pg_core_1.integer)('total_matches').notNull().default(0),
221
- successfulMatches: (0, pg_core_1.integer)('successful_matches').notNull().default(0),
222
- lastUsed: (0, pg_core_1.timestamp)('last_used'),
223
- // Metadata
224
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
225
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
226
- createdBy: (0, pg_core_1.text)('created_by') // Optional: user who created the filter
227
- });
228
- // Legacy content filter keywords table (for backward compatibility)
229
- exports.contentFilterKeywords = (0, pg_core_1.pgTable)('content_filter_keywords', {
230
- id: (0, pg_core_1.integer)('id').primaryKey().generatedAlwaysAsIdentity(),
231
- keyword: (0, pg_core_1.text)('keyword').notNull(),
232
- category: (0, pg_core_1.text)('category').notNull(),
233
- priorityLevel: (0, pg_core_1.integer)('priority_level').notNull().default(1),
234
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
235
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
236
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
237
- });
238
- // AI Models for Translation and Classification
239
- exports.aiModels = (0, pg_core_1.pgTable)('AIModel', {
240
- id: (0, pg_core_1.text)('id').primaryKey(),
241
- // Model identification
242
- name: (0, pg_core_1.text)('name').notNull(),
243
- provider: (0, pg_core_1.text)('provider').notNull(),
244
- modelType: (0, pg_core_1.text)('modelType').notNull(),
245
- version: (0, pg_core_1.text)('version').notNull(),
246
- // Configuration
247
- endpoint: (0, pg_core_1.text)('endpoint'),
248
- apiKey: (0, pg_core_1.text)('apiKey'),
249
- maxTokens: (0, pg_core_1.integer)('maxTokens'),
250
- temperature: (0, pg_core_1.real)('temperature'),
251
- // Capabilities
252
- supportsTranslation: (0, pg_core_1.boolean)('supportsTranslation').notNull().default(false),
253
- supportsClassification: (0, pg_core_1.boolean)('supportsClassification').notNull().default(false),
254
- supportedLanguages: (0, pg_core_1.text)('supportedLanguages').array(),
255
- // Status and metadata
256
- isActive: (0, pg_core_1.boolean)('isActive').notNull().default(true),
257
- isDefault: (0, pg_core_1.boolean)('isDefault').notNull().default(false),
258
- priority: (0, pg_core_1.integer)('priority').notNull().default(0),
259
- // Performance tracking
260
- avgResponseTime: (0, pg_core_1.decimal)('avgResponseTime', { precision: 8, scale: 2 }),
261
- successRate: (0, pg_core_1.decimal)('successRate', { precision: 4, scale: 3 }),
262
- lastUsed: (0, pg_core_1.timestamp)('lastUsed'),
263
- // Timestamps
264
- createdAt: (0, pg_core_1.timestamp)('createdAt').notNull().defaultNow(),
265
- updatedAt: (0, pg_core_1.timestamp)('updatedAt').notNull().defaultNow(),
266
- });
267
- exports.contentTranslations = (0, pg_core_1.pgTable)('ContentTranslation', {
268
- id: (0, pg_core_1.text)('id').primaryKey(),
269
- // Content identification
270
- contentType: (0, pg_core_1.text)('contentType').notNull(),
271
- contentId: (0, pg_core_1.text)('contentId').notNull(),
272
- fieldName: (0, pg_core_1.text)('fieldName').notNull(),
273
- // Translation data
274
- originalText: (0, pg_core_1.text)('originalText').notNull(),
275
- originalLanguage: (0, pg_core_1.text)('originalLanguage').notNull().default('ko'),
276
- translatedText: (0, pg_core_1.text)('translatedText').notNull(),
277
- targetLanguage: (0, pg_core_1.text)('targetLanguage').notNull().default('en'),
278
- // AI Model and quality
279
- modelId: (0, pg_core_1.text)('modelId').notNull().references(() => exports.aiModels.id),
280
- confidence: (0, pg_core_1.decimal)('confidence', { precision: 4, scale: 3 }),
281
- qualityScore: (0, pg_core_1.decimal)('qualityScore', { precision: 4, scale: 3 }),
282
- translationTime: (0, pg_core_1.integer)('translationTime'),
283
- tokenCount: (0, pg_core_1.integer)('tokenCount'),
284
- // Translation status and metadata
285
- status: (0, exports.translationStatusEnum)('status').notNull().default('PENDING'),
286
- isManuallyEdited: (0, pg_core_1.boolean)('isManuallyEdited').notNull().default(false),
287
- editedBy: (0, pg_core_1.text)('editedBy'),
288
- editNotes: (0, pg_core_1.text)('editNotes'),
289
- // Timestamps
290
- createdAt: (0, pg_core_1.timestamp)('createdAt').notNull().defaultNow(),
291
- updatedAt: (0, pg_core_1.timestamp)('updatedAt').notNull().defaultNow(),
292
- translatedAt: (0, pg_core_1.timestamp)('translatedAt').notNull().defaultNow(),
293
- });
294
- // News Articles
295
- exports.newsArticles = (0, pg_core_1.pgTable)('news_articles', {
296
- id: (0, pg_core_1.text)('id').primaryKey(),
297
- title: (0, pg_core_1.text)('title').notNull(),
298
- content: (0, pg_core_1.text)('content'),
299
- summary: (0, pg_core_1.text)('summary'),
300
- url: (0, pg_core_1.text)('url').notNull().unique(),
301
- imageUrl: (0, pg_core_1.text)('image_url'),
302
- publishedAt: (0, pg_core_1.timestamp)('published_at').notNull(),
303
- scrapedAt: (0, pg_core_1.timestamp)('scraped_at').notNull().defaultNow(),
304
- // Source information
305
- sourceName: (0, pg_core_1.text)('source_name'),
306
- sourceUrl: (0, pg_core_1.text)('source_url'),
307
- author: (0, pg_core_1.text)('author'),
308
- // Classification
309
- category: (0, pg_core_1.text)('category'),
310
- tags: (0, pg_core_1.text)('tags').array().notNull().default([]),
311
- language: (0, pg_core_1.text)('language').notNull().default('ko'),
312
- // Quality metrics
313
- relevanceScore: (0, pg_core_1.decimal)('relevance_score', { precision: 4, scale: 3 }),
314
- qualityScore: (0, pg_core_1.decimal)('quality_score', { precision: 4, scale: 3 }),
315
- // Processing status
316
- status: (0, exports.contentStatusEnum)('status').notNull().default('PENDING'),
317
- featured: (0, pg_core_1.boolean)('featured').notNull().default(false),
318
- processingNotes: (0, pg_core_1.text)('processing_notes'),
319
- // Timestamps
320
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
321
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
322
- });
323
- // RSS Feeds
324
- exports.rssFeeds = (0, pg_core_1.pgTable)('rss_feeds', {
325
- id: (0, pg_core_1.text)('id').primaryKey(),
326
- name: (0, pg_core_1.text)('name').notNull(),
327
- url: (0, pg_core_1.text)('url').notNull().unique(),
328
- description: (0, pg_core_1.text)('description'),
329
- // Configuration
330
- category: (0, pg_core_1.text)('category').notNull().default('general'),
331
- language: (0, pg_core_1.text)('language').notNull().default('ko'),
332
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
333
- isPaused: (0, pg_core_1.boolean)('is_paused').notNull().default(false),
334
- schedulingEnabled: (0, pg_core_1.boolean)('scheduling_enabled').notNull().default(true),
335
- checkFrequencyMinutes: (0, pg_core_1.integer)('check_frequency_minutes').notNull().default(60),
336
- scrapeInterval: (0, pg_core_1.integer)('scrape_interval').notNull().default(3600),
337
- maxItems: (0, pg_core_1.integer)('max_items').notNull().default(50),
338
- // Statistics
339
- totalArticlesFound: (0, pg_core_1.integer)('total_articles_found').notNull().default(0),
340
- totalArticlesAccepted: (0, pg_core_1.integer)('total_articles_accepted').notNull().default(0),
341
- successCount: (0, pg_core_1.integer)('success_count').notNull().default(0),
342
- errorCount: (0, pg_core_1.integer)('error_count').notNull().default(0),
343
- lastCheckedAt: (0, pg_core_1.timestamp)('last_checked_at'),
344
- lastArticleFoundAt: (0, pg_core_1.timestamp)('last_article_found_at'),
345
- lastSuccessfulCheck: (0, pg_core_1.timestamp)('last_successful_check'),
346
- lastError: (0, pg_core_1.text)('last_error'),
347
- // Scheduling Status
348
- lastRunAt: (0, pg_core_1.timestamp)('last_run_at'),
349
- lastRunStatus: (0, pg_core_1.text)('last_run_status', { enum: ['success', 'failed', 'running'] }),
350
- nextRunAt: (0, pg_core_1.timestamp)('next_run_at'),
351
- lastSuccessAt: (0, pg_core_1.timestamp)('last_success_at'),
352
- lastErrorAt: (0, pg_core_1.timestamp)('last_error_at'),
353
- lastErrorMessage: (0, pg_core_1.text)('last_error_message'),
354
- // Job Duration Tracking
355
- lastRunDuration: (0, pg_core_1.integer)('last_run_duration'), // milliseconds
356
- averageRunDuration: (0, pg_core_1.integer)('average_run_duration'), // milliseconds
357
- lastRunStartedAt: (0, pg_core_1.timestamp)('last_run_started_at'),
358
- lastRunCompletedAt: (0, pg_core_1.timestamp)('last_run_completed_at'),
359
- tags: (0, pg_core_1.text)('tags').array().notNull().default([]),
360
- priority: (0, pg_core_1.integer)('priority').notNull().default(1),
361
- userAgent: (0, pg_core_1.text)('user_agent'),
362
- headers: (0, pg_core_1.text)('headers'),
363
- timeout: (0, pg_core_1.integer)('timeout').notNull().default(30000),
364
- createdBy: (0, pg_core_1.text)('created_by').notNull().default('system'),
365
- // Timestamps
366
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
367
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
368
- });
369
- // RSS Articles
370
- exports.rssArticles = (0, pg_core_1.pgTable)('rss_articles', {
371
- id: (0, pg_core_1.text)('id').primaryKey(),
372
- feedId: (0, pg_core_1.text)('feed_id').notNull().references(() => exports.rssFeeds.id),
373
- // Article content
374
- title: (0, pg_core_1.text)('title').notNull(),
375
- content: (0, pg_core_1.text)('content'),
376
- description: (0, pg_core_1.text)('description'),
377
- url: (0, pg_core_1.text)('url').notNull(),
378
- link: (0, pg_core_1.text)('link'), // Alias for url for compatibility
379
- author: (0, pg_core_1.text)('author'),
380
- publishedAt: (0, pg_core_1.timestamp)('published_at').notNull(),
381
- scrapedAt: (0, pg_core_1.timestamp)('scraped_at').notNull().defaultNow(),
382
- // Classification and metadata
383
- categories: (0, pg_core_1.text)('categories').array().default([]),
384
- tags: (0, pg_core_1.text)('tags').array().default([]),
385
- language: (0, pg_core_1.text)('language').default('ko'),
386
- // Quality and relevance
387
- relevanceScore: (0, pg_core_1.decimal)('relevance_score', { precision: 4, scale: 3 }),
388
- qualityScore: (0, pg_core_1.decimal)('quality_score', { precision: 4, scale: 3 }),
389
- // AI Classification fields
390
- aiClassified: (0, pg_core_1.boolean)('ai_classified').notNull().default(false),
391
- aiConfidence: (0, pg_core_1.decimal)('ai_confidence', { precision: 4, scale: 3 }),
392
- aiReason: (0, pg_core_1.text)('ai_reason'),
393
- isAion2Related: (0, pg_core_1.boolean)('is_aion2_related').notNull().default(false),
394
- // Content Management fields
395
- featured: (0, pg_core_1.boolean)('featured').notNull().default(false),
396
- featuredUntil: (0, pg_core_1.timestamp)('featured_until'),
397
- // Universal Content Filter fields
398
- classificationFilters: (0, pg_core_1.text)('classification_filters').array().default([]), // Array of filter keys that matched
399
- filterMatchDetails: (0, pg_core_1.jsonb)('filter_match_details'), // JSON object with detailed match information
400
- classificationVersion: (0, pg_core_1.text)('classification_version').default('1.0'), // Version of classification system used
401
- classificationKeywords: (0, pg_core_1.text)('classification_keywords').array().default([]), // Keywords that triggered classification
402
- // Translation fields (for Korean content)
403
- titleTranslated: (0, pg_core_1.text)('title_translated'),
404
- descriptionTranslated: (0, pg_core_1.text)('description_translated'),
405
- contentTranslated: (0, pg_core_1.text)('content_translated'),
406
- translatedAt: (0, pg_core_1.timestamp)('translated_at'),
407
- translationConfidence: (0, pg_core_1.decimal)('translation_confidence', { precision: 4, scale: 3 }),
408
- isTranslated: (0, pg_core_1.boolean)('is_translated').notNull().default(false),
409
- // Image fields (for enhanced RSS processing)
410
- imageUrl: (0, pg_core_1.text)('image_url'), // Featured image URL
411
- images: (0, pg_core_1.text)('images'), // JSON array of all image URLs
412
- // Engagement metrics
413
- views: (0, pg_core_1.integer)('views').default(0),
414
- likes: (0, pg_core_1.integer)('likes').default(0),
415
- shares: (0, pg_core_1.integer)('shares').default(0),
416
- // Processing status
417
- status: (0, exports.contentStatusEnum)('status').notNull().default('PENDING'),
418
- processingNotes: (0, pg_core_1.text)('processing_notes'),
419
- // Historical processing fields
420
- isHistorical: (0, pg_core_1.boolean)('is_historical').notNull().default(false),
421
- historicalBatchId: (0, pg_core_1.text)('historical_batch_id'),
422
- // Timestamps
423
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
424
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
425
- });
426
- // YouTube Source Configurations
427
- exports.youtubeSourceConfigs = (0, pg_core_1.pgTable)('youtube_source_config', {
428
- id: (0, pg_core_1.text)('id').primaryKey(),
429
- // Channel information
430
- channelId: (0, pg_core_1.text)('channel_id').notNull().unique(),
431
- channelName: (0, pg_core_1.text)('channel_name').notNull(),
432
- description: (0, pg_core_1.text)('description'),
433
- // Configuration
434
- tier: (0, pg_core_1.integer)('tier').notNull().default(2),
435
- language: (0, pg_core_1.text)('language').notNull().default('ko'),
436
- isOfficial: (0, pg_core_1.boolean)('is_official').notNull().default(false),
437
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
438
- isPaused: (0, pg_core_1.boolean)('is_paused').notNull().default(false),
439
- schedulingEnabled: (0, pg_core_1.boolean)('scheduling_enabled').notNull().default(true),
440
- checkFrequencyMinutes: (0, pg_core_1.integer)('check_frequency_minutes').notNull().default(60),
441
- maxVideos: (0, pg_core_1.integer)('max_videos').notNull().default(50),
442
- // Quality filters
443
- minViews: (0, pg_core_1.integer)('min_views').default(0),
444
- minRelevanceScore: (0, pg_core_1.decimal)('min_relevance_score', { precision: 4, scale: 3 }).default('0.5'),
445
- contentTypes: (0, pg_core_1.text)('content_types').array().default([]), // ['gameplay', 'news', 'review']
446
- // Management
447
- addedBy: (0, pg_core_1.text)('added_by').notNull().default('system'),
448
- notes: (0, pg_core_1.text)('notes'),
449
- // Statistics
450
- totalVideosFound: (0, pg_core_1.integer)('total_videos_found').notNull().default(0),
451
- totalVideosCreated: (0, pg_core_1.integer)('total_videos_created').notNull().default(0),
452
- successCount: (0, pg_core_1.integer)('success_count').notNull().default(0),
453
- errorCount: (0, pg_core_1.integer)('error_count').notNull().default(0),
454
- apiCallsToday: (0, pg_core_1.integer)('api_calls_today').notNull().default(0),
455
- // Status tracking
456
- lastVideoFoundAt: (0, pg_core_1.timestamp)('last_video_found_at'),
457
- lastCheckedAt: (0, pg_core_1.timestamp)('last_checked_at'),
458
- lastSuccessfulCheck: (0, pg_core_1.timestamp)('last_successful_check'),
459
- lastError: (0, pg_core_1.text)('last_error'),
460
- lastRunAt: (0, pg_core_1.timestamp)('last_run_at'),
461
- lastRunStatus: (0, pg_core_1.text)('last_run_status'),
462
- nextRunAt: (0, pg_core_1.timestamp)('next_run_at'),
463
- lastSuccessAt: (0, pg_core_1.timestamp)('last_success_at'),
464
- lastErrorAt: (0, pg_core_1.timestamp)('last_error_at'),
465
- lastErrorMessage: (0, pg_core_1.text)('last_error_message'),
466
- lastRunDuration: (0, pg_core_1.integer)('last_run_duration'),
467
- // Timestamps
468
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
469
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
470
- });
471
- // YouTube Videos
472
- exports.youtubeVideos = (0, pg_core_1.pgTable)('youtube_videos', {
473
- id: (0, pg_core_1.text)('id').primaryKey(),
474
- videoId: (0, pg_core_1.text)('video_id').notNull().unique(),
475
- // Basic video information
476
- title: (0, pg_core_1.text)('title').notNull(),
477
- description: (0, pg_core_1.text)('description'),
478
- channelId: (0, pg_core_1.text)('channel_id').notNull(),
479
- channelName: (0, pg_core_1.text)('channel_name').notNull(),
480
- channelUrl: (0, pg_core_1.text)('channel_url'),
481
- // Video metadata
482
- publishedAt: (0, pg_core_1.timestamp)('published_at').notNull(),
483
- duration: (0, pg_core_1.text)('duration'),
484
- viewCount: (0, pg_core_1.bigint)('view_count', { mode: 'number' }),
485
- likeCount: (0, pg_core_1.integer)('like_count'),
486
- commentCount: (0, pg_core_1.integer)('comment_count'),
487
- // Media
488
- thumbnailUrl: (0, pg_core_1.text)('thumbnail_url'),
489
- thumbnails: (0, pg_core_1.json)('thumbnails'),
490
- // Classification
491
- language: (0, pg_core_1.text)('language').default('ko'),
492
- contentType: (0, pg_core_1.text)('content_type'), // 'gameplay', 'news', 'review', 'guide'
493
- relevanceScore: (0, pg_core_1.decimal)('relevance_score', { precision: 4, scale: 3 }),
494
- qualityScore: (0, pg_core_1.decimal)('quality_score', { precision: 4, scale: 3 }),
495
- // Metadata
496
- tags: (0, pg_core_1.text)('tags').array().default([]),
497
- categoryId: (0, pg_core_1.integer)('category_id'),
498
- isOfficial: (0, pg_core_1.boolean)('is_official').notNull().default(false),
499
- isFeatured: (0, pg_core_1.boolean)('is_featured').notNull().default(false),
500
- // AI Classification fields
501
- aiClassified: (0, pg_core_1.boolean)('ai_classified').notNull().default(false),
502
- aiConfidence: (0, pg_core_1.decimal)('ai_confidence', { precision: 4, scale: 3 }),
503
- aiReason: (0, pg_core_1.text)('ai_reason'),
504
- isAion2Related: (0, pg_core_1.boolean)('is_aion2_related').notNull().default(false),
505
- // Universal Content Filter fields
506
- classificationFilters: (0, pg_core_1.text)('classification_filters').array().default([]),
507
- filterMatchDetails: (0, pg_core_1.jsonb)('filter_match_details'),
508
- classificationVersion: (0, pg_core_1.text)('classification_version').default('1.0'),
509
- classificationKeywords: (0, pg_core_1.text)('classification_keywords').array().default([]),
510
- // Translation fields (for Korean content)
511
- titleTranslated: (0, pg_core_1.text)('title_translated'),
512
- descriptionTranslated: (0, pg_core_1.text)('description_translated'),
513
- translatedAt: (0, pg_core_1.timestamp)('translated_at'),
514
- translationConfidence: (0, pg_core_1.decimal)('translation_confidence', { precision: 4, scale: 3 }),
515
- isTranslated: (0, pg_core_1.boolean)('is_translated').notNull().default(false),
516
- // Processing status
517
- status: (0, exports.contentStatusEnum)('status').notNull().default('PENDING'),
518
- processingNotes: (0, pg_core_1.text)('processing_notes'),
519
- // Source tracking
520
- sourceConfigId: (0, pg_core_1.text)('source_config_id').references(() => exports.youtubeSourceConfigs.id),
521
- // Timestamps
522
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
523
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
524
- });
525
- // YouTube Search Queries
526
- exports.youtubeSearchQueries = (0, pg_core_1.pgTable)('youtube_search_queries', {
527
- id: (0, pg_core_1.text)('id').primaryKey(),
528
- query: (0, pg_core_1.text)('query').notNull(),
529
- language: (0, pg_core_1.text)('language').notNull().default('ko'),
530
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
531
- // Statistics
532
- totalVideosFound: (0, pg_core_1.integer)('total_videos_found').notNull().default(0),
533
- lastSearchAt: (0, pg_core_1.timestamp)('last_search_at'),
534
- // Timestamps
535
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
536
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
537
- });
538
- // YouTube Quota Usage
539
- exports.youtubeQuotaUsage = (0, pg_core_1.pgTable)('youtube_quota_usage', {
540
- id: (0, pg_core_1.text)('id').primaryKey(),
541
- date: (0, pg_core_1.timestamp)('date').notNull(),
542
- quotaUsed: (0, pg_core_1.integer)('quota_used').notNull().default(0),
543
- quotaLimit: (0, pg_core_1.integer)('quota_limit').notNull().default(10000),
544
- operationType: (0, pg_core_1.text)('operation_type').notNull(), // search, videos, channels, etc.
545
- // Timestamps
546
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
547
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
548
- });
549
- // YouTube Channel Extensions
550
- exports.youtubeChannelExtensions = (0, pg_core_1.pgTable)('youtube_channel_extensions', {
551
- id: (0, pg_core_1.text)('id').primaryKey().$defaultFn(() => (0, crypto_1.randomUUID)()),
552
- sourceConfigId: (0, pg_core_1.text)('source_config_id').notNull().references(() => exports.youtubeSourceConfigs.id),
553
- // Manual addition metadata
554
- addedBy: (0, pg_core_1.text)('added_by').notNull(), // User ID who added the channel
555
- userNotes: (0, pg_core_1.text)('user_notes'),
556
- customTags: (0, pg_core_1.text)('custom_tags').array().default([]),
557
- // AI-generated insights
558
- aiDescription: (0, pg_core_1.text)('ai_description'),
559
- contentCategories: (0, pg_core_1.text)('content_categories').array().default([]),
560
- uploadFrequency: (0, pg_core_1.text)('upload_frequency'), // 'daily', 'weekly', 'monthly', 'irregular'
561
- averageVideoLength: (0, pg_core_1.integer)('average_video_length'), // in seconds
562
- primaryLanguage: (0, pg_core_1.text)('primary_language'),
563
- contentTags: (0, pg_core_1.text)('content_tags').array().default([]),
564
- // Metadata
565
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
566
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
567
- });
568
- // YouTube Channel Subscriptions
569
- exports.youtubeChannelSubscriptions = (0, pg_core_1.pgTable)('youtube_channel_subscriptions', {
570
- id: (0, pg_core_1.text)('id').primaryKey().$defaultFn(() => (0, crypto_1.randomUUID)()),
571
- userId: (0, pg_core_1.text)('user_id').notNull(), // References users(id)
572
- sourceConfigId: (0, pg_core_1.text)('source_config_id').notNull().references(() => exports.youtubeSourceConfigs.id),
573
- // Subscription preferences
574
- notificationEnabled: (0, pg_core_1.boolean)('notification_enabled').notNull().default(true),
575
- filterProfileId: (0, pg_core_1.uuid)('filter_profile_id'), // References filter_profiles(id)
576
- // Metadata
577
- subscribedAt: (0, pg_core_1.timestamp)('subscribed_at').notNull().defaultNow()
578
- }, (table) => ({
579
- uniqueUserChannel: (0, pg_core_1.unique)().on(table.userId, table.sourceConfigId)
580
- }));
581
- // YouTube Channel Filter Assignments - Missing table!
582
- exports.youtubeChannelFilterAssignments = (0, pg_core_1.pgTable)('youtube_channel_filter_assignments', {
583
- id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
584
- channelId: (0, pg_core_1.text)('channel_id').notNull().references(() => exports.youtubeSourceConfigs.channelId, { onDelete: 'cascade' }),
585
- profileId: (0, pg_core_1.uuid)('profile_id').notNull().references(() => exports.filterProfiles.id, { onDelete: 'cascade' }),
586
- isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
587
- assignedAt: (0, pg_core_1.timestamp)('assigned_at').notNull().defaultNow(),
588
- assignedBy: (0, pg_core_1.text)('assigned_by'),
589
- }, (table) => ({
590
- uniqueAssignment: (0, pg_core_1.unique)().on(table.channelId, table.profileId)
591
- }));
592
- // YouTube Filter Rules - Advanced filtering for YouTube content
593
- exports.youtubeFilterRules = (0, pg_core_1.pgTable)('youtube_filter_rules', {
594
- id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
595
- profileId: (0, pg_core_1.uuid)('profile_id').notNull().references(() => exports.filterProfiles.id, { onDelete: 'cascade' }),
596
- // Duration filters (in seconds)
597
- minDuration: (0, pg_core_1.integer)('min_duration'), // minimum video duration
598
- maxDuration: (0, pg_core_1.integer)('max_duration'), // maximum video duration
599
- // View count filters
600
- minViewCount: (0, pg_core_1.bigint)('min_view_count', { mode: 'bigint' }),
601
- maxViewCount: (0, pg_core_1.bigint)('max_view_count', { mode: 'bigint' }),
602
- // Engagement filters
603
- minLikeRatio: (0, pg_core_1.decimal)('min_like_ratio', { precision: 5, scale: 4 }), // likes/(likes+dislikes)
604
- minCommentRatio: (0, pg_core_1.decimal)('min_comment_ratio', { precision: 10, scale: 6 }), // comments/views
605
- // Channel criteria
606
- minSubscriberCount: (0, pg_core_1.bigint)('min_subscriber_count', { mode: 'bigint' }),
607
- channelAgeDays: (0, pg_core_1.integer)('channel_age_days'), // minimum channel age in days
608
- // Content type filters
609
- allowedCategories: (0, pg_core_1.integer)('allowed_categories').array(), // YouTube category IDs
610
- blockedCategories: (0, pg_core_1.integer)('blocked_categories').array(),
611
- languageCodes: (0, pg_core_1.text)('language_codes').array(), // allowed language codes
612
- // Content classification
613
- blockedTags: (0, pg_core_1.text)('blocked_tags').array(),
614
- requiredTags: (0, pg_core_1.text)('required_tags').array(),
615
- // Shorts-specific filters
616
- includeShorts: (0, pg_core_1.boolean)('include_shorts').notNull().default(true),
617
- shortsOnly: (0, pg_core_1.boolean)('shorts_only').notNull().default(false),
618
- // Metadata
619
- createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
620
- updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
621
- });
622
- // =============================================================================
623
- // RELATIONS
624
- // =============================================================================
625
- exports.aiModelsRelations = (0, drizzle_orm_1.relations)(exports.aiModels, ({ many }) => ({
626
- translations: many(exports.contentTranslations),
627
- }));
628
- exports.contentTranslationsRelations = (0, drizzle_orm_1.relations)(exports.contentTranslations, ({ one }) => ({
629
- model: one(exports.aiModels, {
630
- fields: [exports.contentTranslations.modelId],
631
- references: [exports.aiModels.id],
632
- }),
633
- }));
634
- exports.rssFeedsRelations = (0, drizzle_orm_1.relations)(exports.rssFeeds, ({ many }) => ({
635
- articles: many(exports.rssArticles),
636
- filterAssignments: many(exports.rssFeedFilterAssignments),
637
- }));
638
- exports.rssArticlesRelations = (0, drizzle_orm_1.relations)(exports.rssArticles, ({ one }) => ({
639
- feed: one(exports.rssFeeds, {
640
- fields: [exports.rssArticles.feedId],
641
- references: [exports.rssFeeds.id],
642
- }),
643
- }));
644
- exports.youtubeSourceConfigsRelations = (0, drizzle_orm_1.relations)(exports.youtubeSourceConfigs, ({ many }) => ({
645
- videos: many(exports.youtubeVideos),
646
- extensions: many(exports.youtubeChannelExtensions),
647
- subscriptions: many(exports.youtubeChannelSubscriptions),
648
- filterAssignments: many(exports.youtubeChannelFilterAssignments),
649
- }));
650
- exports.youtubeVideosRelations = (0, drizzle_orm_1.relations)(exports.youtubeVideos, ({ one }) => ({
651
- sourceConfig: one(exports.youtubeSourceConfigs, {
652
- fields: [exports.youtubeVideos.sourceConfigId],
653
- references: [exports.youtubeSourceConfigs.id],
654
- }),
655
- }));
656
- exports.youtubeChannelExtensionsRelations = (0, drizzle_orm_1.relations)(exports.youtubeChannelExtensions, ({ one }) => ({
657
- sourceConfig: one(exports.youtubeSourceConfigs, {
658
- fields: [exports.youtubeChannelExtensions.sourceConfigId],
659
- references: [exports.youtubeSourceConfigs.id],
660
- }),
661
- }));
662
- exports.youtubeChannelSubscriptionsRelations = (0, drizzle_orm_1.relations)(exports.youtubeChannelSubscriptions, ({ one }) => ({
663
- sourceConfig: one(exports.youtubeSourceConfigs, {
664
- fields: [exports.youtubeChannelSubscriptions.sourceConfigId],
665
- references: [exports.youtubeSourceConfigs.id],
666
- }),
667
- }));
668
- // =============================================================================
669
- // FILTER SYSTEM RELATIONS
670
- // =============================================================================
671
- exports.filterProfilesRelations = (0, drizzle_orm_1.relations)(exports.filterProfiles, ({ many }) => ({
672
- keywords: many(exports.filterKeywords),
673
- rules: many(exports.filterRules),
674
- scoringConfig: many(exports.filterScoringConfig),
675
- feedAssignments: many(exports.rssFeedFilterAssignments),
676
- youtubeChannelAssignments: many(exports.youtubeChannelFilterAssignments),
677
- executionLogs: many(exports.filterExecutionLogs),
678
- youtubeFilterRules: many(exports.youtubeFilterRules),
679
- }));
680
- exports.filterKeywordsRelations = (0, drizzle_orm_1.relations)(exports.filterKeywords, ({ one }) => ({
681
- profile: one(exports.filterProfiles, {
682
- fields: [exports.filterKeywords.profileId],
683
- references: [exports.filterProfiles.id],
684
- }),
685
- }));
686
- exports.filterRulesRelations = (0, drizzle_orm_1.relations)(exports.filterRules, ({ one, many }) => ({
687
- profile: one(exports.filterProfiles, {
688
- fields: [exports.filterRules.profileId],
689
- references: [exports.filterProfiles.id],
690
- }),
691
- conditions: many(exports.filterRuleConditions),
692
- }));
693
- exports.filterRuleConditionsRelations = (0, drizzle_orm_1.relations)(exports.filterRuleConditions, ({ one }) => ({
694
- rule: one(exports.filterRules, {
695
- fields: [exports.filterRuleConditions.ruleId],
696
- references: [exports.filterRules.id],
697
- }),
698
- }));
699
- exports.filterScoringConfigRelations = (0, drizzle_orm_1.relations)(exports.filterScoringConfig, ({ one }) => ({
700
- profile: one(exports.filterProfiles, {
701
- fields: [exports.filterScoringConfig.profileId],
702
- references: [exports.filterProfiles.id],
703
- }),
704
- }));
705
- exports.rssFeedFilterAssignmentsRelations = (0, drizzle_orm_1.relations)(exports.rssFeedFilterAssignments, ({ one }) => ({
706
- rssFeed: one(exports.rssFeeds, {
707
- fields: [exports.rssFeedFilterAssignments.rssFeedId],
708
- references: [exports.rssFeeds.id],
709
- }),
710
- profile: one(exports.filterProfiles, {
711
- fields: [exports.rssFeedFilterAssignments.profileId],
712
- references: [exports.filterProfiles.id],
713
- }),
714
- }));
715
- exports.youtubeChannelFilterAssignmentsRelations = (0, drizzle_orm_1.relations)(exports.youtubeChannelFilterAssignments, ({ one }) => ({
716
- sourceConfig: one(exports.youtubeSourceConfigs, {
717
- fields: [exports.youtubeChannelFilterAssignments.channelId],
718
- references: [exports.youtubeSourceConfigs.channelId],
719
- }),
720
- profile: one(exports.filterProfiles, {
721
- fields: [exports.youtubeChannelFilterAssignments.profileId],
722
- references: [exports.filterProfiles.id],
723
- }),
724
- }));
725
- exports.filterExecutionLogsRelations = (0, drizzle_orm_1.relations)(exports.filterExecutionLogs, ({ one }) => ({
726
- profile: one(exports.filterProfiles, {
727
- fields: [exports.filterExecutionLogs.profileId],
728
- references: [exports.filterProfiles.id],
729
- }),
730
- }));
731
- exports.youtubeFilterRulesRelations = (0, drizzle_orm_1.relations)(exports.youtubeFilterRules, ({ one }) => ({
732
- profile: one(exports.filterProfiles, {
733
- fields: [exports.youtubeFilterRules.profileId],
734
- references: [exports.filterProfiles.id],
735
- }),
736
- }));
737
- //# sourceMappingURL=content-schema.js.map