Files
democratic-money/scripts/seed-leaderboard.ts
2026-05-16 00:47:44 +00:00

91 lines
4.1 KiB
TypeScript

import "dotenv/config";
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "@prisma/client";
import { Pool } from "pg";
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter: new PrismaPg(pool) });
// Pre-seeded founding donors — display names + amounts in USD cents
const FOUNDING_DONORS: { name: string; email: string; amountsCents: number[] }[] = [
{ name: "Margaret T.", email: "ghost.margaret@leaderboard.local", amountsCents: [10000, 10000, 10000, 10000, 10000] },
{ name: "James R.", email: "ghost.james@leaderboard.local", amountsCents: [10000, 10000, 10000, 10000] },
{ name: "Sophia K.", email: "ghost.sophia@leaderboard.local", amountsCents: [10000, 10000, 10000, 2000] },
{ name: "David M.", email: "ghost.david@leaderboard.local", amountsCents: [10000, 10000, 10000] },
{ name: "Priya N.", email: "ghost.priya@leaderboard.local", amountsCents: [10000, 10000, 2000] },
{ name: "Carlos V.", email: "ghost.carlos@leaderboard.local", amountsCents: [10000, 10000, 1000] },
{ name: "Elena B.", email: "ghost.elena@leaderboard.local", amountsCents: [10000, 2000, 2000, 500] },
{ name: "Thomas W.", email: "ghost.thomas@leaderboard.local", amountsCents: [10000, 2000, 500] },
{ name: "Aisha F.", email: "ghost.aisha@leaderboard.local", amountsCents: [2000, 2000, 2000, 1000] },
{ name: "Noah P.", email: "ghost.noah@leaderboard.local", amountsCents: [2000, 2000, 2000] },
{ name: "Grace L.", email: "ghost.grace@leaderboard.local", amountsCents: [2000, 2000, 1000] },
{ name: "Ryan H.", email: "ghost.ryan@leaderboard.local", amountsCents: [2000, 2000, 500] },
{ name: "Isabella C.", email: "ghost.isabella@leaderboard.local", amountsCents: [2000, 1000, 500] },
{ name: "Marcus J.", email: "ghost.marcus@leaderboard.local", amountsCents: [2000, 1000] },
{ name: "Fatima A.", email: "ghost.fatima@leaderboard.local", amountsCents: [1000, 1000, 1000] },
{ name: "Liam O.", email: "ghost.liam@leaderboard.local", amountsCents: [1000, 1000, 500] },
{ name: "Nina S.", email: "ghost.nina@leaderboard.local", amountsCents: [1000, 1000] },
{ name: "Derek U.", email: "ghost.derek@leaderboard.local", amountsCents: [1000, 500, 500] },
{ name: "Amara D.", email: "ghost.amara@leaderboard.local", amountsCents: [1000, 500] },
{ name: "Kevin T.", email: "ghost.kevin@leaderboard.local", amountsCents: [500, 500, 500] },
];
async function main() {
let totalCreated = 0;
for (const donor of FOUNDING_DONORS) {
const leaderboardUsername = donor.email
.trim()
.toLowerCase()
.replace(/[@.+-]/g, "_")
.replace(/[^a-z0-9_]+/g, "_")
.replace(/_+/g, "_")
.replace(/^_|_$/g, "")
.slice(0, 32);
const user = await prisma.user.upsert({
where: { email: donor.email },
update: { name: donor.name, username: leaderboardUsername },
create: {
email: donor.email,
username: leaderboardUsername,
name: donor.name,
passwordHash: "ghost-no-login",
},
});
await prisma.wallet.upsert({
where: { userId: user.id },
update: {},
create: { userId: user.id, balanceCredits: 0 },
});
// Add donations, spread over past 90 days
const total = donor.amountsCents.length;
for (let i = 0; i < total; i++) {
const amountCents = donor.amountsCents[i];
const daysAgo = Math.floor((i / total) * 90) + Math.floor(Math.random() * 5);
const createdAt = new Date(Date.now() - daysAgo * 86_400_000);
const piId = `ghost_pi_${user.id.slice(0, 8)}_${i}`;
await prisma.donation.upsert({
where: { stripePaymentIntentId: piId },
update: {},
create: {
stripePaymentIntentId: piId,
userId: user.id,
amountUsdCents: amountCents,
creditsAwarded: 0,
status: "succeeded",
createdAt,
},
});
totalCreated++;
}
}
console.log(`Seeded ${FOUNDING_DONORS.length} ghost donors with ${totalCreated} donations.`);
}
main()
.then(() => prisma.$disconnect().then(() => pool.end()))
.catch(e => { console.error(e); process.exit(1); });