@aion2hub/shared-schemas 1.0.3-dev.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,eAAO,MAAM,qBAAqB,gHAOhC,CAAC;AAEH,eAAO,MAAM,iBAAiB,iHAO5B,CAAC;AAEH,eAAO,MAAM,aAAa,kGAMxB,CAAC;AAEH,eAAO,MAAM,gBAAgB,2FAO3B,CAAC;AAEH,eAAO,MAAM,cAAc,uGAKzB,CAAC;AAMH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BnB,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+B9B,CAAC;AAMH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCvB,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCnB,CAAC;AAEH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCtB,CAAC;AAMH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0CxB,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkC/B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAa/B,CAAC;AAGH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoB5B,CAAC;AAMH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0CvB,CAAC;AAEH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBlB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BxB,CAAC;AAMH,eAAO,MAAM,iBAAiB;;EAE3B,CAAC;AAEJ,eAAO,MAAM,4BAA4B;;EAKtC,CAAC;AAEJ,eAAO,MAAM,sBAAsB;;EAKhC,CAAC;AAEJ,eAAO,MAAM,6BAA6B;;EAEvC,CAAC;AAEJ,eAAO,MAAM,iBAAiB;;EAE3B,CAAC;AAEJ,eAAO,MAAM,oBAAoB;;EAK9B,CAAC;AAEJ,eAAO,MAAM,qBAAqB;;;EAG/B,CAAC;AAEJ,eAAO,MAAM,gBAAgB;;EAK1B,CAAC;AAEJ,eAAO,MAAM,sBAAsB;;EAKhC,CAAC;AAOJ,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBhB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMvB,CAAC;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBjB,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BnB,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBnB,CAAC;AAEH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBjB,CAAC;AAGJ,eAAO,MAAM,cAAc;;;;;;EAMxB,CAAC;AAEJ,eAAO,MAAM,qBAAqB;;EAK/B,CAAC;AAEJ,eAAO,MAAM,eAAe;;;;EAOzB,CAAC;AAEJ,eAAO,MAAM,iBAAiB;;;;EAO3B,CAAC;AAEJ,eAAO,MAAM,iBAAiB;;;;;;EAqB3B,CAAC;AAEJ,eAAO,MAAM,gBAAgB;;;;EAa1B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,594 @@
1
+ "use strict";
2
+ /**
3
+ * Centralized Database Schemas for All Services
4
+ * This file contains all table definitions for the entire Aion2Hub system
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ratingsRelations = exports.commentsRelations = exports.articlesRelations = exports.buildsRelations = exports.userSessionsRelations = exports.usersRelations = exports.ratings = exports.comments = exports.articles = exports.builds = exports.userSessions = exports.users = exports.jobExecutionsRelations = exports.jobRunsRelations = exports.scrapingJobsRelations = exports.rssArticlesRelations = exports.rssFeedsRelations = exports.youtubeSourceConfigsRelations = exports.youtubeVideosRelations = exports.contentTranslationsRelations = exports.aiModelsRelations = exports.jobExecutions = exports.jobRuns = exports.scrapingJobs = exports.youtubeQuotaUsage = exports.youtubeSearchQueries = exports.youtubeSourceConfigs = exports.youtubeVideos = exports.rssArticles = exports.rssFeeds = exports.newsArticles = exports.contentTranslations = exports.aiModels = 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
+ 'FAILED',
27
+ 'REJECTED',
28
+ 'PUBLISHED'
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
+ // =============================================================================
52
+ // AI MODELS & TRANSLATIONS (Shared across services)
53
+ // =============================================================================
54
+ exports.aiModels = (0, pg_core_1.pgTable)('AIModel', {
55
+ id: (0, pg_core_1.text)('id').primaryKey(),
56
+ name: (0, pg_core_1.text)('name').notNull().unique(),
57
+ displayName: (0, pg_core_1.text)('displayName').notNull(),
58
+ provider: (0, pg_core_1.text)('provider').notNull().default('ollama'),
59
+ // Model specifications
60
+ modelSize: (0, pg_core_1.text)('modelSize'),
61
+ contextSize: (0, pg_core_1.integer)('contextSize'),
62
+ tasks: (0, pg_core_1.text)('tasks').array(),
63
+ languages: (0, pg_core_1.text)('languages').array(),
64
+ // Performance settings
65
+ temperature: (0, pg_core_1.decimal)('temperature', { precision: 3, scale: 2 }).notNull().default('0.30'),
66
+ topP: (0, pg_core_1.decimal)('topP', { precision: 3, scale: 2 }).notNull().default('0.90'),
67
+ maxTokens: (0, pg_core_1.integer)('maxTokens').notNull().default(1000),
68
+ // Status and metadata
69
+ isActive: (0, pg_core_1.boolean)('isActive').notNull().default(true),
70
+ isDefault: (0, pg_core_1.boolean)('isDefault').notNull().default(false),
71
+ priority: (0, pg_core_1.integer)('priority').notNull().default(0),
72
+ // Performance tracking
73
+ avgResponseTime: (0, pg_core_1.decimal)('avgResponseTime', { precision: 8, scale: 2 }),
74
+ successRate: (0, pg_core_1.decimal)('successRate', { precision: 4, scale: 3 }),
75
+ lastUsed: (0, pg_core_1.timestamp)('lastUsed'),
76
+ // Timestamps
77
+ createdAt: (0, pg_core_1.timestamp)('createdAt').notNull().defaultNow(),
78
+ updatedAt: (0, pg_core_1.timestamp)('updatedAt').notNull().defaultNow(),
79
+ });
80
+ exports.contentTranslations = (0, pg_core_1.pgTable)('ContentTranslation', {
81
+ id: (0, pg_core_1.text)('id').primaryKey(),
82
+ // Content identification
83
+ contentType: (0, pg_core_1.text)('contentType').notNull(),
84
+ contentId: (0, pg_core_1.text)('contentId').notNull(),
85
+ fieldName: (0, pg_core_1.text)('fieldName').notNull(),
86
+ // Translation data
87
+ originalText: (0, pg_core_1.text)('originalText').notNull(),
88
+ originalLanguage: (0, pg_core_1.text)('originalLanguage').notNull().default('ko'),
89
+ translatedText: (0, pg_core_1.text)('translatedText').notNull(),
90
+ targetLanguage: (0, pg_core_1.text)('targetLanguage').notNull().default('en'),
91
+ // AI Model and quality
92
+ modelId: (0, pg_core_1.text)('modelId').notNull().references(() => exports.aiModels.id),
93
+ confidence: (0, pg_core_1.decimal)('confidence', { precision: 4, scale: 3 }),
94
+ qualityScore: (0, pg_core_1.decimal)('qualityScore', { precision: 4, scale: 3 }),
95
+ translationTime: (0, pg_core_1.integer)('translationTime'),
96
+ tokenCount: (0, pg_core_1.integer)('tokenCount'),
97
+ // Translation status and metadata
98
+ status: (0, exports.translationStatusEnum)('status').notNull().default('PENDING'),
99
+ isManuallyEdited: (0, pg_core_1.boolean)('isManuallyEdited').notNull().default(false),
100
+ editedBy: (0, pg_core_1.text)('editedBy'),
101
+ editNotes: (0, pg_core_1.text)('editNotes'),
102
+ // Timestamps
103
+ createdAt: (0, pg_core_1.timestamp)('createdAt').notNull().defaultNow(),
104
+ updatedAt: (0, pg_core_1.timestamp)('updatedAt').notNull().defaultNow(),
105
+ translatedAt: (0, pg_core_1.timestamp)('translatedAt').notNull().defaultNow(),
106
+ });
107
+ // =============================================================================
108
+ // CONTENT SERVICE TABLES
109
+ // =============================================================================
110
+ exports.newsArticles = (0, pg_core_1.pgTable)('news_articles', {
111
+ id: (0, pg_core_1.text)('id').primaryKey(),
112
+ title: (0, pg_core_1.text)('title').notNull(),
113
+ content: (0, pg_core_1.text)('content'),
114
+ summary: (0, pg_core_1.text)('summary'),
115
+ url: (0, pg_core_1.text)('url').notNull().unique(),
116
+ imageUrl: (0, pg_core_1.text)('image_url'),
117
+ publishedAt: (0, pg_core_1.timestamp)('published_at').notNull(),
118
+ scrapedAt: (0, pg_core_1.timestamp)('scraped_at').notNull().defaultNow(),
119
+ // Source information
120
+ sourceName: (0, pg_core_1.text)('source_name'),
121
+ sourceUrl: (0, pg_core_1.text)('source_url'),
122
+ author: (0, pg_core_1.text)('author'),
123
+ // Classification
124
+ category: (0, pg_core_1.text)('category'),
125
+ tags: (0, pg_core_1.text)('tags').array().notNull().default([]),
126
+ language: (0, pg_core_1.text)('language').notNull().default('ko'),
127
+ // Quality metrics
128
+ relevanceScore: (0, pg_core_1.decimal)('relevance_score', { precision: 4, scale: 3 }),
129
+ qualityScore: (0, pg_core_1.decimal)('quality_score', { precision: 4, scale: 3 }),
130
+ // Processing status
131
+ status: (0, exports.contentStatusEnum)('status').notNull().default('PENDING'),
132
+ featured: (0, pg_core_1.boolean)('featured').notNull().default(false),
133
+ processingNotes: (0, pg_core_1.text)('processing_notes'),
134
+ // Timestamps
135
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
136
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
137
+ });
138
+ exports.rssFeeds = (0, pg_core_1.pgTable)('rss_feeds', {
139
+ id: (0, pg_core_1.text)('id').primaryKey(),
140
+ name: (0, pg_core_1.text)('name').notNull(),
141
+ url: (0, pg_core_1.text)('url').notNull().unique(),
142
+ description: (0, pg_core_1.text)('description'),
143
+ // Configuration
144
+ category: (0, pg_core_1.text)('category').notNull().default('general'),
145
+ language: (0, pg_core_1.text)('language').notNull().default('ko'),
146
+ isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
147
+ isPaused: (0, pg_core_1.boolean)('is_paused').notNull().default(false),
148
+ checkFrequencyMinutes: (0, pg_core_1.integer)('check_frequency_minutes').notNull().default(60),
149
+ scrapeInterval: (0, pg_core_1.integer)('scrape_interval').notNull().default(3600),
150
+ maxItems: (0, pg_core_1.integer)('max_items').notNull().default(50),
151
+ // Statistics
152
+ totalArticlesFound: (0, pg_core_1.integer)('total_articles_found').notNull().default(0),
153
+ totalArticlesAccepted: (0, pg_core_1.integer)('total_articles_accepted').notNull().default(0),
154
+ successCount: (0, pg_core_1.integer)('success_count').notNull().default(0),
155
+ errorCount: (0, pg_core_1.integer)('error_count').notNull().default(0),
156
+ lastCheckedAt: (0, pg_core_1.timestamp)('last_checked_at'),
157
+ lastArticleFoundAt: (0, pg_core_1.timestamp)('last_article_found_at'),
158
+ lastSuccessfulCheck: (0, pg_core_1.timestamp)('last_successful_check'),
159
+ lastError: (0, pg_core_1.text)('last_error'),
160
+ tags: (0, pg_core_1.text)('tags').array().notNull().default([]),
161
+ priority: (0, pg_core_1.integer)('priority').notNull().default(1),
162
+ userAgent: (0, pg_core_1.text)('user_agent'),
163
+ headers: (0, pg_core_1.text)('headers'),
164
+ timeout: (0, pg_core_1.integer)('timeout').notNull().default(30000),
165
+ createdBy: (0, pg_core_1.text)('created_by').notNull().default('system'),
166
+ // Timestamps
167
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
168
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
169
+ });
170
+ exports.rssArticles = (0, pg_core_1.pgTable)('rss_articles', {
171
+ id: (0, pg_core_1.text)('id').primaryKey(),
172
+ feedId: (0, pg_core_1.text)('feed_id').notNull().references(() => exports.rssFeeds.id),
173
+ // Article content
174
+ title: (0, pg_core_1.text)('title').notNull(),
175
+ content: (0, pg_core_1.text)('content'),
176
+ description: (0, pg_core_1.text)('description'),
177
+ url: (0, pg_core_1.text)('url').notNull(),
178
+ link: (0, pg_core_1.text)('link'), // Alias for url for compatibility
179
+ author: (0, pg_core_1.text)('author'),
180
+ publishedAt: (0, pg_core_1.timestamp)('published_at').notNull(),
181
+ scrapedAt: (0, pg_core_1.timestamp)('scraped_at').notNull().defaultNow(),
182
+ // Classification and metadata
183
+ categories: (0, pg_core_1.text)('categories').array().default([]),
184
+ tags: (0, pg_core_1.text)('tags').array().default([]),
185
+ language: (0, pg_core_1.text)('language').default('ko'),
186
+ // AI Classification
187
+ featured: (0, pg_core_1.boolean)('featured').notNull().default(false),
188
+ aiClassified: (0, pg_core_1.boolean)('ai_classified').notNull().default(false),
189
+ aiConfidence: (0, pg_core_1.decimal)('ai_confidence', { precision: 4, scale: 3 }),
190
+ aiReason: (0, pg_core_1.text)('ai_reason'),
191
+ // Engagement metrics
192
+ views: (0, pg_core_1.integer)('views').default(0),
193
+ likes: (0, pg_core_1.integer)('likes').default(0),
194
+ shares: (0, pg_core_1.integer)('shares').default(0),
195
+ // Processing status
196
+ status: (0, exports.contentStatusEnum)('status').notNull().default('PENDING'),
197
+ // Timestamps
198
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
199
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
200
+ });
201
+ // =============================================================================
202
+ // SCRAPER SERVICE TABLES
203
+ // =============================================================================
204
+ exports.youtubeVideos = (0, pg_core_1.pgTable)('youtube_videos', {
205
+ id: (0, pg_core_1.text)('id').primaryKey(),
206
+ videoId: (0, pg_core_1.text)('video_id').notNull().unique(),
207
+ // Basic video information
208
+ title: (0, pg_core_1.text)('title').notNull(),
209
+ description: (0, pg_core_1.text)('description'),
210
+ channelId: (0, pg_core_1.text)('channel_id').notNull(),
211
+ channelName: (0, pg_core_1.text)('channel_name').notNull(),
212
+ channelUrl: (0, pg_core_1.text)('channel_url'),
213
+ // Video metadata
214
+ publishedAt: (0, pg_core_1.timestamp)('published_at').notNull(),
215
+ duration: (0, pg_core_1.text)('duration'),
216
+ viewCount: (0, pg_core_1.bigint)('view_count', { mode: 'number' }),
217
+ likeCount: (0, pg_core_1.integer)('like_count'),
218
+ commentCount: (0, pg_core_1.integer)('comment_count'),
219
+ // Media
220
+ thumbnailUrl: (0, pg_core_1.text)('thumbnail_url'),
221
+ thumbnails: (0, pg_core_1.json)('thumbnails'),
222
+ // Classification
223
+ category: (0, pg_core_1.text)('category'),
224
+ contentType: (0, pg_core_1.text)('content_type'),
225
+ tags: (0, pg_core_1.text)('tags').array().notNull().default([]),
226
+ language: (0, pg_core_1.text)('language').notNull().default('ko'),
227
+ // Quality and relevance
228
+ relevanceScore: (0, pg_core_1.decimal)('relevance_score', { precision: 4, scale: 3 }),
229
+ qualityScore: (0, pg_core_1.decimal)('quality_score', { precision: 4, scale: 3 }),
230
+ // Processing status
231
+ status: (0, exports.contentStatusEnum)('status').notNull().default('PENDING'),
232
+ processingNotes: (0, pg_core_1.text)('processing_notes'),
233
+ // Source tracking
234
+ sourceConfigId: (0, pg_core_1.text)('source_config_id').references(() => exports.youtubeSourceConfigs.id),
235
+ // Timestamps
236
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
237
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
238
+ });
239
+ exports.youtubeSourceConfigs = (0, pg_core_1.pgTable)('youtube_source_config', {
240
+ id: (0, pg_core_1.text)('id').primaryKey(),
241
+ // Channel information
242
+ channelId: (0, pg_core_1.text)('channel_id').notNull().unique(),
243
+ channelName: (0, pg_core_1.text)('channel_name').notNull(),
244
+ description: (0, pg_core_1.text)('description'),
245
+ // Configuration
246
+ tier: (0, pg_core_1.integer)('tier').notNull().default(2),
247
+ language: (0, pg_core_1.text)('language').notNull().default('ko'),
248
+ isOfficial: (0, pg_core_1.boolean)('is_official').notNull().default(false),
249
+ isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
250
+ checkFrequencyMinutes: (0, pg_core_1.integer)('check_frequency_minutes').notNull().default(60),
251
+ // Quality filters
252
+ minViews: (0, pg_core_1.integer)('min_views'),
253
+ minRelevanceScore: (0, pg_core_1.decimal)('min_relevance_score', { precision: 4, scale: 3 }),
254
+ contentTypes: (0, pg_core_1.text)('content_types').array().notNull().default([]),
255
+ // Metadata
256
+ addedBy: (0, pg_core_1.text)('added_by'),
257
+ notes: (0, pg_core_1.text)('notes'),
258
+ // Statistics
259
+ totalVideosFound: (0, pg_core_1.integer)('total_videos_found').notNull().default(0),
260
+ totalVideosCreated: (0, pg_core_1.integer)('total_videos_created').notNull().default(0),
261
+ apiCallsToday: (0, pg_core_1.integer)('api_calls_today').notNull().default(0),
262
+ lastVideoFoundAt: (0, pg_core_1.timestamp)('last_video_found_at'),
263
+ lastCheckedAt: (0, pg_core_1.timestamp)('last_checked_at'),
264
+ // Timestamps
265
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
266
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
267
+ });
268
+ exports.youtubeSearchQueries = (0, pg_core_1.pgTable)('youtube_search_queries', {
269
+ id: (0, pg_core_1.text)('id').primaryKey(),
270
+ query: (0, pg_core_1.text)('query').notNull(),
271
+ language: (0, pg_core_1.text)('language').notNull().default('ko'),
272
+ isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
273
+ // Statistics
274
+ totalVideosFound: (0, pg_core_1.integer)('total_videos_found').notNull().default(0),
275
+ lastSearchAt: (0, pg_core_1.timestamp)('last_search_at'),
276
+ // Timestamps
277
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
278
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
279
+ });
280
+ // YouTube Quota Usage Table
281
+ exports.youtubeQuotaUsage = (0, pg_core_1.pgTable)('youtube_quota_usage', {
282
+ id: (0, pg_core_1.text)('id').primaryKey(),
283
+ date: (0, pg_core_1.timestamp)('date').notNull(),
284
+ quotaUsed: (0, pg_core_1.integer)('quota_used').notNull().default(0),
285
+ quotaLimit: (0, pg_core_1.integer)('quota_limit').notNull().default(10000),
286
+ operationType: (0, pg_core_1.text)('operation_type').notNull(), // search, videos, channels, etc.
287
+ // Detailed usage tracking
288
+ queriesUsed: (0, pg_core_1.integer)('queries_used').notNull().default(0),
289
+ quotaUnits: (0, pg_core_1.integer)('quota_units').notNull().default(0),
290
+ searchQueries: (0, pg_core_1.integer)('search_queries').notNull().default(0),
291
+ videoDetails: (0, pg_core_1.integer)('video_details').notNull().default(0),
292
+ channelDetails: (0, pg_core_1.integer)('channel_details').notNull().default(0),
293
+ playlistItems: (0, pg_core_1.integer)('playlist_items').notNull().default(0),
294
+ videosProcessed: (0, pg_core_1.integer)('videos_processed').notNull().default(0),
295
+ videosCreated: (0, pg_core_1.integer)('videos_created').notNull().default(0),
296
+ videosSkipped: (0, pg_core_1.integer)('videos_skipped').notNull().default(0),
297
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
298
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
299
+ });
300
+ // =============================================================================
301
+ // JOB MANAGEMENT TABLES
302
+ // =============================================================================
303
+ exports.scrapingJobs = (0, pg_core_1.pgTable)('scraping_jobs', {
304
+ id: (0, pg_core_1.text)('id').primaryKey(),
305
+ name: (0, pg_core_1.text)('name').notNull(),
306
+ description: (0, pg_core_1.text)('description'),
307
+ type: (0, pg_core_1.text)('type').notNull(),
308
+ status: (0, pg_core_1.text)('status').notNull().default('PENDING'),
309
+ priority: (0, pg_core_1.integer)('priority').notNull().default(1),
310
+ // Scheduling
311
+ isScheduled: (0, pg_core_1.boolean)('is_scheduled').notNull().default(false),
312
+ scheduleType: (0, pg_core_1.text)('schedule_type'),
313
+ scheduleExpression: (0, pg_core_1.text)('schedule_expression'),
314
+ nextRunAt: (0, pg_core_1.timestamp)('next_run_at'),
315
+ lastRunAt: (0, pg_core_1.timestamp)('last_run_at'),
316
+ // Configuration
317
+ config: (0, pg_core_1.text)('config'),
318
+ parameters: (0, pg_core_1.text)('parameters'),
319
+ resourceId: (0, pg_core_1.text)('resource_id'),
320
+ resourceType: (0, pg_core_1.text)('resource_type'),
321
+ // Execution tracking
322
+ executionCount: (0, pg_core_1.integer)('execution_count').notNull().default(0),
323
+ successCount: (0, pg_core_1.integer)('success_count').notNull().default(0),
324
+ failureCount: (0, pg_core_1.integer)('failure_count').notNull().default(0),
325
+ lastError: (0, pg_core_1.text)('last_error'),
326
+ lastErrorAt: (0, pg_core_1.timestamp)('last_error_at'),
327
+ lastSuccessAt: (0, pg_core_1.timestamp)('last_success_at'),
328
+ totalItemsProcessed: (0, pg_core_1.integer)('total_items_processed').notNull().default(0),
329
+ totalItemsAccepted: (0, pg_core_1.integer)('total_items_accepted').notNull().default(0),
330
+ totalItemsRejected: (0, pg_core_1.integer)('total_items_rejected').notNull().default(0),
331
+ averageExecutionTime: (0, pg_core_1.integer)('average_execution_time'),
332
+ lastExecutionTime: (0, pg_core_1.integer)('last_execution_time'),
333
+ // User and metadata
334
+ createdBy: (0, pg_core_1.text)('created_by').default('system'),
335
+ tags: (0, pg_core_1.text)('tags').array(),
336
+ metadata: (0, pg_core_1.text)('metadata'),
337
+ // Timestamps
338
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
339
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
340
+ });
341
+ exports.jobRuns = (0, pg_core_1.pgTable)('job_runs', {
342
+ id: (0, pg_core_1.text)('id').primaryKey(),
343
+ jobId: (0, pg_core_1.text)('job_id').notNull().references(() => exports.scrapingJobs.id),
344
+ status: (0, exports.jobStatusEnum)('status').notNull().default('PENDING'),
345
+ startedAt: (0, pg_core_1.timestamp)('started_at').notNull().defaultNow(),
346
+ completedAt: (0, pg_core_1.timestamp)('completed_at'),
347
+ // Results
348
+ itemsProcessed: (0, pg_core_1.integer)('items_processed').notNull().default(0),
349
+ errors: (0, pg_core_1.json)('errors'),
350
+ logs: (0, pg_core_1.text)('logs'),
351
+ // Timestamps
352
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
353
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
354
+ });
355
+ exports.jobExecutions = (0, pg_core_1.pgTable)('job_executions', {
356
+ id: (0, pg_core_1.text)('id').primaryKey(),
357
+ jobId: (0, pg_core_1.text)('job_id').notNull().references(() => exports.scrapingJobs.id),
358
+ status: (0, pg_core_1.text)('status').notNull().default('PENDING'),
359
+ startedAt: (0, pg_core_1.timestamp)('started_at').notNull().defaultNow(),
360
+ completedAt: (0, pg_core_1.timestamp)('completed_at'),
361
+ executionTime: (0, pg_core_1.integer)('execution_time'),
362
+ // Results
363
+ itemsProcessed: (0, pg_core_1.integer)('items_processed').notNull().default(0),
364
+ itemsAccepted: (0, pg_core_1.integer)('items_accepted').notNull().default(0),
365
+ itemsRejected: (0, pg_core_1.integer)('items_rejected').notNull().default(0),
366
+ // Error handling
367
+ error: (0, pg_core_1.text)('error'),
368
+ errorStack: (0, pg_core_1.text)('error_stack'),
369
+ // Logs and output
370
+ logs: (0, pg_core_1.text)('logs'),
371
+ output: (0, pg_core_1.text)('output'),
372
+ // Resource usage
373
+ memoryUsage: (0, pg_core_1.integer)('memory_usage'),
374
+ cpuTime: (0, pg_core_1.integer)('cpu_time'),
375
+ // Timestamps
376
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
377
+ });
378
+ // =============================================================================
379
+ // RELATIONS
380
+ // =============================================================================
381
+ exports.aiModelsRelations = (0, drizzle_orm_1.relations)(exports.aiModels, ({ many }) => ({
382
+ translations: many(exports.contentTranslations),
383
+ }));
384
+ exports.contentTranslationsRelations = (0, drizzle_orm_1.relations)(exports.contentTranslations, ({ one }) => ({
385
+ model: one(exports.aiModels, {
386
+ fields: [exports.contentTranslations.modelId],
387
+ references: [exports.aiModels.id],
388
+ }),
389
+ }));
390
+ exports.youtubeVideosRelations = (0, drizzle_orm_1.relations)(exports.youtubeVideos, ({ one }) => ({
391
+ sourceConfig: one(exports.youtubeSourceConfigs, {
392
+ fields: [exports.youtubeVideos.sourceConfigId],
393
+ references: [exports.youtubeSourceConfigs.id],
394
+ }),
395
+ }));
396
+ exports.youtubeSourceConfigsRelations = (0, drizzle_orm_1.relations)(exports.youtubeSourceConfigs, ({ many }) => ({
397
+ videos: many(exports.youtubeVideos),
398
+ }));
399
+ exports.rssFeedsRelations = (0, drizzle_orm_1.relations)(exports.rssFeeds, ({ many }) => ({
400
+ articles: many(exports.rssArticles),
401
+ }));
402
+ exports.rssArticlesRelations = (0, drizzle_orm_1.relations)(exports.rssArticles, ({ one }) => ({
403
+ feed: one(exports.rssFeeds, {
404
+ fields: [exports.rssArticles.feedId],
405
+ references: [exports.rssFeeds.id],
406
+ }),
407
+ }));
408
+ exports.scrapingJobsRelations = (0, drizzle_orm_1.relations)(exports.scrapingJobs, ({ many }) => ({
409
+ runs: many(exports.jobRuns),
410
+ executions: many(exports.jobExecutions),
411
+ }));
412
+ exports.jobRunsRelations = (0, drizzle_orm_1.relations)(exports.jobRuns, ({ one }) => ({
413
+ job: one(exports.scrapingJobs, {
414
+ fields: [exports.jobRuns.jobId],
415
+ references: [exports.scrapingJobs.id],
416
+ }),
417
+ }));
418
+ exports.jobExecutionsRelations = (0, drizzle_orm_1.relations)(exports.jobExecutions, ({ one }) => ({
419
+ job: one(exports.scrapingJobs, {
420
+ fields: [exports.jobExecutions.jobId],
421
+ references: [exports.scrapingJobs.id],
422
+ }),
423
+ }));
424
+ // ===================================================================
425
+ // USER MANAGEMENT SCHEMAS
426
+ // ===================================================================
427
+ // User Management Schemas
428
+ exports.users = (0, pg_core_1.pgTable)('users', {
429
+ id: (0, pg_core_1.text)('id').primaryKey().$defaultFn(() => (0, crypto_1.randomUUID)()),
430
+ username: (0, pg_core_1.text)('username').notNull().unique(),
431
+ email: (0, pg_core_1.text)('email').notNull().unique(),
432
+ password: (0, pg_core_1.text)('password').notNull(),
433
+ role: (0, pg_core_1.text)('role', { enum: ['USER', 'MODERATOR', 'ADMIN'] }).notNull().default('USER'),
434
+ isActive: (0, pg_core_1.boolean)('is_active').notNull().default(true),
435
+ isVerified: (0, pg_core_1.boolean)('is_verified').notNull().default(false),
436
+ // Profile information
437
+ displayName: (0, pg_core_1.text)('display_name'),
438
+ avatar: (0, pg_core_1.text)('avatar'),
439
+ bio: (0, pg_core_1.text)('bio'),
440
+ location: (0, pg_core_1.text)('location'),
441
+ website: (0, pg_core_1.text)('website'),
442
+ // Game-related information
443
+ favoriteClass: (0, pg_core_1.text)('favorite_class'),
444
+ gameServer: (0, pg_core_1.text)('game_server'),
445
+ guildName: (0, pg_core_1.text)('guild_name'),
446
+ // Timestamps
447
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
448
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
449
+ lastLogin: (0, pg_core_1.timestamp)('last_login')
450
+ });
451
+ exports.userSessions = (0, pg_core_1.pgTable)('user_sessions', {
452
+ id: (0, pg_core_1.text)('id').primaryKey().$defaultFn(() => (0, crypto_1.randomUUID)()),
453
+ userId: (0, pg_core_1.text)('user_id').notNull().references(() => exports.users.id, { onDelete: 'cascade' }),
454
+ token: (0, pg_core_1.text)('token').notNull().unique(),
455
+ expiresAt: (0, pg_core_1.timestamp)('expires_at').notNull(),
456
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow()
457
+ });
458
+ exports.builds = (0, pg_core_1.pgTable)('builds', {
459
+ id: (0, pg_core_1.text)('id').primaryKey().$defaultFn(() => (0, crypto_1.randomUUID)()),
460
+ name: (0, pg_core_1.text)('name').notNull(),
461
+ description: (0, pg_core_1.text)('description'),
462
+ type: (0, pg_core_1.text)('type', { enum: ['GEAR', 'SKILL', 'HYBRID'] }).notNull(),
463
+ classType: (0, pg_core_1.text)('class_type').notNull(),
464
+ data: (0, pg_core_1.json)('data').notNull(), // Flexible JSON data for different build types
465
+ isPublic: (0, pg_core_1.boolean)('is_public').notNull().default(true),
466
+ // Statistics
467
+ views: (0, pg_core_1.integer)('views').notNull().default(0),
468
+ likes: (0, pg_core_1.integer)('likes').notNull().default(0),
469
+ // Timestamps
470
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
471
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
472
+ // Relations
473
+ authorId: (0, pg_core_1.text)('author_id').notNull().references(() => exports.users.id, { onDelete: 'cascade' })
474
+ });
475
+ exports.articles = (0, pg_core_1.pgTable)('articles', {
476
+ id: (0, pg_core_1.text)('id').primaryKey().$defaultFn(() => (0, crypto_1.randomUUID)()),
477
+ title: (0, pg_core_1.text)('title').notNull(),
478
+ slug: (0, pg_core_1.text)('slug').notNull().unique(),
479
+ content: (0, pg_core_1.text)('content').notNull(),
480
+ excerpt: (0, pg_core_1.text)('excerpt'),
481
+ category: (0, pg_core_1.text)('category').notNull(),
482
+ tags: (0, pg_core_1.text)('tags').array().notNull().default([]),
483
+ status: (0, pg_core_1.text)('status', { enum: ['DRAFT', 'PUBLISHED', 'ARCHIVED'] }).notNull().default('DRAFT'),
484
+ // SEO
485
+ metaTitle: (0, pg_core_1.text)('meta_title'),
486
+ metaDescription: (0, pg_core_1.text)('meta_description'),
487
+ // Media
488
+ featuredImage: (0, pg_core_1.text)('featured_image'),
489
+ // Statistics
490
+ views: (0, pg_core_1.integer)('views').notNull().default(0),
491
+ likes: (0, pg_core_1.integer)('likes').notNull().default(0),
492
+ // Timestamps
493
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
494
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
495
+ publishedAt: (0, pg_core_1.timestamp)('published_at'),
496
+ // Relations
497
+ authorId: (0, pg_core_1.text)('author_id').notNull().references(() => exports.users.id, { onDelete: 'cascade' })
498
+ });
499
+ exports.comments = (0, pg_core_1.pgTable)('comments', {
500
+ id: (0, pg_core_1.text)('id').primaryKey().$defaultFn(() => (0, crypto_1.randomUUID)()),
501
+ content: (0, pg_core_1.text)('content').notNull(),
502
+ isApproved: (0, pg_core_1.boolean)('is_approved').notNull().default(false),
503
+ // Timestamps
504
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
505
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
506
+ // Relations
507
+ authorId: (0, pg_core_1.text)('author_id').notNull().references(() => exports.users.id, { onDelete: 'cascade' }),
508
+ buildId: (0, pg_core_1.text)('build_id').references(() => exports.builds.id, { onDelete: 'cascade' }),
509
+ articleId: (0, pg_core_1.text)('article_id').references(() => exports.articles.id, { onDelete: 'cascade' }),
510
+ // Self-referencing for replies
511
+ parentId: (0, pg_core_1.text)('parent_id').references(() => exports.comments.id)
512
+ });
513
+ exports.ratings = (0, pg_core_1.pgTable)('ratings', {
514
+ id: (0, pg_core_1.text)('id').primaryKey().$defaultFn(() => (0, crypto_1.randomUUID)()),
515
+ value: (0, pg_core_1.integer)('value').notNull(), // 1-5 stars
516
+ // Timestamps
517
+ createdAt: (0, pg_core_1.timestamp)('created_at').notNull().defaultNow(),
518
+ updatedAt: (0, pg_core_1.timestamp)('updated_at').notNull().defaultNow(),
519
+ // Relations
520
+ userId: (0, pg_core_1.text)('user_id').notNull().references(() => exports.users.id, { onDelete: 'cascade' }),
521
+ buildId: (0, pg_core_1.text)('build_id').references(() => exports.builds.id, { onDelete: 'cascade' }),
522
+ articleId: (0, pg_core_1.text)('article_id').references(() => exports.articles.id, { onDelete: 'cascade' })
523
+ }, (table) => ({
524
+ // Ensure one rating per user per item
525
+ userBuildUnique: (0, pg_core_1.unique)().on(table.userId, table.buildId),
526
+ userArticleUnique: (0, pg_core_1.unique)().on(table.userId, table.articleId)
527
+ }));
528
+ // User Management Relations
529
+ exports.usersRelations = (0, drizzle_orm_1.relations)(exports.users, ({ many }) => ({
530
+ sessions: many(exports.userSessions),
531
+ builds: many(exports.builds),
532
+ articles: many(exports.articles),
533
+ comments: many(exports.comments),
534
+ ratings: many(exports.ratings)
535
+ }));
536
+ exports.userSessionsRelations = (0, drizzle_orm_1.relations)(exports.userSessions, ({ one }) => ({
537
+ user: one(exports.users, {
538
+ fields: [exports.userSessions.userId],
539
+ references: [exports.users.id]
540
+ })
541
+ }));
542
+ exports.buildsRelations = (0, drizzle_orm_1.relations)(exports.builds, ({ one, many }) => ({
543
+ author: one(exports.users, {
544
+ fields: [exports.builds.authorId],
545
+ references: [exports.users.id]
546
+ }),
547
+ comments: many(exports.comments),
548
+ ratings: many(exports.ratings)
549
+ }));
550
+ exports.articlesRelations = (0, drizzle_orm_1.relations)(exports.articles, ({ one, many }) => ({
551
+ author: one(exports.users, {
552
+ fields: [exports.articles.authorId],
553
+ references: [exports.users.id]
554
+ }),
555
+ comments: many(exports.comments),
556
+ ratings: many(exports.ratings)
557
+ }));
558
+ exports.commentsRelations = (0, drizzle_orm_1.relations)(exports.comments, ({ one, many }) => ({
559
+ author: one(exports.users, {
560
+ fields: [exports.comments.authorId],
561
+ references: [exports.users.id]
562
+ }),
563
+ build: one(exports.builds, {
564
+ fields: [exports.comments.buildId],
565
+ references: [exports.builds.id]
566
+ }),
567
+ article: one(exports.articles, {
568
+ fields: [exports.comments.articleId],
569
+ references: [exports.articles.id]
570
+ }),
571
+ parent: one(exports.comments, {
572
+ fields: [exports.comments.parentId],
573
+ references: [exports.comments.id],
574
+ relationName: 'CommentReplies'
575
+ }),
576
+ replies: many(exports.comments, {
577
+ relationName: 'CommentReplies'
578
+ })
579
+ }));
580
+ exports.ratingsRelations = (0, drizzle_orm_1.relations)(exports.ratings, ({ one }) => ({
581
+ user: one(exports.users, {
582
+ fields: [exports.ratings.userId],
583
+ references: [exports.users.id]
584
+ }),
585
+ build: one(exports.builds, {
586
+ fields: [exports.ratings.buildId],
587
+ references: [exports.builds.id]
588
+ }),
589
+ article: one(exports.articles, {
590
+ fields: [exports.ratings.articleId],
591
+ references: [exports.articles.id]
592
+ })
593
+ }));
594
+ //# sourceMappingURL=index.js.map