-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Integrate Upstash Redis for Dynamic PostGroup Storage and Retrieval #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#!/usr/bin/env node | ||
|
||
import { seedDatabase, clearDatabase, verifySeeding } from './seedDatabase'; | ||
|
||
/** | ||
* Command-line script to seed the Upstash Redis database with mock data. | ||
* | ||
* Usage: | ||
* npx tsx src/seed.ts # Seed the database | ||
* npx tsx src/seed.ts clear # Clear all PostGroup data | ||
* npx tsx src/seed.ts verify # Verify seeded data | ||
* npx tsx src/seed.ts --help # Show help | ||
*/ | ||
|
||
async function main() { | ||
const args = process.argv.slice(2); | ||
const command = args[0]?.toLowerCase(); | ||
|
||
try { | ||
switch (command) { | ||
case 'clear': | ||
await clearDatabase(); | ||
break; | ||
|
||
case 'verify': | ||
await verifySeeding(); | ||
break; | ||
|
||
case '--help': | ||
case '-h': | ||
case 'help': | ||
showHelp(); | ||
break; | ||
|
||
case undefined: | ||
// Default action: seed the database | ||
await seedDatabase(); | ||
await verifySeeding(); // Verify after seeding | ||
break; | ||
|
||
default: | ||
console.error(`❌ Unknown command: ${command}`); | ||
showHelp(); | ||
process.exit(1); | ||
} | ||
|
||
console.log('✨ Operation completed successfully!'); | ||
process.exit(0); | ||
|
||
} catch (error) { | ||
console.error('💥 Operation failed:', error); | ||
process.exit(1); | ||
} | ||
} | ||
|
||
function showHelp() { | ||
console.log(` | ||
🌱 Database Seeding Script | ||
|
||
Usage: | ||
npx tsx src/seed.ts # Seed the database with mock data | ||
npx tsx src/seed.ts clear # Clear all PostGroup data (use with caution!) | ||
npx tsx src/seed.ts verify # Verify that data was seeded correctly | ||
npx tsx src/seed.ts --help # Show this help message | ||
|
||
Examples: | ||
# Seed the database with mock post groups and posts | ||
npx tsx src/seed.ts | ||
|
||
# Clear all data before seeding fresh data | ||
npx tsx src/seed.ts clear && npx tsx src/seed.ts | ||
|
||
# Just verify what's currently in the database | ||
npx tsx src/seed.ts verify | ||
|
||
Environment Requirements: | ||
- REDIS_URL or Upstash environment variables must be configured | ||
- See .env file for configuration details | ||
`); | ||
} | ||
|
||
// Run the script | ||
if (require.main === module) { | ||
main(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { PostGroup } from './postGroup'; | ||
|
||
export const seedData: PostGroup[] = [ | ||
{ | ||
"id": "group1", | ||
"posts": [ | ||
{ | ||
"id": "post1", | ||
"content": "Empery Digital\n@EMPD_BTC\n·\n11m\nBitcoin Firsts that changed everything:\n- $4B Pizza\n- A nation bets on BTC\n- Wall Street embraces it\n- The Trillion-Dollar Club\nFrom a pizza order to reshaping global finance.\n#Bitcoin #BTC #Blockchain #EmperyDigital", | ||
"sentiment": "BULLISH", | ||
"source": "TWITTER", | ||
"categories": [ | ||
"Cryptocurrency", | ||
"Market Analysis" | ||
], | ||
"subcategories": [ | ||
"Bitcoin", | ||
"Milestones", | ||
"Adoption" | ||
], | ||
"createdAt": "2025-09-16T12:00:00.000Z", | ||
"updatedAt": "2025-09-16T12:00:00.000Z" | ||
}, | ||
{ | ||
"id": "post2", | ||
"content": "Empery Digital\n@EMPD_BTC\n·\n11m\nSome notable events in Bitcoin's history include:\n- The purchase of pizza with Bitcoin\n- A country adopting BTC\n- Increased interest from Wall Street\n- Joining the Trillion-Dollar Club\nThese milestones reflect Bitcoin's evolving role in finance.\n#Bitcoin #BTC #Blockchain #EmperyDigital", | ||
"sentiment": "NEUTRAL", | ||
"source": "TWITTER", | ||
"categories": [ | ||
"Cryptocurrency", | ||
"Market Analysis" | ||
], | ||
"subcategories": [ | ||
"Bitcoin", | ||
"Milestones", | ||
"Adoption" | ||
], | ||
"createdAt": "2025-09-16T12:00:00.000Z", | ||
"updatedAt": "2025-09-16T12:00:00.000Z" | ||
}, | ||
{ | ||
"id": "post3", | ||
"content": "Empery Digital\n@EMPD_BTC\n·\n11m\nRecent events in Bitcoin's history have raised concerns:\n- The infamous $4B pizza purchase\n- A nation risking its economy on BTC\n- Wall Street's speculative involvement\n- Entering the Trillion-Dollar Club amid volatility\nFrom a simple transaction to ongoing financial uncertainty.\n#Bitcoin #BTC #Blockchain #EmperyDigital", | ||
"sentiment": "BEARISH", | ||
"source": "TWITTER", | ||
"categories": [ | ||
"Cryptocurrency", | ||
"Market Analysis" | ||
], | ||
"subcategories": [ | ||
"Bitcoin", | ||
"Milestones", | ||
"Risks" | ||
], | ||
"createdAt": "2025-09-16T12:00:00.000Z", | ||
"updatedAt": "2025-09-16T12:00:00.000Z" | ||
} | ||
] | ||
} | ||
]; |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,90 @@ | ||||||||||||||||
import { initRedis, getRedisClient } from './redisClient'; | ||||||||||||||||
import { seedData } from './seedData'; | ||||||||||||||||
import { PostGroup } from './postGroup'; | ||||||||||||||||
|
||||||||||||||||
Comment on lines
+1
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Type import triggers side effects; switch to type‑only. This import loads src/postGroup.ts at runtime, which starts the cron scheduler. Use a type‑only import (and keep cron gated). -import { PostGroup } from './postGroup';
+import type { PostGroup } from './postGroup'; 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||
/** | ||||||||||||||||
* Seeds the Upstash Redis database with mock data for PostGroups. | ||||||||||||||||
* This function will clear existing PostGroup data and populate it with the seed data. | ||||||||||||||||
*/ | ||||||||||||||||
export async function seedDatabase(): Promise<void> { | ||||||||||||||||
try { | ||||||||||||||||
console.log('🌱 Starting database seeding...'); | ||||||||||||||||
|
||||||||||||||||
// Initialize Redis connection | ||||||||||||||||
await initRedis(); | ||||||||||||||||
const redis = getRedisClient(); | ||||||||||||||||
|
||||||||||||||||
console.log('✅ Connected to Redis'); | ||||||||||||||||
|
||||||||||||||||
// Store the seed data as post-groups data in Redis | ||||||||||||||||
// Using the new key structure as required | ||||||||||||||||
await redis.set('post-groups', JSON.stringify(seedData)); | ||||||||||||||||
|
||||||||||||||||
console.log(`✅ Successfully seeded ${seedData.length} post group(s) to Redis`); | ||||||||||||||||
console.log('📊 Seed data summary:'); | ||||||||||||||||
|
||||||||||||||||
seedData.forEach((group: PostGroup, index: number) => { | ||||||||||||||||
console.log(` Group ${index + 1}: ${group.id} (${group.posts.length} posts)`); | ||||||||||||||||
group.posts.forEach((post, postIndex) => { | ||||||||||||||||
console.log(` Post ${postIndex + 1}: ${post.id} - ${post.sentiment} (${post.source})`); | ||||||||||||||||
}); | ||||||||||||||||
}); | ||||||||||||||||
|
||||||||||||||||
console.log('🎉 Database seeding completed successfully!'); | ||||||||||||||||
|
||||||||||||||||
} catch (error) { | ||||||||||||||||
console.error('❌ Error seeding database:', error); | ||||||||||||||||
throw error; | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
/** | ||||||||||||||||
* Clears all PostGroup data from the database. | ||||||||||||||||
* Use with caution - this will delete all existing post groups! | ||||||||||||||||
*/ | ||||||||||||||||
export async function clearDatabase(): Promise<void> { | ||||||||||||||||
try { | ||||||||||||||||
console.log('🧹 Clearing PostGroup data from database...'); | ||||||||||||||||
|
||||||||||||||||
await initRedis(); | ||||||||||||||||
const redis = getRedisClient(); | ||||||||||||||||
|
||||||||||||||||
await redis.del('post-groups'); | ||||||||||||||||
|
||||||||||||||||
console.log('✅ Database cleared successfully'); | ||||||||||||||||
|
||||||||||||||||
} catch (error) { | ||||||||||||||||
console.error('❌ Error clearing database:', error); | ||||||||||||||||
throw error; | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
/** | ||||||||||||||||
* Verifies that the seed data was properly stored by retrieving and logging it. | ||||||||||||||||
*/ | ||||||||||||||||
export async function verifySeeding(): Promise<void> { | ||||||||||||||||
try { | ||||||||||||||||
console.log('🔍 Verifying seeded data...'); | ||||||||||||||||
|
||||||||||||||||
await initRedis(); | ||||||||||||||||
const redis = getRedisClient(); | ||||||||||||||||
|
||||||||||||||||
const data = await redis.get('post-groups'); | ||||||||||||||||
|
||||||||||||||||
if (!data) { | ||||||||||||||||
console.log('❌ No data found in database'); | ||||||||||||||||
return; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
const postGroups: PostGroup[] = JSON.parse(data); | ||||||||||||||||
|
||||||||||||||||
console.log(`✅ Found ${postGroups.length} post group(s) in database:`); | ||||||||||||||||
postGroups.forEach((group, index) => { | ||||||||||||||||
console.log(` Group ${index + 1}: ${group.id} (${group.posts.length} posts)`); | ||||||||||||||||
}); | ||||||||||||||||
|
||||||||||||||||
} catch (error) { | ||||||||||||||||
console.error('❌ Error verifying seeded data:', error); | ||||||||||||||||
throw error; | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
Comment on lines
+1
to
+90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 🧩 Analysis chainFind and fix any remaining non type‑only imports from './postGroup'. Run to verify repo-wide. 🏁 Script executed: #!/bin/bash
# Flag any value imports (non type-only) from './postGroup'
rg -nP --type=ts -C1 "import\s+\{[^}]*\b(PostGroup|Post)\b[^}]*\}\s+from\s+['\"]\./postGroup['\"]" \
| sed 's/^/NON-TYPE IMPORT: /'
# Show existing type-only imports for confirmation
rg -nP --type=ts -C1 "import\s+type\s+\{[^}]*\b(PostGroup|Post)\b[^}]*\}\s+from\s+['\"]\./postGroup['\"]" \
| sed 's/^/TYPE-ONLY IMPORT: /' Length of output: 329 Convert './postGroup' imports to type-only
🤖 Prompt for AI Agents
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Importing a type from a module with side effects will start the cron scheduler. Use a type‑only import (or move types).
src/postGroup.ts registers a cron job at import time; importing it here just for typing will trigger it. Switch to a type‑only import immediately.
Follow‑up: long‑term, extract Post/PostGroup to a pure types module (e.g., src/types/post.ts) to avoid any runtime side effects from type imports.
📝 Committable suggestion
🤖 Prompt for AI Agents