seed.ts•8 kB
/**
* Database seed script for the News Aggregator API
*
* Run with: npx ts-node prisma/seed.ts
*/
import { PrismaClient } from '@prisma/client';
import { logger } from '../src/utils/logger';
// Node.js process is available globally in Node.js environment
const prisma = new PrismaClient();
async function main() {
logger.info('Starting database seed process...');
// Clear existing data (optional - comment out if you want to keep existing data)
logger.info('Clearing existing data...');
await prisma.articleEntity.deleteMany({});
await prisma.articleTopic.deleteMany({});
await prisma.userArticle.deleteMany({});
await prisma.article.deleteMany({});
await prisma.user.deleteMany({});
await prisma.topic.deleteMany({});
await prisma.entity.deleteMany({});
// Create sample users
logger.info('Creating sample users...');
const user1 = await prisma.user.create({
data: {
email: 'test@example.com',
name: 'Test User',
passwordHash: '$2a$10$dJUJQcVmRXXRRQRXRXWwWuO0bZJ9Dk9fwpFGJ5yJUP3QyOy9XvAfm', // hashed 'password123'
preferredCategories: 'tech,business,science',
preferredSources: 'The Verge,TechCrunch',
preferredLanguage: 'en'
}
});
const user2 = await prisma.user.create({
data: {
email: 'demo@example.com',
name: 'Demo User',
passwordHash: '$2a$10$dJUJQcVmRXXRRQRXRXWwWuO0bZJ9Dk9fwpFGJ5yJUP3QyOy9XvAfm', // hashed 'password123'
preferredCategories: 'politics,entertainment',
preferredSources: 'CNN,BBC',
preferredLanguage: 'en'
}
});
// Create sample topics
logger.info('Creating sample topics...');
const topics = await Promise.all([
prisma.topic.create({ data: { name: 'Technology' } }),
prisma.topic.create({ data: { name: 'Business' } }),
prisma.topic.create({ data: { name: 'Science' } }),
prisma.topic.create({ data: { name: 'Politics' } }),
prisma.topic.create({ data: { name: 'Entertainment' } })
]);
// Create sample entities
logger.info('Creating sample entities...');
const entities = await Promise.all([
prisma.entity.create({ data: { name: 'Apple', type: 'ORGANIZATION' } }),
prisma.entity.create({ data: { name: 'Google', type: 'ORGANIZATION' } }),
prisma.entity.create({ data: { name: 'Elon Musk', type: 'PERSON' } }),
prisma.entity.create({ data: { name: 'United States', type: 'LOCATION' } }),
prisma.entity.create({ data: { name: 'Bitcoin', type: 'OTHER' } })
]);
// Create sample articles
logger.info('Creating sample articles...');
const sampleArticles = [
{
uuid: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
title: 'Apple Announces New iPhone 15 Pro',
description: 'Apple today announced the iPhone 15 Pro with an A17 chip and improved cameras.',
url: 'https://example.com/apple-iphone-15',
imageUrl: 'https://example.com/images/iphone15.jpg',
source: 'TechCrunch',
publishedAt: new Date('2025-04-15T10:30:00Z'),
categories: 'technology,apple,smartphones',
language: 'en',
readCount: 1250,
relevanceScore: 0.92,
sentiment: 0.7
},
{
uuid: 'b2c3d4e5-f6a7-8901-bcde-f23456789012',
title: 'Google Unveils New AI Features for Search',
description: 'Google is enhancing its search engine with new AI-powered features.',
url: 'https://example.com/google-ai-search',
imageUrl: 'https://example.com/images/google-ai.jpg',
source: 'The Verge',
publishedAt: new Date('2025-05-01T14:45:00Z'),
categories: 'technology,ai,google',
language: 'en',
readCount: 987,
relevanceScore: 0.89,
sentiment: 0.5
},
{
uuid: 'c3d4e5f6-a7b8-9012-cdef-345678901234',
title: 'SpaceX Successfully Launches Starship to Mars Orbit',
description: 'Elon Musk\'s SpaceX has successfully launched the Starship rocket to Mars orbit.',
url: 'https://example.com/spacex-starship-launch',
imageUrl: 'https://example.com/images/starship.jpg',
source: 'CNN',
publishedAt: new Date('2025-05-10T09:15:00Z'),
categories: 'science,space,technology',
language: 'en',
readCount: 2540,
relevanceScore: 0.95,
sentiment: 0.8
},
{
uuid: 'd4e5f6a7-b8c9-0123-defg-456789012345',
title: 'Global Markets React to New Economic Policies',
description: 'Stock markets worldwide respond to new economic policies announced by major economies.',
url: 'https://example.com/global-markets',
imageUrl: 'https://example.com/images/markets.jpg',
source: 'Bloomberg',
publishedAt: new Date('2025-05-05T16:20:00Z'),
categories: 'business,economy,markets',
language: 'en',
readCount: 1876,
relevanceScore: 0.87,
sentiment: -0.2
},
{
uuid: 'e5f6a7b8-c9d0-1234-efgh-567890123456',
title: 'Bitcoin Breaks $100,000 for the First Time',
description: 'Bitcoin has surpassed $100,000, marking a historic milestone for the cryptocurrency.',
url: 'https://example.com/bitcoin-record',
imageUrl: 'https://example.com/images/bitcoin.jpg',
source: 'CoinDesk',
publishedAt: new Date('2025-05-12T11:05:00Z'),
categories: 'business,cryptocurrency,finance',
language: 'en',
readCount: 3150,
relevanceScore: 0.94,
sentiment: 0.9
}
];
for (const articleData of sampleArticles) {
const article = await prisma.article.create({ data: articleData });
// Assign topics to articles
const articleTopics: any[] = [];
const categories = articleData.categories.split(',');
for (const topic of topics) {
if (categories.some(cat => topic.name.toLowerCase().includes(cat.toLowerCase()))) {
articleTopics.push(await prisma.articleTopic.create({
data: {
articleId: article.id,
topicId: topic.id,
confidence: Math.random() * 0.5 + 0.5 // Random confidence value between 0.5 and 1.0
}
}));
}
}
// Assign entities to articles
const articleEntities: any[] = [];
if (articleData.title.includes('Apple')) {
articleEntities.push(await prisma.articleEntity.create({
data: {
articleId: article.id,
entityId: entities[0].id,
frequency: Math.floor(Math.random() * 5) + 1
}
}));
}
if (articleData.title.includes('Google')) {
articleEntities.push(await prisma.articleEntity.create({
data: {
articleId: article.id,
entityId: entities[1].id,
frequency: Math.floor(Math.random() * 5) + 1
}
}));
}
if (articleData.description.includes('Elon Musk')) {
articleEntities.push(await prisma.articleEntity.create({
data: {
articleId: article.id,
entityId: entities[2].id,
frequency: Math.floor(Math.random() * 3) + 1
}
}));
}
if (articleData.title.includes('Bitcoin')) {
articleEntities.push(await prisma.articleEntity.create({
data: {
articleId: article.id,
entityId: entities[4].id,
frequency: Math.floor(Math.random() * 7) + 1
}
}));
}
// Create user interactions
if (Math.random() > 0.5) {
await prisma.userArticle.create({
data: {
userId: user1.id,
articleId: article.id,
isBookmarked: Math.random() > 0.7,
isRead: Math.random() > 0.3
}
});
}
if (Math.random() > 0.6) {
await prisma.userArticle.create({
data: {
userId: user2.id,
articleId: article.id,
isBookmarked: Math.random() > 0.6,
isRead: Math.random() > 0.4
}
});
}
}
logger.info('Database seed completed successfully.');
}
main()
.catch((e) => {
logger.error('Error during database seed:', e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});