From 24376285913296ce3382351385cc9213a7c34fea Mon Sep 17 00:00:00 2001 From: Bojan Kucera Date: Mon, 9 Jun 2025 20:19:25 -0400 Subject: [PATCH] fixed mongo --- bun.lock | 58 ++++----- libs/mongodb-client/package.json | 3 +- libs/mongodb-client/src/client.ts | 10 +- libs/mongodb-client/src/schemas.ts | 190 ++++++++++++++--------------- package.json | 2 +- 5 files changed, 133 insertions(+), 130 deletions(-) diff --git a/bun.lock b/bun.lock index a4fa487..fb3a174 100644 --- a/bun.lock +++ b/bun.lock @@ -10,7 +10,7 @@ "@testcontainers/mongodb": "^10.7.2", "@testcontainers/postgresql": "^10.7.2", "@types/bun": "latest", - "@types/node": "^20.12.12", + "@types/node": "^22.15.30", "@types/supertest": "^6.0.2", "@types/yup": "^0.32.0", "bun-types": "^1.2.15", @@ -875,7 +875,7 @@ "@types/methods": ["@types/methods@1.1.4", "", {}, "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ=="], - "@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + "@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], "@types/pg": ["@types/pg@8.15.4", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg=="], @@ -2151,12 +2151,38 @@ "@parcel/watcher/node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], - "@stock-bot/execution-service/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], + "@stock-bot/cache/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], - "@stock-bot/portfolio-service/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], + "@stock-bot/config/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/data-frame/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/event-bus/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/http/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/logger/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/mongodb-client/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/postgres-client/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/questdb-client/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/shutdown/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/strategy-engine/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/strategy-service/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], "@stock-bot/strategy-service/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], + "@stock-bot/types/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/utils/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + + "@stock-bot/vector-engine/@types/node": ["@types/node@20.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q=="], + "@tailwindcss/oxide/tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g=="], @@ -2173,22 +2199,6 @@ "@tufjs/models/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - "@types/cors/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - - "@types/docker-modem/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - - "@types/dockerode/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - - "@types/pg/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - - "@types/ssh2/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - - "@types/ssh2-streams/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - - "@types/superagent/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - - "@types/ws/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.3", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg=="], "ajv-formats/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], @@ -2207,8 +2217,6 @@ "body-parser/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], - "bun-types/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - "cacache/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], "cacache/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], @@ -2237,8 +2245,6 @@ "encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], - "engine.io/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - "engine.io/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="], "engine.io/ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="], @@ -2323,8 +2329,6 @@ "properties-reader/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], - "protobufjs/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - "readdir-glob/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], "restore-cursor/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], @@ -2519,8 +2523,6 @@ "@angular/compiler-cli/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], - "mongodb-memory-server-core/mongodb/mongodb-connection-string-url/@types/whatwg-url/@types/node": ["@types/node@22.15.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA=="], - "mongodb-memory-server-core/mongodb/mongodb-connection-string-url/whatwg-url/tr46": ["tr46@3.0.0", "", { "dependencies": { "punycode": "^2.1.1" } }, "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA=="], "pkg-dir/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], diff --git a/libs/mongodb-client/package.json b/libs/mongodb-client/package.json index 095cb98..eb3a7c0 100644 --- a/libs/mongodb-client/package.json +++ b/libs/mongodb-client/package.json @@ -12,7 +12,8 @@ "type-check": "tsc --noEmit", "clean": "rimraf dist" }, - "dependencies": { "@stock-bot/config": "*", + "dependencies": { + "@stock-bot/config": "*", "@stock-bot/logger": "*", "@stock-bot/types": "*", "mongodb": "^6.3.0", diff --git a/libs/mongodb-client/src/client.ts b/libs/mongodb-client/src/client.ts index df25b86..ebc867d 100644 --- a/libs/mongodb-client/src/client.ts +++ b/libs/mongodb-client/src/client.ts @@ -15,7 +15,7 @@ import type { } from './types'; import { MongoDBHealthMonitor } from './health'; import { schemaMap } from './schemas'; -import { z } from 'zod'; +import * as yup from 'yup'; /** * MongoDB Client for Stock Bot @@ -147,15 +147,15 @@ export class MongoDBClient { } as T; // Validate document if schema exists if (collectionName in schemaMap) { try { - (schemaMap as any)[collectionName].parse(docWithTimestamps); + (schemaMap as any)[collectionName].validateSync(docWithTimestamps); } catch (error) { - if (error instanceof z.ZodError) { + if (error instanceof yup.ValidationError) { this.logger.error(`Document validation failed for ${collectionName}:`, error.errors); - throw new Error(`Document validation failed: ${error.errors.map(e => e.message).join(', ')}`); + throw new Error(`Document validation failed: ${error.errors?.map(e => e).join(', ')}`); } throw error; } - } const result = await collection.insertOne(docWithTimestamps as OptionalUnlessRequiredId); + }const result = await collection.insertOne(docWithTimestamps as OptionalUnlessRequiredId); return { ...docWithTimestamps, _id: result.insertedId } as T; } diff --git a/libs/mongodb-client/src/schemas.ts b/libs/mongodb-client/src/schemas.ts index 7b25e7f..4a90348 100644 --- a/libs/mongodb-client/src/schemas.ts +++ b/libs/mongodb-client/src/schemas.ts @@ -1,124 +1,124 @@ import * as yup from 'yup'; /** - * Zod Schemas for MongoDB Document Validation + * Yup Schemas for MongoDB Document Validation */ // Base schema for all documents -export const documentBaseSchema = z.object({ - _id: z.any().optional(), - created_at: z.date(), - updated_at: z.date(), - source: z.string(), - metadata: z.record(z.any()).optional(), +export const documentBaseSchema = yup.object({ + _id: yup.mixed().optional(), + created_at: yup.date().required(), + updated_at: yup.date().required(), + source: yup.string().required(), + metadata: yup.object().optional(), }); // Sentiment Data Schema -export const sentimentDataSchema = documentBaseSchema.extend({ - symbol: z.string().min(1).max(10), - sentiment_score: z.number().min(-1).max(1), - sentiment_label: z.enum(['positive', 'negative', 'neutral']), - confidence: z.number().min(0).max(1), - text: z.string().min(1), - source_type: z.enum(['reddit', 'twitter', 'news', 'forums']), - source_id: z.string(), - timestamp: z.date(), - processed_at: z.date(), - language: z.string().default('en'), - keywords: z.array(z.string()), - entities: z.array(z.object({ - name: z.string(), - type: z.string(), - confidence: z.number().min(0).max(1), - })), +export const sentimentDataSchema = documentBaseSchema.shape({ + symbol: yup.string().min(1).max(10).required(), + sentiment_score: yup.number().min(-1).max(1).required(), + sentiment_label: yup.string().oneOf(['positive', 'negative', 'neutral']).required(), + confidence: yup.number().min(0).max(1).required(), + text: yup.string().min(1).required(), + source_type: yup.string().oneOf(['reddit', 'twitter', 'news', 'forums']).required(), + source_id: yup.string().required(), + timestamp: yup.date().required(), + processed_at: yup.date().required(), + language: yup.string().default('en'), + keywords: yup.array(yup.string()).required(), + entities: yup.array(yup.object({ + name: yup.string().required(), + type: yup.string().required(), + confidence: yup.number().min(0).max(1).required(), + })).required(), }); // Raw Document Schema -export const rawDocumentSchema = documentBaseSchema.extend({ - document_type: z.enum(['html', 'pdf', 'text', 'json', 'xml']), - content: z.string(), - content_hash: z.string(), - url: z.string().url().optional(), - title: z.string().optional(), - author: z.string().optional(), - published_date: z.date().optional(), - extracted_text: z.string().optional(), - processing_status: z.enum(['pending', 'processed', 'failed']), - size_bytes: z.number().positive(), - language: z.string().optional(), +export const rawDocumentSchema = documentBaseSchema.shape({ + document_type: yup.string().oneOf(['html', 'pdf', 'text', 'json', 'xml']).required(), + content: yup.string().required(), + content_hash: yup.string().required(), + url: yup.string().url().optional(), + title: yup.string().optional(), + author: yup.string().optional(), + published_date: yup.date().optional(), + extracted_text: yup.string().optional(), + processing_status: yup.string().oneOf(['pending', 'processed', 'failed']).required(), + size_bytes: yup.number().positive().required(), + language: yup.string().optional(), }); // News Article Schema -export const newsArticleSchema = documentBaseSchema.extend({ - headline: z.string().min(1), - content: z.string().min(1), - summary: z.string().optional(), - author: z.string(), - publication: z.string(), - published_date: z.date(), - url: z.string().url(), - symbols: z.array(z.string()), - categories: z.array(z.string()), - sentiment_score: z.number().min(-1).max(1).optional(), - relevance_score: z.number().min(0).max(1).optional(), - image_url: z.string().url().optional(), - tags: z.array(z.string()), +export const newsArticleSchema = documentBaseSchema.shape({ + headline: yup.string().min(1).required(), + content: yup.string().min(1).required(), + summary: yup.string().optional(), + author: yup.string().required(), + publication: yup.string().required(), + published_date: yup.date().required(), + url: yup.string().url().required(), + symbols: yup.array(yup.string()).required(), + categories: yup.array(yup.string()).required(), + sentiment_score: yup.number().min(-1).max(1).optional(), + relevance_score: yup.number().min(0).max(1).optional(), + image_url: yup.string().url().optional(), + tags: yup.array(yup.string()).required(), }); // SEC Filing Schema -export const secFilingSchema = documentBaseSchema.extend({ - cik: z.string(), - accession_number: z.string(), - filing_type: z.string(), - company_name: z.string(), - symbols: z.array(z.string()), - filing_date: z.date(), - period_end_date: z.date(), - url: z.string().url(), - content: z.string(), - extracted_data: z.record(z.any()).optional(), - financial_statements: z.array(z.object({ - statement_type: z.string(), - data: z.record(z.number()), +export const secFilingSchema = documentBaseSchema.shape({ + cik: yup.string().required(), + accession_number: yup.string().required(), + filing_type: yup.string().required(), + company_name: yup.string().required(), + symbols: yup.array(yup.string()).required(), + filing_date: yup.date().required(), + period_end_date: yup.date().required(), + url: yup.string().url().required(), + content: yup.string().required(), + extracted_data: yup.object().optional(), + financial_statements: yup.array(yup.object({ + statement_type: yup.string().required(), + data: yup.object().required(), })).optional(), - processing_status: z.enum(['pending', 'processed', 'failed']), + processing_status: yup.string().oneOf(['pending', 'processed', 'failed']).required(), }); // Earnings Transcript Schema -export const earningsTranscriptSchema = documentBaseSchema.extend({ - symbol: z.string().min(1).max(10), - company_name: z.string(), - quarter: z.string(), - year: z.number().min(2000).max(3000), - call_date: z.date(), - transcript: z.string(), - participants: z.array(z.object({ - name: z.string(), - title: z.string(), - type: z.enum(['executive', 'analyst']), - })), - key_topics: z.array(z.string()), - sentiment_analysis: z.object({ - overall_sentiment: z.number().min(-1).max(1), - topic_sentiments: z.record(z.number()), +export const earningsTranscriptSchema = documentBaseSchema.shape({ + symbol: yup.string().min(1).max(10).required(), + company_name: yup.string().required(), + quarter: yup.string().required(), + year: yup.number().min(2000).max(3000).required(), + call_date: yup.date().required(), + transcript: yup.string().required(), + participants: yup.array(yup.object({ + name: yup.string().required(), + title: yup.string().required(), + type: yup.string().oneOf(['executive', 'analyst']).required(), + })).required(), + key_topics: yup.array(yup.string()).required(), + sentiment_analysis: yup.object({ + overall_sentiment: yup.number().min(-1).max(1).required(), + topic_sentiments: yup.object().required(), }).optional(), - financial_highlights: z.record(z.number()).optional(), + financial_highlights: yup.object().optional(), }); // Analyst Report Schema -export const analystReportSchema = documentBaseSchema.extend({ - symbol: z.string().min(1).max(10), - analyst_firm: z.string(), - analyst_name: z.string(), - report_title: z.string(), - report_date: z.date(), - rating: z.enum(['buy', 'hold', 'sell', 'strong_buy', 'strong_sell']), - price_target: z.number().positive().optional(), - previous_rating: z.string().optional(), - content: z.string(), - summary: z.string(), - key_points: z.array(z.string()), - financial_projections: z.record(z.number()).optional(), +export const analystReportSchema = documentBaseSchema.shape({ + symbol: yup.string().min(1).max(10).required(), + analyst_firm: yup.string().required(), + analyst_name: yup.string().required(), + report_title: yup.string().required(), + report_date: yup.date().required(), + rating: yup.string().oneOf(['buy', 'hold', 'sell', 'strong_buy', 'strong_sell']).required(), + price_target: yup.number().positive().optional(), + previous_rating: yup.string().optional(), + content: yup.string().required(), + summary: yup.string().required(), + key_points: yup.array(yup.string()).required(), + financial_projections: yup.object().optional(), }); // Schema mapping for collections diff --git a/package.json b/package.json index 7d2f96d..2ce1e06 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@testcontainers/mongodb": "^10.7.2", "@testcontainers/postgresql": "^10.7.2", "@types/bun": "latest", - "@types/node": "^20.12.12", + "@types/node": "^22.15.30", "@types/supertest": "^6.0.2", "@types/yup": "^0.32.0", "bun-types": "^1.2.15",