@hedgehog-finance/hedgehog-plugin 1.0.21 → 1.0.22
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.
- package/dist/index.d.ts +4 -3
- package/dist/index.js +49 -6
- package/dist/index.js.map +1 -1
- package/dist/setup-api.d.ts +2 -0
- package/dist/setup-api.js +8 -0
- package/dist/setup-api.js.map +1 -0
- package/dist/src/channel.js +25 -23
- package/dist/src/channel.js.map +1 -1
- package/dist/src/core/database.js +449 -39
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/dailyMorningBriefingCron.d.ts +46 -0
- package/dist/src/dailyMorningBriefingCron.js +82 -0
- package/dist/src/dailyMorningBriefingCron.js.map +1 -0
- package/dist/src/features/chartOutput.d.ts +2 -0
- package/dist/src/features/chartOutput.js +35 -0
- package/dist/src/features/chartOutput.js.map +1 -0
- package/dist/src/features/dailyMorningBriefing/schema.d.ts +56 -0
- package/dist/src/features/dailyMorningBriefing/schema.js +22 -0
- package/dist/src/features/dailyMorningBriefing/schema.js.map +1 -0
- package/dist/src/features/dailyMorningBriefing/tools.d.ts +12 -0
- package/dist/src/features/dailyMorningBriefing/tools.js +204 -0
- package/dist/src/features/dailyMorningBriefing/tools.js.map +1 -0
- package/dist/src/features/deepReasoning/schema.d.ts +43 -0
- package/dist/src/features/deepReasoning/schema.js +17 -0
- package/dist/src/features/deepReasoning/schema.js.map +1 -0
- package/dist/src/features/deepReasoning/tools.d.ts +12 -0
- package/dist/src/features/deepReasoning/tools.js +163 -0
- package/dist/src/features/deepReasoning/tools.js.map +1 -0
- package/dist/src/features/index.d.ts +2 -1
- package/dist/src/features/index.js +9 -1
- package/dist/src/features/index.js.map +1 -1
- package/dist/src/features/informationVerification/schema.d.ts +43 -0
- package/dist/src/features/informationVerification/schema.js +17 -0
- package/dist/src/features/informationVerification/schema.js.map +1 -0
- package/dist/src/features/informationVerification/tools.d.ts +12 -0
- package/dist/src/features/informationVerification/tools.js +162 -0
- package/dist/src/features/informationVerification/tools.js.map +1 -0
- package/dist/src/features/notes/schema.d.ts +136 -39
- package/dist/src/features/notes/schema.js +13 -10
- package/dist/src/features/notes/schema.js.map +1 -1
- package/dist/src/features/notes/tools.d.ts +1 -0
- package/dist/src/features/notes/tools.js +47 -14
- package/dist/src/features/notes/tools.js.map +1 -1
- package/dist/src/features/pluginInfo/schema.d.ts +79 -0
- package/dist/src/features/pluginInfo/schema.js +14 -0
- package/dist/src/features/pluginInfo/schema.js.map +1 -0
- package/dist/src/features/pluginInfo/tools.d.ts +1 -0
- package/dist/src/features/pluginInfo/tools.js +157 -2
- package/dist/src/features/pluginInfo/tools.js.map +1 -1
- package/dist/src/features/profileLibrary/schema.d.ts +34 -6
- package/dist/src/features/profileLibrary/schema.js +1 -1
- package/dist/src/features/profileLibrary/schema.js.map +1 -1
- package/dist/src/features/stockAnalysis/schema.d.ts +224 -31
- package/dist/src/features/stockAnalysis/schema.js +76 -12
- package/dist/src/features/stockAnalysis/schema.js.map +1 -1
- package/dist/src/features/stockAnalysis/tools.d.ts +6 -4
- package/dist/src/features/stockAnalysis/tools.js +389 -44
- package/dist/src/features/stockAnalysis/tools.js.map +1 -1
- package/dist/src/features/stockBasic/schema.d.ts +149 -0
- package/dist/src/features/stockBasic/schema.js +26 -0
- package/dist/src/features/stockBasic/schema.js.map +1 -0
- package/dist/src/features/stockBasic/tools.d.ts +12 -0
- package/dist/src/features/stockBasic/tools.js +124 -0
- package/dist/src/features/stockBasic/tools.js.map +1 -0
- package/dist/src/features/watchlist/logic.d.ts +3 -3
- package/dist/src/features/watchlist/logic.js +47 -46
- package/dist/src/features/watchlist/logic.js.map +1 -1
- package/dist/src/features/watchlist/schema.d.ts +89 -54
- package/dist/src/features/watchlist/schema.js +7 -4
- package/dist/src/features/watchlist/schema.js.map +1 -1
- package/dist/src/features/watchlist/tools.d.ts +106 -59
- package/dist/src/features/watchlist/tools.js +182 -104
- package/dist/src/features/watchlist/tools.js.map +1 -1
- package/dist/src/openclawConfig.d.ts +6 -0
- package/dist/src/openclawConfig.js +74 -0
- package/dist/src/openclawConfig.js.map +1 -0
- package/dist/src/openclawConstants.d.ts +4 -0
- package/dist/src/openclawConstants.js +10 -0
- package/dist/src/openclawConstants.js.map +1 -0
- package/dist/src/runtime.js +20 -0
- package/dist/src/runtime.js.map +1 -1
- package/index.ts +52 -5
- package/openclaw.plugin.json +24 -0
- package/package.json +21 -6
- package/setup-api.ts +10 -0
- package/src/channel.ts +26 -25
- package/src/core/database.ts +447 -40
- package/src/dailyMorningBriefingCron.ts +129 -0
- package/src/features/chartOutput.ts +35 -0
- package/src/features/dailyMorningBriefing/schema.ts +38 -0
- package/src/features/dailyMorningBriefing/tools.ts +246 -0
- package/src/features/deepReasoning/schema.ts +22 -0
- package/src/features/deepReasoning/tools.ts +182 -0
- package/src/features/index.ts +11 -2
- package/src/features/informationVerification/schema.ts +22 -0
- package/src/features/informationVerification/tools.ts +181 -0
- package/src/features/notes/schema.ts +17 -12
- package/src/features/notes/tools.ts +54 -17
- package/src/features/pluginInfo/schema.ts +19 -0
- package/src/features/pluginInfo/tools.ts +173 -2
- package/src/features/profileLibrary/schema.ts +1 -1
- package/src/features/stockAnalysis/schema.ts +99 -17
- package/src/features/stockAnalysis/tools.ts +447 -49
- package/src/features/stockBasic/schema.ts +33 -0
- package/src/features/stockBasic/tools.ts +157 -0
- package/src/features/watchlist/logic.ts +56 -53
- package/src/features/watchlist/schema.ts +11 -6
- package/src/features/watchlist/tools.ts +191 -106
- package/src/openclawConfig.ts +101 -0
- package/src/openclawConstants.ts +11 -0
- package/src/runtime.ts +19 -0
|
@@ -47,8 +47,8 @@ function startDailyBackupJob() {
|
|
|
47
47
|
};
|
|
48
48
|
scheduleNextBackup();
|
|
49
49
|
}
|
|
50
|
-
function normalizeMetadataStockCode(
|
|
51
|
-
const code = String(
|
|
50
|
+
function normalizeMetadataStockCode(stock_code, exchange) {
|
|
51
|
+
const code = String(stock_code || "").trim().toUpperCase();
|
|
52
52
|
if (/\.(SH|SS|SZ|HK|US)$/i.test(code)) {
|
|
53
53
|
return code.replace(/\.SS$/i, ".SH");
|
|
54
54
|
}
|
|
@@ -63,36 +63,51 @@ function normalizeMetadataStockCode(stockCode, exchange) {
|
|
|
63
63
|
return code;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
+
function runStockColumnNameMigrations(db) {
|
|
67
|
+
const legacyCodeColumn = "stock" + "Code";
|
|
68
|
+
const legacyNameColumn = "stock" + "Name";
|
|
69
|
+
const tables = ["watchlist", "global_stock_metadata", "stock_classification_cache", "stock_ai_analysis"];
|
|
70
|
+
for (const table of tables) {
|
|
71
|
+
const columns = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
72
|
+
const columnNames = new Set(columns.map(column => column.name));
|
|
73
|
+
if (columnNames.has(legacyCodeColumn) && !columnNames.has("stock_code")) {
|
|
74
|
+
db.prepare(`ALTER TABLE ${table} RENAME COLUMN ${legacyCodeColumn} TO stock_code`).run();
|
|
75
|
+
}
|
|
76
|
+
if (columnNames.has(legacyNameColumn) && !columnNames.has("stock_name")) {
|
|
77
|
+
db.prepare(`ALTER TABLE ${table} RENAME COLUMN ${legacyNameColumn} TO stock_name`).run();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
66
81
|
function runWatchlistDedupMigrations(db) {
|
|
67
82
|
db.exec("BEGIN TRANSACTION");
|
|
68
83
|
try {
|
|
69
84
|
const metadataRows = db.prepare(`
|
|
70
|
-
SELECT
|
|
85
|
+
SELECT stock_code, exchange FROM stock_classification_cache
|
|
71
86
|
`).all();
|
|
72
87
|
const metadataDeleteStmt = db.prepare(`
|
|
73
|
-
DELETE FROM
|
|
88
|
+
DELETE FROM stock_classification_cache WHERE stock_code = ? AND exchange = ?
|
|
74
89
|
`);
|
|
75
90
|
const metadataUpdateStmt = db.prepare(`
|
|
76
|
-
UPDATE
|
|
91
|
+
UPDATE stock_classification_cache SET stock_code = ? WHERE stock_code = ? AND exchange = ?
|
|
77
92
|
`);
|
|
78
93
|
const metadataExistsStmt = db.prepare(`
|
|
79
|
-
SELECT 1 FROM
|
|
94
|
+
SELECT 1 FROM stock_classification_cache WHERE stock_code = ? AND exchange = ?
|
|
80
95
|
`);
|
|
81
96
|
for (const row of metadataRows) {
|
|
82
|
-
const normalizedCode = normalizeMetadataStockCode(row.
|
|
83
|
-
if (!normalizedCode || normalizedCode === row.
|
|
97
|
+
const normalizedCode = normalizeMetadataStockCode(row.stock_code, row.exchange);
|
|
98
|
+
if (!normalizedCode || normalizedCode === row.stock_code)
|
|
84
99
|
continue;
|
|
85
100
|
const existing = metadataExistsStmt.get(normalizedCode, row.exchange);
|
|
86
101
|
if (existing) {
|
|
87
|
-
metadataDeleteStmt.run(row.
|
|
102
|
+
metadataDeleteStmt.run(row.stock_code, row.exchange);
|
|
88
103
|
}
|
|
89
104
|
else {
|
|
90
|
-
metadataUpdateStmt.run(normalizedCode, row.
|
|
105
|
+
metadataUpdateStmt.run(normalizedCode, row.stock_code, row.exchange);
|
|
91
106
|
}
|
|
92
107
|
}
|
|
93
108
|
const duplicateCategories = db.prepare(`
|
|
94
109
|
SELECT userId, name, type, MIN(id) AS keepId, GROUP_CONCAT(id) AS ids
|
|
95
|
-
FROM
|
|
110
|
+
FROM industry_theme_categories
|
|
96
111
|
GROUP BY userId, name, type
|
|
97
112
|
HAVING COUNT(*) > 1
|
|
98
113
|
`).all();
|
|
@@ -101,7 +116,7 @@ function runWatchlistDedupMigrations(db) {
|
|
|
101
116
|
const ids = dup.ids.split(",").filter(id => id && id !== dup.keepId);
|
|
102
117
|
for (const oldId of ids) {
|
|
103
118
|
db.prepare(`UPDATE ${table} SET categoryId = ? WHERE userId = ? AND categoryId = ?`).run(dup.keepId, dup.userId, oldId);
|
|
104
|
-
db.prepare("DELETE FROM
|
|
119
|
+
db.prepare("DELETE FROM industry_theme_categories WHERE id = ?").run(oldId);
|
|
105
120
|
}
|
|
106
121
|
}
|
|
107
122
|
db.exec(`
|
|
@@ -123,14 +138,108 @@ function runWatchlistDedupMigrations(db) {
|
|
|
123
138
|
throw e;
|
|
124
139
|
}
|
|
125
140
|
db.exec(`
|
|
126
|
-
CREATE UNIQUE INDEX IF NOT EXISTS
|
|
127
|
-
ON
|
|
141
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_industry_theme_categories_user_name_type
|
|
142
|
+
ON industry_theme_categories(userId, name, type);
|
|
128
143
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_watchlist_industry_items_watchlist_category
|
|
129
144
|
ON watchlist_industry_items(watchlistId, categoryId);
|
|
130
145
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_watchlist_theme_items_watchlist_category
|
|
131
146
|
ON watchlist_theme_items(watchlistId, categoryId);
|
|
132
147
|
`);
|
|
133
148
|
}
|
|
149
|
+
function runClassificationCacheMigrations(db) {
|
|
150
|
+
const oldColumns = db.prepare("PRAGMA table_info(global_stock_metadata)").all();
|
|
151
|
+
if (oldColumns.length === 0)
|
|
152
|
+
return;
|
|
153
|
+
const oldColumnNames = new Set(oldColumns.map(column => column.name));
|
|
154
|
+
const industryColumn = oldColumnNames.has("industry_classification") ? "industry_classification" : "industryJson";
|
|
155
|
+
const themeColumn = oldColumnNames.has("theme_classification") ? "theme_classification" : oldColumnNames.has("theme") ? "theme" : "themeJson";
|
|
156
|
+
const updatedColumn = oldColumnNames.has("last_updated") ? "last_updated" : "lastUpdated";
|
|
157
|
+
if (!oldColumnNames.has(industryColumn) || !oldColumnNames.has(themeColumn))
|
|
158
|
+
return;
|
|
159
|
+
db.exec("BEGIN");
|
|
160
|
+
try {
|
|
161
|
+
db.exec(`
|
|
162
|
+
INSERT OR REPLACE INTO stock_classification_cache (
|
|
163
|
+
stock_code,
|
|
164
|
+
exchange,
|
|
165
|
+
stock_name,
|
|
166
|
+
industry_classification,
|
|
167
|
+
theme_classification,
|
|
168
|
+
last_updated
|
|
169
|
+
)
|
|
170
|
+
SELECT
|
|
171
|
+
stock_code,
|
|
172
|
+
exchange,
|
|
173
|
+
stock_name,
|
|
174
|
+
${industryColumn},
|
|
175
|
+
${themeColumn},
|
|
176
|
+
${updatedColumn}
|
|
177
|
+
FROM global_stock_metadata;
|
|
178
|
+
|
|
179
|
+
DROP TABLE global_stock_metadata;
|
|
180
|
+
`);
|
|
181
|
+
db.exec("COMMIT");
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
if (db.inTransaction)
|
|
185
|
+
db.exec("ROLLBACK");
|
|
186
|
+
throw e;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function runClassificationCacheSchemaMigrations(db) {
|
|
190
|
+
const columns = db.prepare("PRAGMA table_info(stock_classification_cache)").all();
|
|
191
|
+
if (columns.length === 0)
|
|
192
|
+
return;
|
|
193
|
+
const columnNames = new Set(columns.map(column => column.name));
|
|
194
|
+
if (columnNames.has("theme") && !columnNames.has("theme_classification")) {
|
|
195
|
+
db.prepare("ALTER TABLE stock_classification_cache RENAME COLUMN theme TO theme_classification").run();
|
|
196
|
+
columnNames.delete("theme");
|
|
197
|
+
columnNames.add("theme_classification");
|
|
198
|
+
}
|
|
199
|
+
if (columnNames.has("lastUpdated") && !columnNames.has("last_updated")) {
|
|
200
|
+
db.prepare("ALTER TABLE stock_classification_cache RENAME COLUMN lastUpdated TO last_updated").run();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function runIndustryThemeCategoryMigrations(db) {
|
|
204
|
+
const oldColumns = db.prepare("PRAGMA table_info(watchlist_categories)").all();
|
|
205
|
+
if (oldColumns.length === 0)
|
|
206
|
+
return;
|
|
207
|
+
db.exec("BEGIN");
|
|
208
|
+
try {
|
|
209
|
+
db.exec(`
|
|
210
|
+
INSERT OR IGNORE INTO industry_theme_categories (
|
|
211
|
+
id,
|
|
212
|
+
remoteId,
|
|
213
|
+
userId,
|
|
214
|
+
name,
|
|
215
|
+
type,
|
|
216
|
+
weight,
|
|
217
|
+
sortOrder,
|
|
218
|
+
createdAt,
|
|
219
|
+
updatedAt
|
|
220
|
+
)
|
|
221
|
+
SELECT
|
|
222
|
+
id,
|
|
223
|
+
remoteId,
|
|
224
|
+
userId,
|
|
225
|
+
name,
|
|
226
|
+
type,
|
|
227
|
+
weight,
|
|
228
|
+
sortOrder,
|
|
229
|
+
createdAt,
|
|
230
|
+
updatedAt
|
|
231
|
+
FROM watchlist_categories;
|
|
232
|
+
|
|
233
|
+
DROP TABLE watchlist_categories;
|
|
234
|
+
`);
|
|
235
|
+
db.exec("COMMIT");
|
|
236
|
+
}
|
|
237
|
+
catch (e) {
|
|
238
|
+
if (db.inTransaction)
|
|
239
|
+
db.exec("ROLLBACK");
|
|
240
|
+
throw e;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
134
243
|
function runStockNotesMigrations(db) {
|
|
135
244
|
const columns = db.prepare("PRAGMA table_info(stock_notes)").all();
|
|
136
245
|
if (columns.length > 0 && !columns.some(column => column.name === "watchlistId")) {
|
|
@@ -142,6 +251,67 @@ function runStockNotesMigrations(db) {
|
|
|
142
251
|
}
|
|
143
252
|
db.exec("CREATE INDEX IF NOT EXISTS idx_stock_notes_user_stock ON stock_notes(userId, watchlistId, updatedAt DESC)");
|
|
144
253
|
}
|
|
254
|
+
function runDailyMorningBriefingMigrations(db) {
|
|
255
|
+
const tableColumns = db.prepare("PRAGMA table_info(daily_morning_briefings)").all();
|
|
256
|
+
const tableColumnNames = new Set(tableColumns.map(column => column.name));
|
|
257
|
+
const indexes = db.prepare("PRAGMA index_list(daily_morning_briefings)").all();
|
|
258
|
+
const hasUniqueDateMarketIndex = indexes.some(index => {
|
|
259
|
+
if (index.unique !== 1)
|
|
260
|
+
return false;
|
|
261
|
+
const columns = db.prepare(`PRAGMA index_info(${index.name})`).all();
|
|
262
|
+
const columnNames = columns.map(column => column.name);
|
|
263
|
+
return columnNames.length === 2 && columnNames.includes("briefingDate") && columnNames.includes("market");
|
|
264
|
+
});
|
|
265
|
+
if (!hasUniqueDateMarketIndex)
|
|
266
|
+
return;
|
|
267
|
+
const snapshotColumn = tableColumnNames.has("watchlistSnapshot") ? "watchlistSnapshot" : "watchlistSnapshotJson";
|
|
268
|
+
const statusColumn = tableColumnNames.has("status") ? "status" : "'completed'";
|
|
269
|
+
db.exec("BEGIN");
|
|
270
|
+
try {
|
|
271
|
+
db.exec(`
|
|
272
|
+
DROP TABLE IF EXISTS daily_morning_briefings_history;
|
|
273
|
+
|
|
274
|
+
CREATE TABLE daily_morning_briefings_history (
|
|
275
|
+
id TEXT PRIMARY KEY,
|
|
276
|
+
market TEXT NOT NULL DEFAULT 'CN',
|
|
277
|
+
briefingDate TEXT NOT NULL,
|
|
278
|
+
content TEXT NOT NULL,
|
|
279
|
+
status TEXT NOT NULL DEFAULT 'completed',
|
|
280
|
+
watchlistSnapshot TEXT NOT NULL DEFAULT '[]',
|
|
281
|
+
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
282
|
+
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW'))
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
INSERT INTO daily_morning_briefings_history (id, market, briefingDate, content, status, watchlistSnapshot, createdAt, updatedAt)
|
|
286
|
+
SELECT id, market, briefingDate, content, ${statusColumn}, ${snapshotColumn}, createdAt, updatedAt
|
|
287
|
+
FROM daily_morning_briefings;
|
|
288
|
+
|
|
289
|
+
DROP TABLE daily_morning_briefings;
|
|
290
|
+
ALTER TABLE daily_morning_briefings_history RENAME TO daily_morning_briefings;
|
|
291
|
+
CREATE INDEX IF NOT EXISTS idx_daily_morning_briefings_date ON daily_morning_briefings(briefingDate DESC);
|
|
292
|
+
`);
|
|
293
|
+
db.exec("COMMIT");
|
|
294
|
+
}
|
|
295
|
+
catch (e) {
|
|
296
|
+
if (db.inTransaction)
|
|
297
|
+
db.exec("ROLLBACK");
|
|
298
|
+
throw e;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function runDailyMorningBriefingSchemaMigrations(db) {
|
|
302
|
+
const columns = db.prepare("PRAGMA table_info(daily_morning_briefings)").all();
|
|
303
|
+
if (columns.length === 0)
|
|
304
|
+
return;
|
|
305
|
+
const columnNames = new Set(columns.map(column => column.name));
|
|
306
|
+
if (columnNames.has("watchlistSnapshotJson") && !columnNames.has("watchlistSnapshot")) {
|
|
307
|
+
db.prepare("ALTER TABLE daily_morning_briefings RENAME COLUMN watchlistSnapshotJson TO watchlistSnapshot").run();
|
|
308
|
+
columnNames.delete("watchlistSnapshotJson");
|
|
309
|
+
columnNames.add("watchlistSnapshot");
|
|
310
|
+
}
|
|
311
|
+
if (!columnNames.has("status")) {
|
|
312
|
+
db.prepare("ALTER TABLE daily_morning_briefings ADD COLUMN status TEXT NOT NULL DEFAULT 'completed'").run();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
145
315
|
function runStockAiAnalysisMigrations(db) {
|
|
146
316
|
const indexes = db.prepare("PRAGMA index_list(stock_ai_analysis)").all();
|
|
147
317
|
const hasUniqueStockIndex = indexes.some(index => {
|
|
@@ -149,7 +319,7 @@ function runStockAiAnalysisMigrations(db) {
|
|
|
149
319
|
return false;
|
|
150
320
|
const columns = db.prepare(`PRAGMA index_info(${index.name})`).all();
|
|
151
321
|
const columnNames = columns.map(column => column.name);
|
|
152
|
-
return columnNames.includes("userId") && columnNames.includes("
|
|
322
|
+
return columnNames.includes("userId") && columnNames.includes("stock_code");
|
|
153
323
|
});
|
|
154
324
|
if (!hasUniqueStockIndex)
|
|
155
325
|
return;
|
|
@@ -161,8 +331,8 @@ function runStockAiAnalysisMigrations(db) {
|
|
|
161
331
|
CREATE TABLE stock_ai_analysis_history (
|
|
162
332
|
id TEXT NOT NULL,
|
|
163
333
|
userId TEXT NOT NULL,
|
|
164
|
-
|
|
165
|
-
|
|
334
|
+
stock_code TEXT NOT NULL,
|
|
335
|
+
stock_name TEXT NOT NULL,
|
|
166
336
|
market TEXT NOT NULL DEFAULT 'CN',
|
|
167
337
|
content TEXT NOT NULL,
|
|
168
338
|
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
@@ -170,13 +340,13 @@ function runStockAiAnalysisMigrations(db) {
|
|
|
170
340
|
PRIMARY KEY(id, userId)
|
|
171
341
|
);
|
|
172
342
|
|
|
173
|
-
INSERT INTO stock_ai_analysis_history (id, userId,
|
|
174
|
-
SELECT id, userId,
|
|
343
|
+
INSERT INTO stock_ai_analysis_history (id, userId, stock_code, stock_name, market, content, createdAt, updatedAt)
|
|
344
|
+
SELECT id, userId, stock_code, stock_name, market, content, createdAt, updatedAt
|
|
175
345
|
FROM stock_ai_analysis;
|
|
176
346
|
|
|
177
347
|
DROP TABLE stock_ai_analysis;
|
|
178
348
|
ALTER TABLE stock_ai_analysis_history RENAME TO stock_ai_analysis;
|
|
179
|
-
CREATE INDEX IF NOT EXISTS idx_stock_ai_analysis_user_stock_updated ON stock_ai_analysis(userId,
|
|
349
|
+
CREATE INDEX IF NOT EXISTS idx_stock_ai_analysis_user_stock_updated ON stock_ai_analysis(userId, stock_code, updatedAt DESC);
|
|
180
350
|
`);
|
|
181
351
|
db.exec("COMMIT");
|
|
182
352
|
}
|
|
@@ -186,6 +356,12 @@ function runStockAiAnalysisMigrations(db) {
|
|
|
186
356
|
throw e;
|
|
187
357
|
}
|
|
188
358
|
}
|
|
359
|
+
function runStockAiAnalysisSchemaMigrations(db) {
|
|
360
|
+
const columns = db.prepare("PRAGMA table_info(stock_ai_analysis)").all();
|
|
361
|
+
if (columns.length > 0 && !columns.some(column => column.name === "status")) {
|
|
362
|
+
db.prepare("ALTER TABLE stock_ai_analysis ADD COLUMN status TEXT NOT NULL DEFAULT 'completed'").run();
|
|
363
|
+
}
|
|
364
|
+
}
|
|
189
365
|
function runArticleAiAnalysisMigrations(db) {
|
|
190
366
|
const columns = db.prepare("PRAGMA table_info(article_ai_analysis)").all();
|
|
191
367
|
if (columns.length === 0 || columns.some(column => column.name === "sourceId")) {
|
|
@@ -226,6 +402,162 @@ function runArticleAiAnalysisMigrations(db) {
|
|
|
226
402
|
throw e;
|
|
227
403
|
}
|
|
228
404
|
}
|
|
405
|
+
function runNewsAnalysisMigrations(db) {
|
|
406
|
+
const columns = db.prepare("PRAGMA table_info(article_ai_analysis)").all();
|
|
407
|
+
if (columns.length === 0 || !columns.some(column => column.name === "sourceId")) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
db.exec("BEGIN");
|
|
411
|
+
try {
|
|
412
|
+
db.exec(`
|
|
413
|
+
INSERT OR REPLACE INTO news_fact_check_analysis (id, sourceId, sourceTitle, userId, status, content, createdAt, updatedAt)
|
|
414
|
+
SELECT id, sourceId, '', userId, 'completed', content, createdAt, updatedAt
|
|
415
|
+
FROM article_ai_analysis
|
|
416
|
+
WHERE analysisType = 'verification';
|
|
417
|
+
|
|
418
|
+
INSERT OR REPLACE INTO news_deep_reasoning_analysis (id, sourceId, sourceTitle, userId, market, status, content, createdAt, updatedAt)
|
|
419
|
+
SELECT id, sourceId, '', userId, market, 'completed', content, createdAt, updatedAt
|
|
420
|
+
FROM article_ai_analysis
|
|
421
|
+
WHERE analysisType = 'deduction';
|
|
422
|
+
|
|
423
|
+
DROP TABLE article_ai_analysis;
|
|
424
|
+
`);
|
|
425
|
+
db.exec("COMMIT");
|
|
426
|
+
}
|
|
427
|
+
catch (e) {
|
|
428
|
+
if (db.inTransaction)
|
|
429
|
+
db.exec("ROLLBACK");
|
|
430
|
+
throw e;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
function runNewsFactCheckAnalysisSchemaMigrations(db) {
|
|
434
|
+
const columns = db.prepare("PRAGMA table_info(news_fact_check_analysis)").all();
|
|
435
|
+
if (columns.length === 0)
|
|
436
|
+
return;
|
|
437
|
+
const columnNames = new Set(columns.map(column => column.name));
|
|
438
|
+
if (!columnNames.has("market") &&
|
|
439
|
+
columnNames.has("sourceTitle"))
|
|
440
|
+
return;
|
|
441
|
+
const sourceTitleExpr = columnNames.has("sourceTitle") ? "sourceTitle" : "''";
|
|
442
|
+
const statusExpr = columnNames.has("status") ? "status" : "'completed'";
|
|
443
|
+
db.exec("BEGIN");
|
|
444
|
+
try {
|
|
445
|
+
db.exec(`
|
|
446
|
+
DROP TABLE IF EXISTS news_fact_check_analysis_v2;
|
|
447
|
+
|
|
448
|
+
CREATE TABLE news_fact_check_analysis_v2 (
|
|
449
|
+
id TEXT NOT NULL,
|
|
450
|
+
sourceId TEXT NOT NULL,
|
|
451
|
+
sourceTitle TEXT NOT NULL DEFAULT '',
|
|
452
|
+
userId TEXT NOT NULL,
|
|
453
|
+
status TEXT NOT NULL DEFAULT 'completed',
|
|
454
|
+
content TEXT NOT NULL,
|
|
455
|
+
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
456
|
+
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
457
|
+
PRIMARY KEY(id, userId),
|
|
458
|
+
UNIQUE(sourceId, userId)
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
INSERT OR REPLACE INTO news_fact_check_analysis_v2 (id, sourceId, sourceTitle, userId, status, content, createdAt, updatedAt)
|
|
462
|
+
SELECT id, sourceId, ${sourceTitleExpr}, userId, ${statusExpr}, content, createdAt, updatedAt
|
|
463
|
+
FROM news_fact_check_analysis;
|
|
464
|
+
|
|
465
|
+
DROP TABLE news_fact_check_analysis;
|
|
466
|
+
ALTER TABLE news_fact_check_analysis_v2 RENAME TO news_fact_check_analysis;
|
|
467
|
+
CREATE INDEX IF NOT EXISTS idx_news_fact_check_analysis_user_source_updated
|
|
468
|
+
ON news_fact_check_analysis(userId, sourceId, updatedAt DESC);
|
|
469
|
+
`);
|
|
470
|
+
db.exec("COMMIT");
|
|
471
|
+
}
|
|
472
|
+
catch (e) {
|
|
473
|
+
if (db.inTransaction)
|
|
474
|
+
db.exec("ROLLBACK");
|
|
475
|
+
throw e;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
function runNewsDeepReasoningAnalysisSchemaMigrations(db) {
|
|
479
|
+
const columns = db.prepare("PRAGMA table_info(news_deep_reasoning_analysis)").all();
|
|
480
|
+
if (columns.length === 0)
|
|
481
|
+
return;
|
|
482
|
+
const columnNames = new Set(columns.map(column => column.name));
|
|
483
|
+
if (columnNames.has("market") && columnNames.has("sourceTitle"))
|
|
484
|
+
return;
|
|
485
|
+
const sourceTitleExpr = columnNames.has("sourceTitle") ? "sourceTitle" : "''";
|
|
486
|
+
const marketExpr = columnNames.has("market") ? "market" : "'CN'";
|
|
487
|
+
const statusExpr = columnNames.has("status") ? "status" : "'completed'";
|
|
488
|
+
db.exec("BEGIN");
|
|
489
|
+
try {
|
|
490
|
+
db.exec(`
|
|
491
|
+
DROP TABLE IF EXISTS news_deep_reasoning_analysis_v2;
|
|
492
|
+
|
|
493
|
+
CREATE TABLE news_deep_reasoning_analysis_v2 (
|
|
494
|
+
id TEXT NOT NULL,
|
|
495
|
+
sourceId TEXT NOT NULL,
|
|
496
|
+
sourceTitle TEXT NOT NULL DEFAULT '',
|
|
497
|
+
userId TEXT NOT NULL,
|
|
498
|
+
market TEXT NOT NULL DEFAULT 'CN',
|
|
499
|
+
status TEXT NOT NULL DEFAULT 'completed',
|
|
500
|
+
content TEXT NOT NULL,
|
|
501
|
+
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
502
|
+
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
503
|
+
PRIMARY KEY(id, userId),
|
|
504
|
+
UNIQUE(sourceId, userId, market)
|
|
505
|
+
);
|
|
506
|
+
|
|
507
|
+
INSERT OR REPLACE INTO news_deep_reasoning_analysis_v2 (id, sourceId, sourceTitle, userId, market, status, content, createdAt, updatedAt)
|
|
508
|
+
SELECT id, sourceId, ${sourceTitleExpr}, userId, ${marketExpr}, ${statusExpr}, content, createdAt, updatedAt
|
|
509
|
+
FROM news_deep_reasoning_analysis;
|
|
510
|
+
|
|
511
|
+
DROP TABLE news_deep_reasoning_analysis;
|
|
512
|
+
ALTER TABLE news_deep_reasoning_analysis_v2 RENAME TO news_deep_reasoning_analysis;
|
|
513
|
+
CREATE INDEX IF NOT EXISTS idx_news_deep_reasoning_analysis_user_source_updated
|
|
514
|
+
ON news_deep_reasoning_analysis(userId, sourceId, updatedAt DESC);
|
|
515
|
+
`);
|
|
516
|
+
db.exec("COMMIT");
|
|
517
|
+
}
|
|
518
|
+
catch (e) {
|
|
519
|
+
if (db.inTransaction)
|
|
520
|
+
db.exec("ROLLBACK");
|
|
521
|
+
throw e;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
function runNewsFactCheckDropSourceContentMigration(db) {
|
|
525
|
+
const columns = db.prepare("PRAGMA table_info(news_fact_check_analysis)").all();
|
|
526
|
+
if (columns.length === 0)
|
|
527
|
+
return;
|
|
528
|
+
if (!columns.some(column => column.name === "sourceContent"))
|
|
529
|
+
return;
|
|
530
|
+
db.prepare("ALTER TABLE news_fact_check_analysis DROP COLUMN sourceContent").run();
|
|
531
|
+
}
|
|
532
|
+
function runNewsDeepReasoningDropSourceContentMigration(db) {
|
|
533
|
+
const columns = db.prepare("PRAGMA table_info(news_deep_reasoning_analysis)").all();
|
|
534
|
+
if (columns.length === 0)
|
|
535
|
+
return;
|
|
536
|
+
if (!columns.some(column => column.name === "sourceContent"))
|
|
537
|
+
return;
|
|
538
|
+
db.prepare("ALTER TABLE news_deep_reasoning_analysis DROP COLUMN sourceContent").run();
|
|
539
|
+
}
|
|
540
|
+
function runProfileLibrariesSchemaMigrations(db) {
|
|
541
|
+
const columns = db.prepare("PRAGMA table_info(profile_libraries)").all();
|
|
542
|
+
if (columns.length === 0)
|
|
543
|
+
return;
|
|
544
|
+
const columnNames = new Set(columns.map(column => column.name));
|
|
545
|
+
if (!columnNames.has("knowType")) {
|
|
546
|
+
db.prepare("ALTER TABLE profile_libraries ADD COLUMN knowType TEXT").run();
|
|
547
|
+
}
|
|
548
|
+
if (!columnNames.has("recordDate")) {
|
|
549
|
+
db.prepare("ALTER TABLE profile_libraries ADD COLUMN recordDate DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW'))").run();
|
|
550
|
+
}
|
|
551
|
+
if (!columnNames.has("content")) {
|
|
552
|
+
db.prepare("ALTER TABLE profile_libraries ADD COLUMN content TEXT").run();
|
|
553
|
+
}
|
|
554
|
+
if (!columnNames.has("vectorValue")) {
|
|
555
|
+
db.prepare("ALTER TABLE profile_libraries ADD COLUMN vectorValue BLOB").run();
|
|
556
|
+
}
|
|
557
|
+
if (!columnNames.has("source")) {
|
|
558
|
+
db.prepare("ALTER TABLE profile_libraries ADD COLUMN source TEXT").run();
|
|
559
|
+
}
|
|
560
|
+
}
|
|
229
561
|
export function getDB() {
|
|
230
562
|
if (!_db) {
|
|
231
563
|
const dbPath = getDbPath();
|
|
@@ -240,34 +572,57 @@ export function getDB() {
|
|
|
240
572
|
_db = new DatabaseSync(dbPath);
|
|
241
573
|
_db.exec("PRAGMA journal_mode = WAL");
|
|
242
574
|
_db.exec("PRAGMA synchronous = NORMAL");
|
|
575
|
+
runStockColumnNameMigrations(_db);
|
|
243
576
|
_db.exec(`
|
|
244
577
|
CREATE TABLE IF NOT EXISTS watchlist (
|
|
245
578
|
id TEXT PRIMARY KEY,
|
|
246
579
|
userId TEXT NOT NULL,
|
|
247
|
-
|
|
580
|
+
stock_code TEXT NOT NULL,
|
|
248
581
|
exchange TEXT NOT NULL,
|
|
249
582
|
market TEXT NOT NULL,
|
|
250
|
-
|
|
583
|
+
stock_name TEXT NOT NULL,
|
|
251
584
|
sortOrder REAL DEFAULT 0,
|
|
252
585
|
isDeleted INTEGER DEFAULT 0 CHECK (isDeleted IN (0, 1)),
|
|
253
586
|
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
254
587
|
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
255
|
-
UNIQUE(userId,
|
|
588
|
+
UNIQUE(userId, stock_code, exchange)
|
|
256
589
|
);
|
|
257
590
|
|
|
258
|
-
CREATE TABLE IF NOT EXISTS
|
|
259
|
-
|
|
260
|
-
exchange
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
PRIMARY KEY(
|
|
591
|
+
CREATE TABLE IF NOT EXISTS stock_classification_cache (
|
|
592
|
+
stock_code TEXT NOT NULL,
|
|
593
|
+
exchange TEXT NOT NULL,
|
|
594
|
+
stock_name TEXT NOT NULL,
|
|
595
|
+
industry_classification TEXT,
|
|
596
|
+
theme_classification TEXT,
|
|
597
|
+
last_updated DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
598
|
+
PRIMARY KEY(stock_code, exchange)
|
|
266
599
|
);
|
|
267
600
|
|
|
268
601
|
CREATE INDEX IF NOT EXISTS idx_watchlist_main ON watchlist(userId, isDeleted, sortOrder ASC);
|
|
269
602
|
|
|
270
|
-
CREATE TABLE IF NOT EXISTS
|
|
603
|
+
CREATE TABLE IF NOT EXISTS stock_basic (
|
|
604
|
+
stock_code TEXT PRIMARY KEY,
|
|
605
|
+
symbol TEXT NOT NULL,
|
|
606
|
+
name TEXT NOT NULL,
|
|
607
|
+
fullname TEXT,
|
|
608
|
+
enname TEXT,
|
|
609
|
+
cnspell TEXT,
|
|
610
|
+
exchange TEXT NOT NULL,
|
|
611
|
+
market TEXT,
|
|
612
|
+
industry TEXT,
|
|
613
|
+
area TEXT,
|
|
614
|
+
curr_type TEXT,
|
|
615
|
+
list_date TEXT,
|
|
616
|
+
is_hs TEXT,
|
|
617
|
+
act_name TEXT,
|
|
618
|
+
act_ent_type TEXT,
|
|
619
|
+
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
620
|
+
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW'))
|
|
621
|
+
);
|
|
622
|
+
CREATE INDEX IF NOT EXISTS idx_stock_basic_exchange_symbol ON stock_basic(exchange, symbol);
|
|
623
|
+
CREATE INDEX IF NOT EXISTS idx_stock_basic_name ON stock_basic(name);
|
|
624
|
+
|
|
625
|
+
CREATE TABLE IF NOT EXISTS industry_theme_categories (
|
|
271
626
|
id TEXT PRIMARY KEY,
|
|
272
627
|
remoteId TEXT,
|
|
273
628
|
userId TEXT NOT NULL,
|
|
@@ -306,7 +661,12 @@ export function getDB() {
|
|
|
306
661
|
CREATE TABLE IF NOT EXISTS profile_libraries (
|
|
307
662
|
id TEXT NOT NULL,
|
|
308
663
|
userId TEXT NOT NULL,
|
|
664
|
+
knowType TEXT,
|
|
309
665
|
title TEXT NOT NULL,
|
|
666
|
+
recordDate DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
667
|
+
content TEXT,
|
|
668
|
+
vectorValue BLOB,
|
|
669
|
+
source TEXT,
|
|
310
670
|
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
311
671
|
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
312
672
|
PRIMARY KEY(id, userId)
|
|
@@ -337,34 +697,84 @@ export function getDB() {
|
|
|
337
697
|
CREATE TABLE IF NOT EXISTS stock_ai_analysis (
|
|
338
698
|
id TEXT NOT NULL,
|
|
339
699
|
userId TEXT NOT NULL,
|
|
340
|
-
|
|
341
|
-
|
|
700
|
+
stock_code TEXT NOT NULL,
|
|
701
|
+
stock_name TEXT NOT NULL,
|
|
342
702
|
market TEXT NOT NULL DEFAULT 'CN',
|
|
703
|
+
status TEXT NOT NULL DEFAULT 'completed',
|
|
343
704
|
content TEXT NOT NULL,
|
|
344
705
|
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
345
706
|
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
346
707
|
PRIMARY KEY(id, userId)
|
|
347
708
|
);
|
|
348
|
-
CREATE INDEX IF NOT EXISTS idx_stock_ai_analysis_user_stock_updated ON stock_ai_analysis(userId,
|
|
709
|
+
CREATE INDEX IF NOT EXISTS idx_stock_ai_analysis_user_stock_updated ON stock_ai_analysis(userId, stock_code, updatedAt DESC);
|
|
710
|
+
|
|
711
|
+
CREATE TABLE IF NOT EXISTS news_fact_check_analysis (
|
|
712
|
+
id TEXT NOT NULL,
|
|
713
|
+
sourceId TEXT NOT NULL,
|
|
714
|
+
sourceTitle TEXT NOT NULL DEFAULT '',
|
|
715
|
+
userId TEXT NOT NULL,
|
|
716
|
+
status TEXT NOT NULL DEFAULT 'completed',
|
|
717
|
+
content TEXT NOT NULL,
|
|
718
|
+
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
719
|
+
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
720
|
+
PRIMARY KEY(id, userId),
|
|
721
|
+
UNIQUE(sourceId, userId)
|
|
722
|
+
);
|
|
723
|
+
CREATE INDEX IF NOT EXISTS idx_news_fact_check_analysis_user_source_updated
|
|
724
|
+
ON news_fact_check_analysis(userId, sourceId, updatedAt DESC);
|
|
349
725
|
|
|
350
|
-
CREATE TABLE IF NOT EXISTS
|
|
726
|
+
CREATE TABLE IF NOT EXISTS news_deep_reasoning_analysis (
|
|
351
727
|
id TEXT NOT NULL,
|
|
352
728
|
sourceId TEXT NOT NULL,
|
|
729
|
+
sourceTitle TEXT NOT NULL DEFAULT '',
|
|
353
730
|
userId TEXT NOT NULL,
|
|
354
|
-
analysisType TEXT NOT NULL,
|
|
355
731
|
market TEXT NOT NULL DEFAULT 'CN',
|
|
732
|
+
status TEXT NOT NULL DEFAULT 'completed',
|
|
356
733
|
content TEXT NOT NULL,
|
|
357
734
|
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
358
735
|
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
359
736
|
PRIMARY KEY(id, userId),
|
|
360
|
-
UNIQUE(sourceId, userId,
|
|
737
|
+
UNIQUE(sourceId, userId, market)
|
|
738
|
+
);
|
|
739
|
+
CREATE INDEX IF NOT EXISTS idx_news_deep_reasoning_analysis_user_source_updated
|
|
740
|
+
ON news_deep_reasoning_analysis(userId, sourceId, updatedAt DESC);
|
|
741
|
+
|
|
742
|
+
CREATE TABLE IF NOT EXISTS daily_morning_briefings (
|
|
743
|
+
id TEXT PRIMARY KEY,
|
|
744
|
+
market TEXT NOT NULL DEFAULT 'CN',
|
|
745
|
+
briefingDate TEXT NOT NULL,
|
|
746
|
+
content TEXT NOT NULL,
|
|
747
|
+
status TEXT NOT NULL DEFAULT 'completed',
|
|
748
|
+
watchlistSnapshot TEXT NOT NULL DEFAULT '[]',
|
|
749
|
+
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
750
|
+
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW'))
|
|
751
|
+
);
|
|
752
|
+
CREATE INDEX IF NOT EXISTS idx_daily_morning_briefings_date ON daily_morning_briefings(briefingDate DESC);
|
|
753
|
+
|
|
754
|
+
CREATE TABLE IF NOT EXISTS skill_versions (
|
|
755
|
+
skillName TEXT PRIMARY KEY,
|
|
756
|
+
version TEXT NOT NULL,
|
|
757
|
+
createdAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')),
|
|
758
|
+
updatedAt DATETIME DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW'))
|
|
361
759
|
);
|
|
362
|
-
CREATE INDEX IF NOT EXISTS idx_article_ai_analysis_user_source_type_updated ON article_ai_analysis(userId, sourceId, analysisType, updatedAt DESC);
|
|
363
760
|
`);
|
|
761
|
+
runClassificationCacheSchemaMigrations(_db);
|
|
762
|
+
runClassificationCacheMigrations(_db);
|
|
763
|
+
runClassificationCacheSchemaMigrations(_db);
|
|
764
|
+
runIndustryThemeCategoryMigrations(_db);
|
|
364
765
|
runWatchlistDedupMigrations(_db);
|
|
365
766
|
runStockNotesMigrations(_db);
|
|
366
767
|
runStockAiAnalysisMigrations(_db);
|
|
768
|
+
runStockAiAnalysisSchemaMigrations(_db);
|
|
367
769
|
runArticleAiAnalysisMigrations(_db);
|
|
770
|
+
runNewsFactCheckAnalysisSchemaMigrations(_db);
|
|
771
|
+
runNewsDeepReasoningAnalysisSchemaMigrations(_db);
|
|
772
|
+
runNewsAnalysisMigrations(_db);
|
|
773
|
+
runDailyMorningBriefingMigrations(_db);
|
|
774
|
+
runDailyMorningBriefingSchemaMigrations(_db);
|
|
775
|
+
runNewsFactCheckDropSourceContentMigration(_db);
|
|
776
|
+
runNewsDeepReasoningDropSourceContentMigration(_db);
|
|
777
|
+
runProfileLibrariesSchemaMigrations(_db);
|
|
368
778
|
}
|
|
369
779
|
return _db;
|
|
370
780
|
}
|