Files
sapiens-mobile/server/storage.ts
jungwoo choi 919afe56f2 feat: SAPIENS Mobile App - Initial commit
React Native mobile application for SAPIENS news platform.
Consolidated all previous history into single commit.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 14:30:25 +09:00

1969 lines
85 KiB
TypeScript

import {
type User,
type InsertUser,
type MediaOutlet,
type InsertMediaOutlet,
type Article,
type InsertArticle,
type Comment,
type InsertComment,
type CommentReaction,
type InsertCommentReaction,
type Bookmark,
type InsertBookmark,
type PredictionMarket,
type InsertPredictionMarket,
users,
mediaOutlets,
articles,
comments,
commentReactions,
bookmarks,
predictionMarkets
} from "@shared/schema";
import { randomUUID } from "crypto";
import { drizzle } from "drizzle-orm/neon-http";
import { neon } from "@neondatabase/serverless";
import { eq, desc, asc, and, or, sql, like, count } from "drizzle-orm";
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
// Initialize database connection
if (!process.env.DATABASE_URL) {
throw new Error("DATABASE_URL environment variable is required");
}
const sqlClient = neon(process.env.DATABASE_URL);
const db = drizzle(sqlClient);
// Storage interface for the news platform
export interface IStorage {
// User methods
getUser(id: string): Promise<User | undefined>;
getUserByUsername(username: string): Promise<User | undefined>;
createUser(user: InsertUser): Promise<User>;
// Media outlet methods
getAllOutlets(): Promise<MediaOutlet[]>;
getOutletsByCategory(category: string): Promise<MediaOutlet[]>;
getOutletById(id: string): Promise<MediaOutlet | undefined>;
createOutlet(outlet: InsertMediaOutlet): Promise<MediaOutlet>;
deleteOutlet(id: string): Promise<boolean>;
updateOutlet(id: string, updates: Partial<InsertMediaOutlet>): Promise<MediaOutlet | undefined>;
mergeOutlets(fromOutletId: string, toOutletId: string): Promise<{ success: boolean; movedArticles: number }>;
// Article methods
getAllArticles(): Promise<Article[]>;
getArticlesByOutlet(outletId: string): Promise<Article[]>;
getArticleById(id: string): Promise<Article | undefined>;
getFeaturedArticles(limit?: number): Promise<Article[]>;
searchArticles(query: string): Promise<Article[]>;
createArticle(article: InsertArticle): Promise<Article>;
deleteArticle(id: string): Promise<boolean>;
// Scraped article methods
createScrapedArticle(article: Omit<InsertArticle, 'id'> & {
sourceUrl: string;
author?: string;
originalImageUrl?: string;
isScraped?: number;
}): Promise<Article>;
getScrapedArticles(limit?: number): Promise<Article[]>;
updateArticleWithScrapedData(id: string, data: {
sourceUrl?: string;
author?: string;
originalImageUrl?: string;
}): Promise<Article | undefined>;
// Thumbnail generation methods
updateArticleThumbnail(id: string, thumbnailPath: string): Promise<Article | undefined>;
// YouTube-style feed methods (enriched with outlet data)
listFeed(params: { cursor?: string; limit?: number; filter?: 'all' | 'people' | 'topics' | 'companies' }): Promise<{ items: (Article & { outletName: string; outletAvatar: string; category: string })[]; nextCursor?: string }>;
incrementView(id: string): Promise<void>;
// Comment system methods
getCommentsByArticle(articleId: string, params: { limit?: number; offset?: number }): Promise<{ comments: Comment[]; total: number }>;
getCommentReplies(parentId: string, params: { limit?: number; offset?: number }): Promise<{ comments: Comment[]; total: number }>;
getCommentById(id: string): Promise<Comment | undefined>;
createComment(comment: InsertComment): Promise<Comment>;
updateComment(id: string, content: string): Promise<Comment | undefined>;
deleteComment(id: string): Promise<boolean>;
// Comment reaction methods (atomic operations)
toggleCommentReaction(commentId: string, userIdentifier: string, reactionType: 'like' | 'dislike'): Promise<{ action: 'added' | 'removed' | 'changed'; reaction: CommentReaction | null }>;
getUserCommentReaction(commentId: string, userIdentifier: string): Promise<CommentReaction | undefined>;
// Bookmark methods
toggleBookmark(articleId: string, userIdentifier: string): Promise<{ action: 'added' | 'removed'; bookmark: Bookmark | null }>;
isBookmarked(articleId: string, userIdentifier: string): Promise<boolean>;
getUserBookmarks(userIdentifier: string): Promise<Bookmark[]>;
// Article stats methods
getArticleCommentCount(articleId: string): Promise<number>;
// Article deduplication methods
removeDuplicateArticles(): Promise<{ removedCount: number; details: { outletId: string; duplicatesRemoved: number }[] }>;
// Prediction Market methods
getPredictionMarketsByArticle(articleId: string, params: { limit?: number; offset?: number }): Promise<PredictionMarket[]>;
getPredictionMarketById(id: string): Promise<PredictionMarket | undefined>;
createPredictionMarket(market: InsertPredictionMarket): Promise<PredictionMarket>;
}
export class DbStorage implements IStorage {
// In-memory Maps for hybrid storage approach
private outlets = new Map<string, MediaOutlet>();
private users = new Map<string, User>();
private articles = new Map<string, Article>();
private comments = new Map<string, Comment>();
private commentReactions = new Map<string, CommentReaction>();
private bookmarks = new Map<string, Bookmark>();
constructor() {
this.logDatabaseStats();
this.initializeDefaultData();
}
private async logDatabaseStats() {
try {
const outletCount = await db.select({ count: count() }).from(mediaOutlets);
const articleCount = await db.select({ count: count() }).from(articles);
console.log(`[DbStorage] Connected to database with ${outletCount[0].count} outlets and ${articleCount[0].count} articles`);
} catch (error) {
console.error('[DbStorage] Failed to connect to database:', error);
}
}
private async initializeDefaultData() {
// Initialize with new outlet structure based on requirements
const defaultOutlets = [
// People Category (4 outlets)
{
id: 'jacob-robert-steeves',
name: 'Jacob Robert Steeves',
description: 'Co-founder of Bittensor and primary architect of decentralized AI',
category: 'people',
focusSubject: 'Jacob Robert Steeves',
avatar: '/api/assets/jacob-steeves_1758526589973.png',
profileImage: '/api/assets/steeves thumbnail_1758526589975.png',
bio: 'Co-founder of Bittensor and a primary architect of its decentralized AI network.',
fullBio: [
'Co-founder of Bittensor and primary architect of the decentralized AI network protocol.',
'Visionary leader advocating for open, permissionless intelligence markets and AI democratization.',
'Technical expert directing core research in AI consensus mechanisms and protocol development.'
]
},
{
id: 'ala-shaabana',
name: 'Ala Shaabana',
description: 'Co-founder and key technical architect of Bittensor',
category: 'people',
focusSubject: 'Ala Shaabana',
avatar: '/api/assets/Ala Shaabana_1758526589971.jpeg',
profileImage: '/api/assets/ala thumbnail_1758526589972.png',
bio: 'A co-founder of Bittensor and a key technical architect of its decentralized AI network.',
fullBio: [
'Co-founder of Bittensor with a Ph.D. in Computer Science specializing in advanced AI and machine learning.',
'Primary architect of the Bittensor protocol\'s complex incentive and consensus mechanisms.',
'Known for technical precision and focus on scalability in decentralized AI network design.'
]
},
{
id: 'joseph-jacks',
name: 'Joseph Jacks',
description: 'Founder of Open Source Capital and Bittensor advocate',
category: 'people',
focusSubject: 'Joseph Jacks',
avatar: '/api/assets/Joseph Jacks_1758526589973.jpeg',
profileImage: '/api/assets/joseph thumbnail_1758526589974.png',
bio: 'Founder and General Partner of OSS Capital, a venture capital firm with a strong focus on open-source software.',
fullBio: [
'Founder and General Partner of OSS Capital, the first venture capital fund exclusively focused on commercial open-source software (COSS). Since 2018, has led over 40 funding rounds representing $200+ million in investments.',
'Entrepreneurial background includes founding Kismatic (first enterprise Kubernetes company, acquired by Apprenda), co-founding Aljabr cloud data management startup, and creating KubeCon conference now run by Linux Foundation.',
'Previously held strategic roles at Mesosphere (D2IQ), Enstratius (acquired by Dell), TIBCO Software, and Talend. Served as Entrepreneur in Residence at Quantum Corporation supporting the Rook project.',
'Visionary behind Open Core Summit, the global vendor-neutral conference for the COSS ecosystem, bringing together 1,000+ attendees from 29 countries, 40+ sponsors, and 100+ speakers annually.',
'Investment portfolio includes notable successes like Remix (acquired by Shopify), OpenBB (Bloomberg Terminal alternative), and dozens of open-source alternatives to major enterprise software platforms.',
'Limited partners include tech luminaries: WordPress co-creator Matt Mullenweg, Red Hat co-founder Bob Young, YouTube founders Chad Hurley and Steve Chen, GitHub co-founder Tom Preston-Werner, and Shopify founder Tobias Lütke.',
'Core investment philosophy: "Open source is eating software faster than software is eating the world" - believes open core approach will replace closed core SaaS companies entirely.',
'Serves on boards of multiple portfolio companies including Plane, OpenBB, DeSci Labs, and Liquid AI, actively guiding the next generation of open-source commercial enterprises.'
]
},
{
id: 'robert-myers',
name: 'Robert Myers',
description: 'CEO of Manifold Labs and former Opentensor Foundation co-founder',
category: 'people',
focusSubject: 'Robert Myers',
avatar: '/api/assets/Robert Myers_1758526589974.jpg',
profileImage: '/api/assets/robert thumbnail_1758526589974.png',
bio: 'Co-founder and former Marketing Director of Opentensor Foundation, currently CEO of Manifold Labs.',
fullBio: [
'Co-founder and former Marketing Director of Opentensor Foundation behind Bittensor.',
'Current CEO of Manifold Labs, AI infrastructure company funded by OSS Capital.',
'Focus on building critical tools and infrastructure for decentralized AI networks.'
]
},
// Topics Category (3 outlets)
{
id: 'alt-coin',
name: 'Alt Coin',
description: 'Coverage of alternative cryptocurrencies and emerging tokens',
category: 'topics',
focusSubject: 'Alt Coin',
avatar: '/api/assets/altcoin_1758526589973.jpeg',
profileImage: '/api/assets/alt coin news_1758526589972.png',
bio: 'A term for any cryptocurrency other than Bitcoin (BTC).',
fullBio: [
'Any cryptocurrency other than Bitcoin, built to solve problems like scalability, privacy, or smart contracts.',
'Highly volatile and speculative market with potential for massive gains and significant losses.',
'Success depends on community strength, network utility, and technological innovation.'
]
},
{
id: 'stable-coin',
name: 'Stable Coin',
description: 'Analysis of stablecoins and price-stable digital assets',
category: 'topics',
focusSubject: 'Stable Coin',
avatar: '/api/assets/stable coin_1758526589975.jpeg',
profileImage: '/api/assets/stable coin news_1758526589975.png',
bio: 'A class of cryptocurrencies designed to minimize price volatility, often pegged to a fiat currency like the US Dollar.',
fullBio: [
'Cryptocurrency designed to minimize price volatility, usually pegged to fiat currencies like USD.',
'Collateralized by fiat, other cryptocurrencies, or algorithmic mechanisms to maintain price stability.',
'Essential for cross-border transactions and DeFi by providing stable store of value.'
]
},
{
id: 'bittensor',
name: 'Bittensor',
description: 'Comprehensive coverage of the Bittensor network and ecosystem',
category: 'topics',
focusSubject: 'Bittensor',
avatar: '/api/assets/Bittensor_1758526589973.jpg',
profileImage: '/api/assets/Bittensor_1758526589973.jpg',
bio: 'A decentralized blockchain network focused on creating a global, open marketplace for artificial intelligence.',
fullBio: [
'Decentralized blockchain network creating a global marketplace for artificial intelligence.',
'Uses "Yuma Consensus" mechanism and specialized "Subnets" for AI tasks like language processing.',
'Native TAO token incentivizes participation and democratizes AI away from centralized corporate control.'
]
},
{
id: 'dat',
name: 'DAT',
description: 'Digital Asset Treasury strategies and corporate cryptocurrency adoption',
category: 'topics',
focusSubject: 'DAT',
avatar: '/api/assets/dat_default.jpeg',
profileImage: '/api/assets/dat_news_default.png',
bio: 'Digital Asset Treasury strategies helping corporations integrate cryptocurrency into their treasury management.',
fullBio: [
'Digital Asset Treasury strategies transforming corporate treasury management through cryptocurrency integration.',
'Comprehensive framework for institutional digital asset adoption including custody, compliance, and risk management.',
'Leading the transition from traditional corporate treasuries to multi-asset digital strategies.'
]
},
// Additional Topics Category outlets
{
id: 'blockchain',
name: 'Blockchain',
description: 'Comprehensive blockchain technology news and analysis',
category: 'topics',
focusSubject: 'Blockchain',
avatar: '/api/assets/blockchain_1758526589973.jpeg',
profileImage: '/api/assets/blockchain_news_1758526589972.png',
bio: 'The foundational technology behind cryptocurrencies and decentralized applications.',
fullBio: [
'Distributed ledger technology that maintains a continuously growing list of records.',
'Enables trustless transactions and smart contracts without central authority.',
'Revolutionary technology transforming finance, supply chain, and digital identity.'
]
},
{
id: 'defi',
name: 'DeFi',
description: 'Decentralized Finance protocols and innovations',
category: 'topics',
focusSubject: 'DeFi',
avatar: '/api/assets/defi_1758526589973.jpeg',
profileImage: '/api/assets/defi_news_1758526589972.png',
bio: 'Decentralized Financial services built on blockchain technology.',
fullBio: [
'Financial services using smart contracts instead of traditional intermediaries.',
'Includes lending, borrowing, trading, and yield farming protocols.',
'Democratizes access to financial services globally without traditional barriers.'
]
},
{
id: 'nft',
name: 'NFT',
description: 'Non-Fungible Tokens and digital collectibles market',
category: 'topics',
focusSubject: 'NFT',
avatar: '/api/assets/nft_1758526589973.jpeg',
profileImage: '/api/assets/nft_news_1758526589972.png',
bio: 'Unique digital assets representing ownership of digital or physical items.',
fullBio: [
'Non-fungible tokens that represent unique ownership of digital assets.',
'Revolutionizing art, gaming, music, and digital collectibles markets.',
'Enables creators to monetize digital content with verified scarcity.'
]
},
{
id: 'dao',
name: 'DAO',
description: 'Decentralized Autonomous Organizations and governance',
category: 'topics',
focusSubject: 'DAO',
avatar: '/api/assets/dao_1758526589973.jpeg',
profileImage: '/api/assets/dao_news_1758526589972.png',
bio: 'Organizations governed by smart contracts and community voting.',
fullBio: [
'Organizations governed entirely by smart contracts and token holder voting.',
'Enables transparent, democratic decision-making without traditional management.',
'Revolutionary organizational structure for the decentralized economy.'
]
},
{
id: 'metaverse',
name: 'Metaverse',
description: 'Virtual worlds and immersive digital experiences',
category: 'topics',
focusSubject: 'Metaverse',
avatar: '/api/assets/metaverse_1758526589973.jpeg',
profileImage: '/api/assets/metaverse_news_1758526589972.png',
bio: 'Persistent virtual worlds where users interact in immersive digital environments.',
fullBio: [
'Persistent virtual worlds enabling social interaction and economic activity.',
'Combines VR, AR, blockchain, and AI to create immersive digital experiences.',
'The future of social media, gaming, and digital commerce.'
]
},
{
id: 'ai-crypto',
name: 'AI Crypto',
description: 'Artificial Intelligence and cryptocurrency convergence',
category: 'topics',
focusSubject: 'AI Crypto',
avatar: '/api/assets/ai_crypto_1758526589973.jpeg',
profileImage: '/api/assets/ai_crypto_news_1758526589972.png',
bio: 'The intersection of artificial intelligence and cryptocurrency technologies.',
fullBio: [
'Intersection of artificial intelligence and cryptocurrency technologies.',
'AI-powered trading, predictive analytics, and automated market making.',
'Decentralized AI networks incentivized by cryptocurrency tokens.'
]
},
{
id: 'layer2',
name: 'Layer 2',
description: 'Blockchain scaling solutions and second-layer protocols',
category: 'topics',
focusSubject: 'Layer 2',
avatar: '/api/assets/layer2_1758526589973.jpeg',
profileImage: '/api/assets/layer2_news_1758526589972.png',
bio: 'Scaling solutions built on top of existing blockchain networks.',
fullBio: [
'Scaling solutions that process transactions off the main blockchain.',
'Reduces fees and increases transaction throughput significantly.',
'Critical infrastructure for blockchain mass adoption and usability.'
]
},
{
id: 'privacy-coins',
name: 'Privacy Coins',
description: 'Privacy-focused cryptocurrencies and anonymous transactions',
category: 'topics',
focusSubject: 'Privacy Coins',
avatar: '/api/assets/privacy_coins_1758526589973.jpeg',
profileImage: '/api/assets/privacy_coins_news_1758526589972.png',
bio: 'Cryptocurrencies designed to provide enhanced privacy and anonymity.',
fullBio: [
'Cryptocurrencies using advanced cryptography to ensure transaction privacy.',
'Protects user financial privacy from surveillance and data mining.',
'Essential for financial freedom and protection of personal information.'
]
},
{
id: 'gamefi',
name: 'GameFi',
description: 'Gaming and decentralized finance integration',
category: 'topics',
focusSubject: 'GameFi',
avatar: '/api/assets/gamefi_1758526589973.jpeg',
profileImage: '/api/assets/gamefi_news_1758526589972.png',
bio: 'Games that integrate DeFi elements and play-to-earn mechanics.',
fullBio: [
'Games that integrate DeFi elements and blockchain-based ownership.',
'Players earn cryptocurrency rewards for gameplay and participation.',
'Revolutionizing gaming economics through true digital asset ownership.'
]
},
{
id: 'socialfi',
name: 'SocialFi',
description: 'Social media platforms with financial incentives',
category: 'topics',
focusSubject: 'SocialFi',
avatar: '/api/assets/socialfi_1758526589973.jpeg',
profileImage: '/api/assets/socialfi_news_1758526589972.png',
bio: 'Social media platforms that reward users with cryptocurrency.',
fullBio: [
'Social media platforms that reward content creation and engagement.',
'Users earn tokens for creating quality content and building communities.',
'Aligns incentives between platforms, creators, and audiences.'
]
},
{
id: 'cbdc',
name: 'CBDC',
description: 'Central Bank Digital Currencies and government crypto',
category: 'topics',
focusSubject: 'CBDC',
avatar: '/api/assets/cbdc_1758526589973.jpeg',
profileImage: '/api/assets/cbdc_news_1758526589972.png',
bio: 'Digital versions of national currencies issued by central banks.',
fullBio: [
'Digital versions of fiat currencies issued and controlled by central banks.',
'Combines benefits of digital payments with government backing.',
'Represents governments adoption of blockchain technology for monetary policy.'
]
},
{
id: 'cross-chain',
name: 'Cross-Chain',
description: 'Blockchain interoperability and cross-chain protocols',
category: 'topics',
focusSubject: 'Cross-Chain',
avatar: '/api/assets/cross_chain_1758526589973.jpeg',
profileImage: '/api/assets/cross_chain_news_1758526589972.png',
bio: 'Technologies enabling communication and value transfer between different blockchains.',
fullBio: [
'Technologies enabling communication between different blockchain networks.',
'Allows assets and data to move freely across multiple chains.',
'Critical for blockchain ecosystem maturity and user experience.'
]
},
{
id: 'yield-farming',
name: 'Yield Farming',
description: 'DeFi yield generation strategies and liquidity mining',
category: 'topics',
focusSubject: 'Yield Farming',
avatar: '/api/assets/yield_farming_1758526589973.jpeg',
profileImage: '/api/assets/yield_farming_news_1758526589972.png',
bio: 'Strategies to maximize returns by providing liquidity to DeFi protocols.',
fullBio: [
'Strategies to maximize returns by providing liquidity to DeFi protocols.',
'Users lend or stake tokens to earn high yields and bonus rewards.',
'Core economic activity driving DeFi protocol growth and adoption.'
]
},
{
id: 'tokenomics',
name: 'Tokenomics',
description: 'Cryptocurrency token economics and design principles',
category: 'topics',
focusSubject: 'Tokenomics',
avatar: '/api/assets/tokenomics_1758526589973.jpeg',
profileImage: '/api/assets/tokenomics_news_1758526589972.png',
bio: 'The economic design and incentive structures of cryptocurrency tokens.',
fullBio: [
'Economic design and incentive structures behind cryptocurrency tokens.',
'Determines how tokens are distributed, used, and valued over time.',
'Critical factor in the long-term success of blockchain projects.'
]
},
{
id: 'regulation',
name: 'Regulation',
description: 'Cryptocurrency regulation and government policy',
category: 'topics',
focusSubject: 'Regulation',
avatar: '/api/assets/regulation_1758526589973.jpeg',
profileImage: '/api/assets/regulation_news_1758526589972.png',
bio: 'Government policies and regulations affecting the cryptocurrency industry.',
fullBio: [
'Government policies and regulations shaping the cryptocurrency industry.',
'Balances innovation, consumer protection, and financial stability.',
'Critical factor determining mainstream adoption and institutional investment.'
]
},
{
id: 'mining',
name: 'Mining',
description: 'Cryptocurrency mining and proof-of-work consensus',
category: 'topics',
focusSubject: 'Mining',
avatar: '/api/assets/mining_1758526589973.jpeg',
profileImage: '/api/assets/mining_news_1758526589972.png',
bio: 'The process of validating transactions and securing blockchain networks.',
fullBio: [
'Process of validating transactions and securing proof-of-work blockchains.',
'Miners compete to solve cryptographic puzzles for block rewards.',
'Essential infrastructure maintaining decentralization and network security.'
]
},
{
id: 'staking',
name: 'Staking',
description: 'Proof-of-stake validation and staking rewards',
category: 'topics',
focusSubject: 'Staking',
avatar: '/api/assets/staking_1758526589973.jpeg',
profileImage: '/api/assets/staking_news_1758526589972.png',
bio: 'Locking tokens to help secure proof-of-stake networks and earn rewards.',
fullBio: [
'Locking tokens to help validate transactions on proof-of-stake networks.',
'More energy-efficient alternative to proof-of-work mining.',
'Allows token holders to earn passive income while securing networks.'
]
},
{
id: 'institutional',
name: 'Institutional',
description: 'Institutional cryptocurrency adoption and investment',
category: 'topics',
focusSubject: 'Institutional',
avatar: '/api/assets/institutional_1758526589973.jpeg',
profileImage: '/api/assets/institutional_news_1758526589972.png',
bio: 'Large institutions and corporations adopting cryptocurrency.',
fullBio: [
'Large institutions and corporations adopting cryptocurrency investments.',
'Banks, hedge funds, and public companies adding crypto to portfolios.',
'Driving mainstream adoption and market maturation.'
]
},
{
id: 'derivatives',
name: 'Derivatives',
description: 'Cryptocurrency derivatives and financial instruments',
category: 'topics',
focusSubject: 'Derivatives',
avatar: '/api/assets/derivatives_1758526589973.jpeg',
profileImage: '/api/assets/derivatives_news_1758526589972.png',
bio: 'Financial instruments derived from cryptocurrency underlying assets.',
fullBio: [
'Financial instruments like futures, options, and swaps on cryptocurrencies.',
'Enables sophisticated trading strategies and risk management.',
'Critical infrastructure for institutional participation in crypto markets.'
]
},
// Additional People Category outlets
{
id: 'vitalik-buterin',
name: 'Vitalik Buterin',
description: 'Ethereum founder and blockchain visionary',
category: 'people',
focusSubject: 'Vitalik Buterin',
avatar: '/api/assets/vitalik_1758526589973.jpeg',
profileImage: '/api/assets/vitalik_news_1758526589972.png',
bio: 'Co-founder of Ethereum and one of the most influential figures in blockchain.',
fullBio: [
'Co-founder of Ethereum, the worlds second-largest cryptocurrency platform.',
'Visionary programmer who conceptualized smart contracts and decentralized applications.',
'Leading voice in blockchain scalability, governance, and decentralization.'
]
},
{
id: 'satoshi-nakamoto',
name: 'Satoshi Nakamoto',
description: 'Anonymous creator of Bitcoin and blockchain technology',
category: 'people',
focusSubject: 'Satoshi Nakamoto',
avatar: '/api/assets/satoshi_1758526589973.jpeg',
profileImage: '/api/assets/satoshi_news_1758526589972.png',
bio: 'Pseudonymous creator of Bitcoin, the first and most famous cryptocurrency.',
fullBio: [
'Pseudonymous creator of Bitcoin and inventor of blockchain technology.',
'Published the Bitcoin whitepaper in 2008, launching the cryptocurrency revolution.',
'Mysterious figure who disappeared from public view in 2011.'
]
},
{
id: 'changpeng-zhao',
name: 'Changpeng Zhao',
description: 'Former CEO of Binance and crypto exchange pioneer',
category: 'people',
focusSubject: 'Changpeng Zhao',
avatar: '/api/assets/cz_1758526589973.jpeg',
profileImage: '/api/assets/cz_news_1758526589972.png',
bio: 'Former CEO of Binance, the worlds largest cryptocurrency exchange.',
fullBio: [
'Former CEO of Binance, building it into the worlds largest crypto exchange.',
'Pioneered many innovations in cryptocurrency trading and DeFi.',
'Influential leader in global cryptocurrency adoption and regulation.'
]
},
{
id: 'brian-armstrong',
name: 'Brian Armstrong',
description: 'CEO of Coinbase and cryptocurrency adoption advocate',
category: 'people',
focusSubject: 'Brian Armstrong',
avatar: '/api/assets/brian_armstrong_1758526589973.jpeg',
profileImage: '/api/assets/brian_armstrong_news_1758526589972.png',
bio: 'CEO and co-founder of Coinbase, the largest US cryptocurrency exchange.',
fullBio: [
'CEO and co-founder of Coinbase, Americas leading cryptocurrency platform.',
'Advocate for clear cryptocurrency regulation and mainstream adoption.',
'Leading voice in bringing cryptocurrency to traditional financial institutions.'
]
},
{
id: 'andreas-antonopoulos',
name: 'Andreas Antonopoulos',
description: 'Bitcoin educator and blockchain technology advocate',
category: 'people',
focusSubject: 'Andreas Antonopoulos',
avatar: '/api/assets/andreas_1758526589973.jpeg',
profileImage: '/api/assets/andreas_news_1758526589972.png',
bio: 'Renowned Bitcoin educator and author of "Mastering Bitcoin."',
fullBio: [
'Renowned Bitcoin educator and author of "Mastering Bitcoin" and "Mastering Ethereum."',
'Passionate advocate for decentralization and financial sovereignty.',
'Influential speaker educating millions about cryptocurrency technology.'
]
},
{
id: 'michael-saylor',
name: 'Michael Saylor',
description: 'MicroStrategy CEO and Bitcoin maximalist',
category: 'people',
focusSubject: 'Michael Saylor',
avatar: '/api/assets/saylor_1758526589973.jpeg',
profileImage: '/api/assets/saylor_news_1758526589972.png',
bio: 'CEO of MicroStrategy and prominent Bitcoin advocate.',
fullBio: [
'Born February 4, 1965 in military family, graduated first in class from high school, earned full ROTC scholarship to MIT where he double-majored in aeronautical engineering and history of science, graduating with highest honors in 1987.',
'Founded MicroStrategy in 1989 with MIT fraternity brother Sanju Bansal, initially focused on business intelligence software. Won $10 million McDonald\'s contract in 1992, took company public in 1998.',
'Survived dot-com crash devastation when stock plummeted from $333 to $120 in single day (March 2000). Paid $350,000 SEC penalty plus $8.3 million disgorgement for financial reporting issues.',
'Prolific inventor holding 48+ patents, credited as inventor of relational analytics. Founded multiple companies including Alarm.com (NASDAQ: ALRM) and Angel.com (sold for $110M).',
'Author of "The Mobile Wave" (NYT/WSJ bestseller), founded Saylor Academy providing free education to 1.8+ million students. MIT Technology Review "Innovator Under 35" (1999).',
'Executive Chairman of MicroStrategy since 2022, previously CEO for 33 years. Led corporate Bitcoin adoption strategy purchasing 639,835+ bitcoins worth billions, making MSTR largest corporate Bitcoin holder.',
'Bitcoin maximalist advocate promoting cryptocurrency as superior store of value and inflation hedge. His Bitcoin strategy transformed MicroStrategy from traditional software company to Bitcoin proxy investment vehicle.'
]
},
{
id: 'elon-musk',
name: 'Elon Musk',
description: 'Tesla CEO and influential cryptocurrency commentator',
category: 'people',
focusSubject: 'Elon Musk',
avatar: '/api/assets/elon_1758526589973.jpeg',
profileImage: '/api/assets/elon_news_1758526589972.png',
bio: 'CEO of Tesla and SpaceX, influential voice in cryptocurrency markets.',
fullBio: [
'World\'s wealthiest person (net worth $384-$487 billion as of 2025), born June 28, 1971 in Pretoria, South Africa. Emigrated to avoid apartheid military service, studied at Queen\'s University and University of Pennsylvania (Economics + Physics degrees).',
'Early entrepreneur: Created and sold video game at age 12, co-founded Zip2 (sold for $307M), then X.com which merged to become PayPal (sold to eBay for $1.5B, Musk received $176M).',
'Founded SpaceX in 2002 with vision of Mars colonization, now leading private space company. First private company to send astronauts to ISS (2020), pioneered reusable rockets, operates Starlink satellite constellation.',
'CEO of Tesla since 2008, driving global electric vehicle revolution. Transformed company from startup to world\'s most valuable automaker with Model S, 3, X lineup and autonomous driving technology.',
'Acquired Twitter for $44 billion in 2022, rebranded to X as part of vision for "everything app." Also founded Neuralink (brain-machine interfaces), The Boring Company (tunnel infrastructure), and xAI (AI competitor to ChatGPT).',
'Briefly served as co-head of Department of Government Efficiency (DOGE) under Trump administration (January-May 2025) before returning focus to business ventures.',
'Known for 80-hour work weeks, visionary leadership in sustainable transport, space exploration, and artificial intelligence. His social media presence significantly impacts cryptocurrency and stock markets globally.'
]
},
{
id: 'gavin-wood',
name: 'Gavin Wood',
description: 'Polkadot founder and Ethereum co-founder',
category: 'people',
focusSubject: 'Gavin Wood',
avatar: '/api/assets/gavin_wood_1758526589973.jpeg',
profileImage: '/api/assets/gavin_wood_news_1758526589972.png',
bio: 'Co-founder of Ethereum and founder of Polkadot blockchain.',
fullBio: [
'Co-founder of Ethereum and creator of the Solidity programming language.',
'Founder of Polkadot, pioneering blockchain interoperability solutions.',
'Visionary technologist advancing multi-chain blockchain ecosystem.'
]
},
{
id: 'charles-hoskinson',
name: 'Charles Hoskinson',
description: 'Cardano founder and blockchain researcher',
category: 'people',
focusSubject: 'Charles Hoskinson',
avatar: '/api/assets/charles_1758526589973.jpeg',
profileImage: '/api/assets/charles_news_1758526589972.png',
bio: 'Founder of Cardano and co-founder of Ethereum.',
fullBio: [
'Founder of Cardano blockchain and co-founder of Ethereum.',
'Academic approach to blockchain development with peer-reviewed research.',
'Advocate for formal verification and scientific methodology in crypto.'
]
},
{
id: 'sergey-nazarov',
name: 'Sergey Nazarov',
description: 'Chainlink co-founder and oracle technology pioneer',
category: 'people',
focusSubject: 'Sergey Nazarov',
avatar: '/api/assets/sergey_1758526589973.jpeg',
profileImage: '/api/assets/sergey_news_1758526589972.png',
bio: 'Co-founder of Chainlink, the leading blockchain oracle network.',
fullBio: [
'Co-founder of Chainlink, providing real-world data to smart contracts.',
'Pioneer in blockchain oracle technology and decentralized data feeds.',
'Enabling smart contracts to interact with external data and systems.'
]
},
{
id: 'arthur-hayes',
name: 'Arthur Hayes',
description: 'Former BitMEX CEO and crypto derivatives pioneer',
category: 'people',
focusSubject: 'Arthur Hayes',
avatar: '/api/assets/arthur_hayes_1758526589973.jpeg',
profileImage: '/api/assets/arthur_hayes_news_1758526589972.png',
bio: 'Former CEO of BitMEX and pioneer in cryptocurrency derivatives.',
fullBio: [
'Former CEO of BitMEX, pioneering cryptocurrency derivatives trading.',
'Influential voice in crypto markets and monetary policy analysis.',
'Advocate for Bitcoin as alternative to traditional financial systems.'
]
},
{
id: 'elizabeth-stark',
name: 'Elizabeth Stark',
description: 'Lightning Labs CEO and Bitcoin Lightning Network advocate',
category: 'people',
focusSubject: 'Elizabeth Stark',
avatar: '/api/assets/elizabeth_stark_1758526589973.jpeg',
profileImage: '/api/assets/elizabeth_stark_news_1758526589972.png',
bio: 'CEO of Lightning Labs, developing Bitcoin Lightning Network scaling.',
fullBio: [
'CEO of Lightning Labs, building Bitcoin Lightning Network infrastructure.',
'Advocate for Bitcoin scalability and instant payment solutions.',
'Pioneer in layer-2 blockchain scaling technology and Bitcoin innovation.'
]
},
{
id: 'cathie-wood',
name: 'Cathie Wood',
description: 'ARK Invest CEO and innovation investor',
category: 'people',
focusSubject: 'Cathie Wood',
avatar: '/api/assets/cathie_wood_1758526589973.jpeg',
profileImage: '/api/assets/cathie_wood_news_1758526589972.png',
bio: 'CEO of ARK Invest, prominent investor in disruptive technologies.',
fullBio: [
'CEO of ARK Invest, focusing on disruptive innovation investments.',
'Strong advocate for Bitcoin and cryptocurrency adoption.',
'Influential voice connecting traditional investing with crypto markets.'
]
},
{
id: 'jack-dorsey',
name: 'Jack Dorsey',
description: 'Former Twitter CEO and Bitcoin advocate',
category: 'people',
focusSubject: 'Jack Dorsey',
avatar: '/api/assets/jack_dorsey_1758526589973.jpeg',
profileImage: '/api/assets/jack_dorsey_news_1758526589972.png',
bio: 'Former CEO of Twitter and Square, passionate Bitcoin advocate.',
fullBio: [
'Former CEO of Twitter and Square, passionate about Bitcoin adoption.',
'Building decentralized social media and Bitcoin infrastructure.',
'Advocate for Bitcoin as tool for global financial inclusion.'
]
},
{
id: 'dan-larimer',
name: 'Dan Larimer',
description: 'Blockchain developer and EOS creator',
category: 'people',
focusSubject: 'Dan Larimer',
avatar: '/api/assets/dan_larimer_1758526589973.jpeg',
profileImage: '/api/assets/dan_larimer_news_1758526589972.png',
bio: 'Creator of EOS, Steemit, and BitShares blockchain platforms.',
fullBio: [
'Creator of multiple blockchain platforms including EOS and BitShares.',
'Pioneer in delegated proof-of-stake consensus mechanisms.',
'Innovative developer focused on blockchain scalability and user experience.'
]
},
{
id: 'cameron-winklevoss',
name: 'Cameron Winklevoss',
description: 'Gemini co-founder and crypto entrepreneur',
category: 'people',
focusSubject: 'Cameron Winklevoss',
avatar: '/api/assets/cameron_1758526589973.jpeg',
profileImage: '/api/assets/cameron_news_1758526589972.png',
bio: 'Co-founder of Gemini cryptocurrency exchange.',
fullBio: [
'Co-founder of Gemini cryptocurrency exchange with twin brother Tyler.',
'Early Bitcoin investor and advocate for cryptocurrency regulation.',
'Entrepreneur bridging traditional finance with digital assets.'
]
},
{
id: 'tyler-winklevoss',
name: 'Tyler Winklevoss',
description: 'Gemini co-founder and digital asset advocate',
category: 'people',
focusSubject: 'Tyler Winklevoss',
avatar: '/api/assets/tyler_1758526589973.jpeg',
profileImage: '/api/assets/tyler_news_1758526589972.png',
bio: 'Co-founder of Gemini cryptocurrency exchange.',
fullBio: [
'Co-founder of Gemini cryptocurrency exchange with twin brother Cameron.',
'Pioneer in cryptocurrency compliance and regulatory engagement.',
'Advocate for institutional-grade cryptocurrency infrastructure.'
]
},
{
id: 'roger-ver',
name: 'Roger Ver',
description: 'Bitcoin Cash advocate and early Bitcoin investor',
category: 'people',
focusSubject: 'Roger Ver',
avatar: '/api/assets/roger_ver_1758526589973.jpeg',
profileImage: '/api/assets/roger_ver_news_1758526589972.png',
bio: 'Early Bitcoin investor and advocate, known as "Bitcoin Jesus."',
fullBio: [
'Early Bitcoin investor and evangelist, known as "Bitcoin Jesus."',
'Prominent advocate for Bitcoin Cash and cryptocurrency adoption.',
'Entrepreneur focused on peer-to-peer electronic cash systems.'
]
},
{
id: 'palmer-luckey',
name: 'Palmer Luckey',
description: 'Oculus VR founder and Anduril Industries CEO, pioneering VR/AR and defense tech',
category: 'people',
focusSubject: 'Palmer Luckey',
avatar: '/api/assets/palmer_luckey_1758526589973.jpeg',
profileImage: '/api/assets/palmer_luckey_profile_1758526589973.jpeg',
bio: 'Founder of Oculus VR and current CEO of Anduril Industries, pioneering virtual reality and defense technology.',
fullBio: [
'Founded Oculus VR at age 20, revolutionizing virtual reality technology before selling to Facebook for $2 billion.',
'Currently CEO of Anduril Industries, developing AI-powered defense systems and autonomous weapons platforms.',
'Visionary entrepreneur bridging gaming technology, military applications, and next-generation computing interfaces.'
]
},
{
id: 'mike-novogratz',
name: 'Mike Novogratz',
description: 'CEO of Galaxy Digital and crypto investment pioneer',
category: 'people',
focusSubject: 'Mike Novogratz',
avatar: '/api/assets/mike novogratz_1759136098707.jpg',
profileImage: '/api/assets/mike novogratz_1759136098707.jpg',
bio: 'CEO and founder of Galaxy Digital, a leading cryptocurrency investment firm.',
fullBio: [
'CEO and founder of Galaxy Digital, one of the largest cryptocurrency investment firms.',
'Former Goldman Sachs partner and Fortress Investment Group principal with 20+ years Wall Street experience.',
'Early Bitcoin advocate and institutional crypto adoption pioneer, managing billions in digital assets.'
]
},
{
id: 'michael-j-saylor',
name: 'Michael J. Saylor',
description: 'MicroStrategy CEO and Bitcoin maximalist',
category: 'people',
focusSubject: 'Michael J. Saylor',
avatar: '/api/assets/michael j. saylor_1759136096272.jpg',
profileImage: '/api/assets/michael j. saylor_1759136096272.jpg',
bio: 'CEO of MicroStrategy and leading advocate for Bitcoin as a treasury reserve asset.',
fullBio: [
'CEO of MicroStrategy, the first major corporation to adopt Bitcoin as primary treasury reserve asset.',
'Led MicroStrategy to purchase over $5 billion worth of Bitcoin, pioneering corporate crypto adoption.',
'Prominent Bitcoin maximalist and advocate for digital asset treasury strategies among corporations.'
]
},
// Companies Category (additional outlets)
{
id: 'coinbase',
name: 'Coinbase',
description: 'Leading cryptocurrency exchange and platform',
category: 'companies',
focusSubject: 'Coinbase',
avatar: '/api/assets/coinbase_1758526589973.jpeg',
profileImage: '/api/assets/coinbase_news_1758526589972.png',
bio: 'Leading cryptocurrency exchange and platform in the United States.',
fullBio: [
'Largest cryptocurrency exchange in the United States, publicly traded.',
'Provides easy-to-use platform for buying, selling, and storing cryptocurrencies.',
'Pioneer in regulatory compliance and institutional cryptocurrency services.'
]
},
{
id: 'binance',
name: 'Binance',
description: 'Worlds largest cryptocurrency exchange by volume',
category: 'companies',
focusSubject: 'Binance',
avatar: '/api/assets/binance_1758526589973.jpeg',
profileImage: '/api/assets/binance_news_1758526589972.png',
bio: 'The worlds largest cryptocurrency exchange by trading volume.',
fullBio: [
'Worlds largest cryptocurrency exchange by trading volume and users.',
'Comprehensive ecosystem including spot trading, futures, staking, and DeFi.',
'Global platform serving millions of users in over 100 countries.'
]
},
{
id: 'galaxy-digital',
name: 'Galaxy Digital',
description: 'Leading cryptocurrency investment and trading firm',
category: 'companies',
focusSubject: 'Galaxy Digital',
avatar: '/api/assets/galaxy_1759136096271.jpeg',
profileImage: '/api/assets/galaxy_1759136096271.jpeg',
bio: 'Leading cryptocurrency investment firm and digital asset merchant bank.',
fullBio: [
'Leading cryptocurrency investment firm and digital asset merchant bank founded by Mike Novogratz.',
'Provides institutional-grade cryptocurrency trading, investment management, and advisory services.',
'Publicly traded company (TSX: GLXY) serving institutions and high-net-worth investors in digital assets.'
]
},
{
id: 'microstrategy',
name: 'MicroStrategy',
description: 'Business intelligence company with major Bitcoin holdings',
category: 'companies',
focusSubject: 'MicroStrategy',
avatar: '/api/assets/microstrategy_1759136096272.webp',
profileImage: '/api/assets/microstrategy_1759136096272.webp',
bio: 'Business intelligence company with one of the largest corporate Bitcoin treasuries.',
fullBio: [
'Business intelligence software company with massive Bitcoin treasury.',
'First major corporation to adopt Bitcoin as primary reserve asset.',
'Pioneer in corporate Bitcoin adoption and treasury diversification strategy.'
]
},
{
id: 'tesla',
name: 'Tesla',
description: 'Electric vehicle company with cryptocurrency investments',
category: 'companies',
focusSubject: 'Tesla',
avatar: '/api/assets/tesla_1758526589973.jpeg',
profileImage: '/api/assets/tesla_news_1758526589972.png',
bio: 'Electric vehicle manufacturer with significant cryptocurrency holdings.',
fullBio: [
'Electric vehicle and clean energy company with Bitcoin investments.',
'Pioneered corporate cryptocurrency adoption and payment acceptance.',
'Leading voice in sustainable Bitcoin mining and renewable energy.'
]
},
{
id: 'paypal',
name: 'PayPal',
description: 'Digital payments company offering cryptocurrency services',
category: 'companies',
focusSubject: 'PayPal',
avatar: '/api/assets/paypal_1758526589973.jpeg',
profileImage: '/api/assets/paypal_news_1758526589972.png',
bio: 'Digital payments company providing cryptocurrency buying and selling services.',
fullBio: [
'Global digital payments leader offering cryptocurrency services.',
'Enables millions of users to buy, sell, and hold cryptocurrencies.',
'Bridging traditional payments with digital asset adoption.'
]
},
{
id: 'square',
name: 'Square',
description: 'Financial services company with Bitcoin integration',
category: 'companies',
focusSubject: 'Square',
avatar: '/api/assets/square_1758526589973.jpeg',
profileImage: '/api/assets/square_news_1758526589972.png',
bio: 'Financial services and mobile payment company with Bitcoin integration.',
fullBio: [
'Financial services company integrating Bitcoin into payment solutions.',
'Cash App provides easy Bitcoin buying and selling for consumers.',
'Advocate for Bitcoin adoption and Lightning Network development.'
]
},
{
id: 'grayscale',
name: 'Grayscale',
description: 'Digital asset investment management company',
category: 'companies',
focusSubject: 'Grayscale',
avatar: '/api/assets/grayscale_1758526589973.jpeg',
profileImage: '/api/assets/grayscale_news_1758526589972.png',
bio: 'Leading digital asset investment management company.',
fullBio: [
'Leading digital asset investment manager with billions under management.',
'Provides institutional and accredited investor access to cryptocurrencies.',
'Pioneer in cryptocurrency investment products and regulatory compliance.'
]
},
{
id: 'chainlink',
name: 'Chainlink',
description: 'Decentralized oracle network connecting blockchains to real world',
category: 'companies',
focusSubject: 'Chainlink',
avatar: '/api/assets/chainlink_1758526589973.jpeg',
profileImage: '/api/assets/chainlink_news_1758526589972.png',
bio: 'Decentralized oracle network providing real-world data to smart contracts.',
fullBio: [
'Leading decentralized oracle network connecting blockchains to real-world data.',
'Enables smart contracts to securely interact with external data feeds.',
'Critical infrastructure powering DeFi and blockchain applications.'
]
},
{
id: 'ethereum-foundation',
name: 'Ethereum Foundation',
description: 'Non-profit supporting Ethereum blockchain development',
category: 'companies',
focusSubject: 'Ethereum Foundation',
avatar: '/api/assets/ethereum_foundation_1758526589973.jpeg',
profileImage: '/api/assets/ethereum_foundation_news_1758526589972.png',
bio: 'Non-profit organization supporting Ethereum blockchain development.',
fullBio: [
'Non-profit organization supporting Ethereum blockchain development and research.',
'Funds core protocol development and ecosystem growth initiatives.',
'Steward of the Ethereum networks evolution and decentralization.'
]
},
{
id: 'consensys',
name: 'ConsenSys',
description: 'Ethereum software company and blockchain infrastructure',
category: 'companies',
focusSubject: 'ConsenSys',
avatar: '/api/assets/consensys_1758526589973.jpeg',
profileImage: '/api/assets/consensys_news_1758526589972.png',
bio: 'Leading Ethereum software company building blockchain infrastructure.',
fullBio: [
'Leading Ethereum software company building decentralized applications.',
'Creates tools and infrastructure for Web3 and DeFi applications.',
'MetaMask wallet provider serving millions of Ethereum users globally.'
]
},
{
id: 'ripple',
name: 'Ripple',
description: 'Digital payment protocol for global financial institutions',
category: 'companies',
focusSubject: 'Ripple',
avatar: '/api/assets/ripple_1758526589973.jpeg',
profileImage: '/api/assets/ripple_news_1758526589972.png',
bio: 'Digital payment protocol company serving global financial institutions.',
fullBio: [
'Digital payment protocol company serving banks and financial institutions.',
'Enables fast, low-cost cross-border payments using XRP cryptocurrency.',
'Bridging traditional banking with modern blockchain payment solutions.'
]
},
{
id: 'circle',
name: 'Circle',
description: 'Financial technology company behind USDC stablecoin',
category: 'companies',
focusSubject: 'Circle',
avatar: '/api/assets/circle_1758526589973.jpeg',
profileImage: '/api/assets/circle_news_1758526589972.png',
bio: 'Financial technology company behind USDC stablecoin.',
fullBio: [
'Financial technology company issuing USDC, second-largest stablecoin.',
'Provides institutional-grade digital asset infrastructure and services.',
'Pioneer in regulated stablecoin issuance and digital dollar adoption.'
]
},
{
id: 'kraken',
name: 'Kraken',
description: 'Veteran cryptocurrency exchange and trading platform',
category: 'companies',
focusSubject: 'Kraken',
avatar: '/api/assets/kraken_1758526589973.jpeg',
profileImage: '/api/assets/kraken_news_1758526589972.png',
bio: 'Veteran cryptocurrency exchange known for security and advanced trading.',
fullBio: [
'Long-standing cryptocurrency exchange known for security and reliability.',
'Offers advanced trading features and institutional cryptocurrency services.',
'Pioneer in cryptocurrency market analysis and regulatory compliance.'
]
},
{
id: 'ftx',
name: 'FTX',
description: 'Former major cryptocurrency exchange and derivatives platform',
category: 'companies',
focusSubject: 'FTX',
avatar: '/api/assets/ftx_1758526589973.jpeg',
profileImage: '/api/assets/ftx_news_1758526589972.png',
bio: 'Former major cryptocurrency exchange that collapsed amid fraud allegations.',
fullBio: [
'Former major cryptocurrency exchange that collapsed in November 2022.',
'Once a leading platform for crypto derivatives and institutional trading.',
'Bankruptcy and fraud case serving as cautionary tale for crypto industry.'
]
},
{
id: 'alameda-research',
name: 'Alameda Research',
description: 'Former quantitative trading firm in cryptocurrency markets',
category: 'companies',
focusSubject: 'Alameda Research',
avatar: '/api/assets/alameda_1758526589973.jpeg',
profileImage: '/api/assets/alameda_news_1758526589972.png',
bio: 'Former quantitative trading firm associated with FTX collapse.',
fullBio: [
'Former quantitative cryptocurrency trading firm founded by Sam Bankman-Fried.',
'Involved in the FTX collapse and subsequent fraud investigations.',
'Case study in risk management and conflicts of interest in crypto trading.'
]
},
{
id: 'celsius',
name: 'Celsius',
description: 'Former cryptocurrency lending platform that filed for bankruptcy',
category: 'companies',
focusSubject: 'Celsius',
avatar: '/api/assets/celsius_1758526589973.jpeg',
profileImage: '/api/assets/celsius_news_1758526589972.png',
bio: 'Former cryptocurrency lending platform that filed for bankruptcy.',
fullBio: [
'Former cryptocurrency lending platform offering high yields to depositors.',
'Filed for bankruptcy in 2022 amid liquidity crisis and regulatory issues.',
'Cautionary tale about risks in unregulated cryptocurrency lending.'
]
},
{
id: 'three-arrows-capital',
name: 'Three Arrows Capital',
description: 'Former cryptocurrency hedge fund that collapsed',
category: 'companies',
focusSubject: 'Three Arrows Capital',
avatar: '/api/assets/3ac_1758526589973.jpeg',
profileImage: '/api/assets/3ac_news_1758526589972.png',
bio: 'Former prominent cryptocurrency hedge fund that collapsed in 2022.',
fullBio: [
'Former prominent cryptocurrency hedge fund managing billions in assets.',
'Collapsed in 2022 due to excessive leverage and poor risk management.',
'Bankruptcy had widespread impacts across cryptocurrency markets and DeFi.'
]
},
// Companies Category (4 outlets)
{
id: 'xtao',
name: 'xTAO',
description: 'Publicly traded infrastructure company for the Bittensor ecosystem',
category: 'companies',
focusSubject: 'xTAO',
avatar: '/api/assets/xtao_logo_1758526589976.jpg',
profileImage: '/api/assets/xTAO news_1758526589976.png',
bio: 'A publicly traded company listed on the TSX Venture Exchange, focused on building infrastructure for the Bittensor ecosystem.',
fullBio: [
'Publicly traded company on TSX Venture Exchange building infrastructure for Bittensor ecosystem.',
'High-performance validator holding significant TAO token treasury for staking and network security.',
'Provides regulated entry point for institutional investors seeking decentralized AI exposure.'
]
},
{
id: 'yuma',
name: 'YUMA',
description: 'Leading accelerator and investment firm for the Bittensor ecosystem',
category: 'companies',
focusSubject: 'YUMA',
avatar: '/api/assets/yuma_1758526589977.png',
profileImage: '/api/assets/yuma news_1758526589976.png',
bio: 'A leading accelerator and investment firm focused exclusively on the Bittensor ecosystem.',
fullBio: [
'Leading accelerator and investment firm focused exclusively on the Bittensor ecosystem.',
'Provides capital, technical resources, and community connections for building new Subnets.',
'Known for strong due diligence and nurturing successful high-performing Subnet projects.'
]
},
{
id: 'taox',
name: 'TAOX',
description: 'Public investment vehicle for Bittensor ecosystem exposure',
category: 'companies',
focusSubject: 'TAOX',
avatar: '/api/assets/taox_1758526589975.jpeg',
profileImage: '/api/assets/taox news_1758526589975.png',
bio: 'Public investment vehicle focused on providing exposure to the Bittensor ecosystem.',
fullBio: [
'Public investment vehicle focused on providing exposure to the Bittensor ecosystem.',
'Specializes in acquiring, holding, and staking TAO tokens for institutional investors.',
'Bridges conventional financial markets with decentralized AI sector opportunities.'
]
},
{
id: 'oblong',
name: 'Oblong',
description: 'Spatial computing and collaborative interface technology company',
category: 'companies',
focusSubject: 'Oblong',
avatar: '/api/assets/oblong_1758526589974.png',
profileImage: '/api/assets/oblong_1758526589974.png',
bio: 'An innovative technology company focused on spatial computing and collaborative interfaces.',
fullBio: [
'Technology company pioneering spatial computing and gesture-based collaborative interfaces.',
'Develops enterprise visualization solutions and intuitive human-computer interaction technologies.',
'Focus on immersive workspace solutions and next-generation user interface design.'
]
},
// Football Clubs - Topics Category (2 outlets)
{
id: 'manchester-city',
name: 'Manchester City F.C.',
description: 'English professional football club based in Manchester',
category: 'topics',
focusSubject: 'Manchester City',
avatar: '/api/assets/Manchester City F.C. _1759157887061.png',
profileImage: '/api/assets/Manchester City F.C. _1759157887061.png',
bio: 'English professional football club competing in the Premier League.',
fullBio: [
'One of the most successful English clubs in recent years with multiple Premier League titles.',
'Known for their attacking style of play under manager Pep Guardiola.',
'Regular competitors in UEFA Champions League with state-of-the-art training facilities.'
]
},
{
id: 'liverpool-fc',
name: 'Liverpool F.C.',
description: 'English professional football club based in Liverpool',
category: 'topics',
focusSubject: 'Liverpool',
avatar: '/api/assets/Liverpool F.C. _1759157885432.png',
profileImage: '/api/assets/Liverpool F.C. _1759157885432.png',
bio: 'English professional football club competing in the Premier League.',
fullBio: [
'One of the most successful clubs in English and European football history.',
'Known for their passionate supporters and the famous "You\'ll Never Walk Alone" anthem.',
'Six-time European Cup/Champions League winners with a rich footballing heritage.'
]
},
// Football Players - People Category (5 outlets)
{
id: 'erling-haaland',
name: 'Erling Haaland',
description: 'Norwegian professional footballer playing for Manchester City',
category: 'people',
focusSubject: 'Erling Haaland',
avatar: '/api/assets/default-player.png',
profileImage: '/api/assets/default-player.png',
bio: 'Norwegian striker for Manchester City and the Norway national team.',
fullBio: [
'Prolific goalscorer known for his speed, strength, and clinical finishing ability.',
'Record-breaking striker who has dominated every league he has played in.',
'One of the most promising young talents in world football with incredible goal-scoring records.'
]
},
{
id: 'mohamed-salah',
name: 'Mohamed Salah',
description: 'Egyptian professional footballer playing for Liverpool',
category: 'people',
focusSubject: 'Mohamed Salah',
avatar: '/api/assets/default-player.png',
profileImage: '/api/assets/default-player.png',
bio: 'Egyptian winger and forward for Liverpool and the Egypt national team.',
fullBio: [
'Prolific winger and forward known for his pace, dribbling, and goal-scoring ability.',
'Liverpool legend and one of the Premier League\'s all-time leading scorers.',
'Egyptian icon and captain of the national team with numerous individual awards.'
]
},
{
id: 'alexis-mac-allister',
name: 'Alexis Mac Allister',
description: 'Argentine professional footballer playing for Liverpool',
category: 'people',
focusSubject: 'Alexis Mac Allister',
avatar: '/api/assets/default-player.png',
profileImage: '/api/assets/default-player.png',
bio: 'Argentine central midfielder for Liverpool and the Argentina national team.',
fullBio: [
'Versatile midfielder known for his passing ability, work rate, and tactical intelligence.',
'World Cup winner with Argentina and key player in their recent international successes.',
'Adaptable player capable of playing multiple midfield roles with excellent technical skills.'
]
}
];
for (const outlet of defaultOutlets) {
const mediaOutlet: MediaOutlet = {
...outlet,
avatar: outlet.avatar || null,
profileImage: outlet.profileImage || null,
fullBio: (outlet as any).fullBio || null,
wikiProfile: null
};
this.outlets.set(outlet.id, mediaOutlet);
}
console.log(`[MemStorage] Initialized with ${defaultOutlets.length} outlets`);
// Load articles from articles_final.json
try {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const articlesPath = path.join(__dirname, '../articles_final.json');
const articlesRaw = fs.readFileSync(articlesPath, 'utf-8');
const articlesData = JSON.parse(articlesRaw);
for (const article of articlesData) {
const articleWithDate: Article = {
...article,
publishedAt: typeof article.publishedAt === 'string' ? new Date(article.publishedAt) : article.publishedAt
};
this.articles.set(article.id, articleWithDate);
}
console.log(`[MemStorage] Loaded ${this.articles.size} articles`);
} catch (error) {
console.error('[MemStorage] Failed to load articles:', error);
}
}
// User methods
async getUser(id: string): Promise<User | undefined> {
return this.users.get(id);
}
async getUserByUsername(username: string): Promise<User | undefined> {
return Array.from(this.users.values()).find(user => user.username === username);
}
async createUser(user: InsertUser): Promise<User> {
const newUser: User = {
id: randomUUID(),
...user,
avatar: user.avatar || null,
preferredLanguage: user.preferredLanguage || null
};
this.users.set(newUser.id, newUser);
return newUser;
}
// Media outlet methods
async getAllOutlets(): Promise<MediaOutlet[]> {
return Array.from(this.outlets.values()).sort((a, b) => a.name.localeCompare(b.name));
}
async getOutletsByCategory(category: string): Promise<MediaOutlet[]> {
return Array.from(this.outlets.values())
.filter(outlet => outlet.category === category)
.sort((a, b) => a.name.localeCompare(b.name));
}
async getOutletById(id: string): Promise<MediaOutlet | undefined> {
return this.outlets.get(id);
}
async createOutlet(outlet: InsertMediaOutlet): Promise<MediaOutlet> {
const newOutlet: MediaOutlet = {
id: randomUUID(),
...outlet,
avatar: outlet.avatar || null,
profileImage: outlet.profileImage || null,
fullBio: outlet.fullBio || null,
wikiProfile: outlet.wikiProfile || null
};
try {
await db.insert(mediaOutlets).values(newOutlet);
return newOutlet;
} catch (error) {
console.error('Error inserting outlet into database:', error);
throw error;
}
}
async deleteOutlet(id: string): Promise<boolean> {
try {
const result = await db.delete(mediaOutlets).where(eq(mediaOutlets.id, id));
return result.rowCount !== undefined && result.rowCount > 0;
} catch (error) {
console.error('Error deleting outlet from database:', error);
return false;
}
}
async updateOutlet(id: string, updates: Partial<InsertMediaOutlet>): Promise<MediaOutlet | undefined> {
try {
// First check if outlet exists
const existing = await db.select().from(mediaOutlets).where(eq(mediaOutlets.id, id));
if (existing.length === 0) return undefined;
// Update the outlet
const result = await db.update(mediaOutlets)
.set(updates)
.where(eq(mediaOutlets.id, id))
.returning();
return result[0] || undefined;
} catch (error) {
console.error('Error updating outlet in database:', error);
return undefined;
}
}
async mergeOutlets(fromOutletId: string, toOutletId: string): Promise<{ success: boolean; movedArticles: number }> {
const fromOutlet = this.outlets.get(fromOutletId);
const toOutlet = this.outlets.get(toOutletId);
if (!fromOutlet || !toOutlet) {
return { success: false, movedArticles: 0 };
}
// Move all articles from source outlet to target outlet
let movedArticles = 0;
for (const [articleId, article] of Array.from(this.articles.entries())) {
if (article.outletId === fromOutletId) {
this.articles.set(articleId, { ...article, outletId: toOutletId });
movedArticles++;
}
}
// Delete the source outlet
this.outlets.delete(fromOutletId);
return { success: true, movedArticles };
}
// Article methods
async getAllArticles(): Promise<Article[]> {
const result = await db.select().from(articles).orderBy(desc(articles.publishedAt));
return result;
}
async getArticlesByOutlet(outletId: string): Promise<Article[]> {
return Array.from(this.articles.values())
.filter(article => article.outletId === outletId)
.sort((a, b) => {
const dateA = typeof a.publishedAt === 'string' ? new Date(a.publishedAt) : a.publishedAt;
const dateB = typeof b.publishedAt === 'string' ? new Date(b.publishedAt) : b.publishedAt;
return dateB.getTime() - dateA.getTime();
});
}
async getArticleCountsByOutlets(): Promise<Record<string, number>> {
const counts: Record<string, number> = {};
for (const article of this.articles.values()) {
counts[article.outletId] = (counts[article.outletId] || 0) + 1;
}
return counts;
}
async getArticleById(id: string): Promise<Article | undefined> {
return this.articles.get(id);
}
async getFeaturedArticles(limit: number = 10): Promise<Article[]> {
const result = await db.select().from(articles).orderBy(desc(articles.publishedAt)).limit(limit);
return result;
}
async searchArticles(query: string): Promise<Article[]> {
const searchTerm = `%${query.toLowerCase()}%`;
const result = await db.select().from(articles)
.where(
or(
like(sql`lower(${articles.title})`, searchTerm),
like(sql`lower(${articles.summary})`, searchTerm),
like(sql`lower(${articles.body})`, searchTerm)
)
)
.orderBy(desc(articles.publishedAt));
return result;
}
async createArticle(article: InsertArticle): Promise<Article> {
const newArticle: Article = {
id: randomUUID(),
viewCount: 0,
sourceUrl: null,
author: null,
originalImageUrl: null,
scrapedAt: null,
isScraped: 0,
...article,
tags: article.tags || null
};
try {
await db.insert(articles).values(newArticle);
return newArticle;
} catch (error) {
console.error('Error inserting article into database:', error);
throw error;
}
}
async deleteArticle(id: string): Promise<boolean> {
try {
const result = await db.delete(articles).where(eq(articles.id, id));
return true;
} catch (error) {
console.error('Error deleting article from database:', error);
return false;
}
}
async createScrapedArticle(article: Omit<InsertArticle, 'id'> & {
sourceUrl: string;
author?: string;
originalImageUrl?: string;
isScraped?: number;
}): Promise<Article> {
const newArticle: Article = {
id: randomUUID(),
viewCount: 0,
scrapedAt: new Date(),
isScraped: 1,
...article,
tags: article.tags || null,
author: article.author || null,
originalImageUrl: article.originalImageUrl || null
};
this.articles.set(newArticle.id, newArticle);
return newArticle;
}
async getScrapedArticles(limit: number = 50): Promise<Article[]> {
return Array.from(this.articles.values())
.filter(article => article.isScraped === 1)
.sort((a, b) => b.publishedAt.getTime() - a.publishedAt.getTime())
.slice(0, limit);
}
async updateArticleWithScrapedData(id: string, data: {
sourceUrl?: string;
author?: string;
originalImageUrl?: string;
}): Promise<Article | undefined> {
const article = this.articles.get(id);
if (!article) return undefined;
const updatedArticle = { ...article, ...data };
this.articles.set(id, updatedArticle);
return updatedArticle;
}
async updateArticleThumbnail(id: string, thumbnail: string): Promise<Article | undefined> {
try {
const result = await db
.update(articles)
.set({ thumbnail })
.where(eq(articles.id, id))
.returning();
return result[0] || undefined;
} catch (error) {
console.error('Error updating article thumbnail in database:', error);
return undefined;
}
}
async listFeed(params: { cursor?: string; limit?: number; filter?: 'all' | 'people' | 'topics' | 'companies' }): Promise<{ items: (Article & { outletName: string; outletAvatar: string; category: string })[]; nextCursor?: string }> {
try {
const limit = params.limit || 20;
// Query from database with joins
let query = db
.select({
article: articles,
outlet: mediaOutlets
})
.from(articles)
.leftJoin(mediaOutlets, eq(articles.outletId, mediaOutlets.id))
.orderBy(desc(articles.publishedAt));
// Apply filter if specified
if (params.filter && params.filter !== 'all') {
query = query.where(eq(mediaOutlets.category, params.filter)) as any;
}
// Execute query with limit + 1 to check for next page
const results = await query.limit(limit + 1);
// Apply cursor pagination if provided
let filteredResults = results;
if (params.cursor) {
const cursorIndex = results.findIndex(r => r.article.id === params.cursor);
if (cursorIndex !== -1) {
filteredResults = results.slice(cursorIndex + 1);
}
}
const hasNext = filteredResults.length > limit;
const items = filteredResults.slice(0, limit);
// Enrich with outlet data
const enrichedItems = items.map(({ article, outlet }) => ({
...article,
outletName: outlet?.name || 'Unknown Outlet',
outletAvatar: outlet?.avatar || '',
category: outlet?.category || 'unknown'
}));
const nextCursor = hasNext ? enrichedItems[enrichedItems.length - 1]?.id : undefined;
return { items: enrichedItems, nextCursor };
} catch (error) {
console.error('[DbStorage] Error in listFeed:', error);
return { items: [] };
}
}
async incrementView(id: string): Promise<void> {
const article = this.articles.get(id);
if (article) {
const currentViewCount = article.viewCount || 0;
const updatedArticle = {
...article,
viewCount: currentViewCount + 1
};
this.articles.set(id, updatedArticle);
}
}
async removeDuplicateArticles(): Promise<{ removedCount: number; details: { outletId: string; duplicatesRemoved: number }[] }> {
const outletGroups = new Map<string, Map<string, Article[]>>();
// Group articles by outlet and title
for (const article of Array.from(this.articles.values())) {
if (!outletGroups.has(article.outletId)) {
outletGroups.set(article.outletId, new Map());
}
const titleGroups = outletGroups.get(article.outletId)!;
if (!titleGroups.has(article.title)) {
titleGroups.set(article.title, []);
}
titleGroups.get(article.title)!.push(article);
}
let totalRemoved = 0;
const outletDetails = new Map<string, number>();
// Process each outlet
for (const [outletId, titleGroups] of Array.from(outletGroups.entries())) {
let outletRemoved = 0;
for (const [title, articles] of Array.from(titleGroups.entries())) {
if (articles.length > 1) {
// Sort by publishedAt desc to keep the most recent
articles.sort((a: Article, b: Article) => b.publishedAt.getTime() - a.publishedAt.getTime());
// Keep the first (most recent) and remove the rest
const [keep, ...toRemove] = articles;
for (const article of toRemove) {
this.articles.delete(article.id);
totalRemoved++;
outletRemoved++;
}
}
}
if (outletRemoved > 0) {
outletDetails.set(outletId, outletRemoved);
}
}
const details = Array.from(outletDetails.entries()).map(([outletId, duplicatesRemoved]) => ({
outletId,
duplicatesRemoved
}));
return {
removedCount: totalRemoved,
details
};
}
// Comment system methods
async getCommentsByArticle(articleId: string, params: { limit?: number; offset?: number }): Promise<{ comments: Comment[]; total: number }> {
const limit = params.limit || 20;
const offset = params.offset || 0;
const allComments = Array.from(this.comments.values())
.filter(comment => comment.articleId === articleId && !comment.parentId)
.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
const total = allComments.length;
const comments = allComments.slice(offset, offset + limit);
return { comments, total };
}
async getCommentReplies(parentId: string, params: { limit?: number; offset?: number }): Promise<{ comments: Comment[]; total: number }> {
const limit = params.limit || 20;
const offset = params.offset || 0;
const allReplies = Array.from(this.comments.values())
.filter(comment => comment.parentId === parentId)
.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
const total = allReplies.length;
const comments = allReplies.slice(offset, offset + limit);
return { comments, total };
}
async getCommentById(id: string): Promise<Comment | undefined> {
return this.comments.get(id);
}
async createComment(comment: InsertComment): Promise<Comment> {
const newComment: Comment = {
id: randomUUID(),
likesCount: 0,
dislikesCount: 0,
repliesCount: 0,
createdAt: new Date(),
updatedAt: new Date(),
...comment,
avatar: comment.avatar || null,
parentId: comment.parentId || null
};
this.comments.set(newComment.id, newComment);
return newComment;
}
async updateComment(id: string, content: string): Promise<Comment | undefined> {
const comment = this.comments.get(id);
if (!comment) return undefined;
const updatedComment = {
...comment,
content,
updatedAt: new Date()
};
this.comments.set(id, updatedComment);
return updatedComment;
}
async deleteComment(id: string): Promise<boolean> {
return this.comments.delete(id);
}
async toggleCommentReaction(commentId: string, userIdentifier: string, reactionType: 'like' | 'dislike'): Promise<{ action: 'added' | 'removed' | 'changed'; reaction: CommentReaction | null }> {
const reactionKey = `${commentId}:${userIdentifier}`;
const existingReaction = this.commentReactions.get(reactionKey);
if (existingReaction) {
if (existingReaction.reactionType === reactionType) {
// Remove the reaction
this.commentReactions.delete(reactionKey);
return { action: 'removed', reaction: null };
} else {
// Change the reaction
const updatedReaction = { ...existingReaction, reactionType };
this.commentReactions.set(reactionKey, updatedReaction);
return { action: 'changed', reaction: updatedReaction };
}
} else {
// Add new reaction
const newReaction: CommentReaction = {
id: randomUUID(),
commentId,
reactionType,
userIdentifier,
createdAt: new Date()
};
this.commentReactions.set(reactionKey, newReaction);
return { action: 'added', reaction: newReaction };
}
}
async getUserCommentReaction(commentId: string, userIdentifier: string): Promise<CommentReaction | undefined> {
const reactionKey = `${commentId}:${userIdentifier}`;
return this.commentReactions.get(reactionKey);
}
async toggleBookmark(articleId: string, userIdentifier: string): Promise<{ action: 'added' | 'removed'; bookmark: Bookmark | null }> {
const bookmarkKey = `${articleId}:${userIdentifier}`;
const existingBookmark = this.bookmarks.get(bookmarkKey);
if (existingBookmark) {
this.bookmarks.delete(bookmarkKey);
try {
await db.delete(bookmarks)
.where(
and(
eq(bookmarks.articleId, articleId),
eq(bookmarks.userIdentifier, userIdentifier)
)
);
} catch (error) {
console.error('[DbStorage] Error removing bookmark:', error);
}
return { action: 'removed', bookmark: null };
} else {
const newBookmark: Bookmark = {
id: randomUUID(),
articleId,
userIdentifier,
createdAt: new Date()
};
this.bookmarks.set(bookmarkKey, newBookmark);
try {
await db.insert(bookmarks).values(newBookmark);
} catch (error) {
console.error('[DbStorage] Error adding bookmark:', error);
}
return { action: 'added', bookmark: newBookmark };
}
}
async isBookmarked(articleId: string, userIdentifier: string): Promise<boolean> {
const bookmarkKey = `${articleId}:${userIdentifier}`;
return this.bookmarks.has(bookmarkKey);
}
async getUserBookmarks(userIdentifier: string): Promise<Bookmark[]> {
return Array.from(this.bookmarks.values())
.filter(bookmark => bookmark.userIdentifier === userIdentifier);
}
async getArticleCommentCount(articleId: string): Promise<number> {
try {
const result = await db
.select({ count: count() })
.from(comments)
.where(eq(comments.articleId, articleId));
return result[0]?.count || 0;
} catch (error) {
console.error('[DbStorage] Error getting comment count:', error);
return Array.from(this.comments.values())
.filter(comment => comment.articleId === articleId).length;
}
}
// Prediction Market methods
async getPredictionMarketsByArticle(articleId: string, params: { limit?: number; offset?: number }): Promise<PredictionMarket[]> {
const limit = params.limit || 3;
const offset = params.offset || 0;
// Generate diverse prediction markets (binary and multiple choice)
const mockMarkets: PredictionMarket[] = [
// Binary markets (Yes/No)
{
id: `pm-${articleId}-1`,
articleId,
question: "Will this prediction come true by end of year?",
description: "Market resolves YES if the main prediction in this article occurs by December 31st",
marketType: "binary",
yesPrice: 65,
noPrice: 35,
options: null,
totalVolume: 421000,
endDate: new Date('2025-12-31'),
category: "Politics",
isLive: 1,
isResolved: 0,
createdAt: new Date(),
},
// Multiple choice market - Election
{
id: `pm-${articleId}-2`,
articleId,
question: "Who will win the mayoral election?",
description: "Market on the winner of upcoming mayoral election",
marketType: "multiple_choice",
yesPrice: null,
noPrice: null,
options: JSON.stringify([
{ name: "John Smith", price: 86 },
{ name: "Sarah Johnson", price: 14 },
]),
totalVolume: 108000,
endDate: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
category: "Politics",
isLive: 0,
isResolved: 0,
createdAt: new Date(),
},
// Multiple choice market - Sports match
{
id: `pm-${articleId}-3`,
articleId,
question: "Match Winner",
description: "Which team will win the upcoming match",
marketType: "multiple_choice",
yesPrice: null,
noPrice: null,
options: JSON.stringify([
{ name: "Team A", price: 60 },
{ name: "Draw", price: 22 },
{ name: "Team B", price: 18 },
]),
totalVolume: 421000,
endDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
category: "Sports",
isLive: 1,
isResolved: 0,
createdAt: new Date(),
},
// Binary market
{
id: `pm-${articleId}-4`,
articleId,
question: "Will stock price increase by 10% in next quarter?",
description: "Resolves YES if the mentioned company's stock rises 10%+ within 90 days",
marketType: "binary",
yesPrice: 55,
noPrice: 45,
options: null,
totalVolume: 221000,
endDate: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
category: "Business",
isLive: 0,
isResolved: 0,
createdAt: new Date(),
},
// Multiple choice market - Company acquisition
{
id: `pm-${articleId}-5`,
articleId,
question: "Which company will acquire XYZ Corp?",
description: "Market on potential acquirer of XYZ Corporation",
marketType: "multiple_choice",
yesPrice: null,
noPrice: null,
options: JSON.stringify([
{ name: "Microsoft", price: 45 },
{ name: "Google", price: 32 },
{ name: "Amazon", price: 23 },
]),
totalVolume: 457000,
endDate: new Date(Date.now() + 180 * 24 * 60 * 60 * 1000),
category: "Business",
isLive: 0,
isResolved: 0,
createdAt: new Date(),
},
];
return mockMarkets.slice(offset, offset + limit);
}
async getPredictionMarketById(id: string): Promise<PredictionMarket | undefined> {
// Mock implementation - would query database in production
return undefined;
}
async createPredictionMarket(market: InsertPredictionMarket): Promise<PredictionMarket> {
const newMarket: PredictionMarket = {
id: randomUUID(),
...market,
options: market.options ?? null,
description: market.description ?? null,
category: market.category ?? null,
yesPrice: market.yesPrice ?? null,
noPrice: market.noPrice ?? null,
createdAt: new Date(),
};
return newMarket;
}
}
// Create and export storage instance
export const storage = new DbStorage();