- tsconfig: remove deprecated downlevelIteration (es2017 has native iterators), change moduleResolution from node to bundler - auth: set allowDangerousEmailAccountLinking=false on all OAuth providers, restrict debug mode to development only - prisma: replace new PrismaClient() with singleton import in 10 API routes to prevent connection pool exhaustion - goal API: validate user-supplied quote URLs to block SSRF (private IPs, non-http(s) schemes) - email: guard DEV verification/reset link console.logs behind NODE_ENV check v1.98.0
215 lines
8.2 KiB
TypeScript
215 lines
8.2 KiB
TypeScript
import { PrismaClient } from '@prisma/client';
|
|
const prisma = new PrismaClient();
|
|
|
|
const dailyTasks = [
|
|
"Pretend to listen to partner's work drama",
|
|
"Feed the kids (again? really?)",
|
|
"Hide Amazon packages from spouse",
|
|
"Attempt to fold a fitted sheet, give up and roll it into a ball",
|
|
"Cook a meal that exactly 0% of the family will appreciate",
|
|
"Look at the mess. Sigh. Walk away.",
|
|
"Move the laundry from washer to dryer, leave it there for 3 days",
|
|
"Find out what died in the fridge",
|
|
"Pay bills and cry softly",
|
|
"Unload dishwasher with immense resentment",
|
|
"Scroll on phone until legs go numb on the toilet",
|
|
"Perform archeological dig in the teenage bedroom",
|
|
"Interrogate child about missing tupperware lid",
|
|
"Nod enthusiastically at toddler's incomprehensible story",
|
|
"Try to decipher spouse's 'helpful' grocery list",
|
|
"Pretend I don't see the full trash can",
|
|
"Vacuum the rug and ignore the corners",
|
|
"Wonder where all my money went"
|
|
];
|
|
|
|
const workEvents = [
|
|
"Meaningless sync meeting #42",
|
|
"Stare blankly at spreadsheet",
|
|
"Listen to boss talk about synergy",
|
|
"Reply 'As per my previous email...' to Gary",
|
|
"Pretend to be busy so no one asks me for help",
|
|
"'Quick chat' that ruins my entire afternoon",
|
|
"Update Jira tickets to make it look like I did something",
|
|
"Mute mic and eat aggressively loud chips during all-hands",
|
|
"Consider moving to the woods and becoming a hermit",
|
|
"Frantically search for the tab that is playing music",
|
|
"Draft angry email, delete it, send 'Sounds good!'",
|
|
"Nod meaningfully during presentation I don't understand"
|
|
];
|
|
|
|
const birthdayTasks = [
|
|
"Buy a gift that makes me look thoughtful but was actually on sale",
|
|
"Wrap the present (using newspaper because I forgot wrapping paper)",
|
|
"Attend birthday party and strategically position myself near the snack table",
|
|
"Fake a smile while listening to Uncle Bob's views",
|
|
"Smuggle leftover cake home in napkins"
|
|
];
|
|
|
|
async function main() {
|
|
const user = await prisma.user.findUnique({
|
|
where: { email: 'kugelblitz@gmx.de' }
|
|
});
|
|
|
|
if (!user) return;
|
|
|
|
// 1. Delete all recently generated tasks
|
|
await prisma.task.deleteMany({
|
|
where: {
|
|
userId: user.id,
|
|
createdAt: { gte: new Date(new Date().setHours(0,0,0,0)) },
|
|
title: { not: 'Meeting with team' } // leave the one subagent added if you want, or just let it delete if the title is strictly dailyTasks. Actually just delete all created today!
|
|
}
|
|
});
|
|
|
|
// 2. Create Projects for beautiful colors
|
|
let pWork = await prisma.project.findFirst({ where: { userId: user.id, name: 'Work' } });
|
|
if (!pWork) pWork = await prisma.project.create({ data: { userId: user.id, name: 'Work', color: '#3b82f6', icon: 'faBriefcase' } });
|
|
|
|
let pFamily = await prisma.project.findFirst({ where: { userId: user.id, name: 'Family' } });
|
|
if (!pFamily) pFamily = await prisma.project.create({ data: { userId: user.id, name: 'Family', color: '#10b981', icon: 'faHouse' } });
|
|
|
|
let pLife = await prisma.project.findFirst({ where: { userId: user.id, name: 'Life' } });
|
|
if (!pLife) pLife = await prisma.project.create({ data: { userId: user.id, name: 'Life', color: '#f59e0b', icon: 'faHeart' } });
|
|
|
|
// 3. Find target Someday lists to populate the bottom
|
|
const lists = await prisma.somedayList.findMany({ where: { userId: user.id } });
|
|
const kugelList = lists.find(l => l.title.includes('kugel'));
|
|
const papaList = lists.find(l => l.title.includes('Papa'));
|
|
|
|
// Target dates: March 16 to April 12, 2026
|
|
const startDate = new Date('2026-03-16T00:00:00Z');
|
|
const endDate = new Date('2026-04-12T00:00:00Z');
|
|
const birthdayDate = new Date('2026-04-04T00:00:00Z');
|
|
const aprilFools = new Date('2026-04-01T00:00:00Z');
|
|
|
|
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
|
|
const isBirthday = d.getTime() === birthdayDate.getTime();
|
|
const isAprilFools = d.getTime() === aprilFools.getTime();
|
|
const dateStr = d.toISOString().split('T')[0];
|
|
const isWeekend = d.getDay() === 0 || d.getDay() === 6;
|
|
|
|
// We want a DENSE calendar for the tutorial. 50% fill rate for EACH SLOT.
|
|
// Daily Life events (scheduled on grid)
|
|
const numLife = Math.floor(Math.random() * 2) + 1;
|
|
for (let i = 0; i < numLife; i++) {
|
|
const h = Math.floor(Math.random() * 3) + 6; // 6-8 AM or evening
|
|
await prisma.task.create({
|
|
data: {
|
|
title: dailyTasks[Math.floor(Math.random() * dailyTasks.length)],
|
|
userId: user.id,
|
|
scheduledDate: new Date(dateStr),
|
|
dayOfWeek: d.getDay(),
|
|
startTime: `${h.toString().padStart(2, '0')}:00`,
|
|
endTime: `${(h + 1).toString().padStart(2, '0')}:00`,
|
|
projectId: pLife.id
|
|
}
|
|
});
|
|
}
|
|
|
|
if (!isWeekend) {
|
|
// Work events
|
|
let currentHour = 8;
|
|
while (currentHour <= 16) {
|
|
if (Math.random() > 0.4) { // 60% chance to put a work meeting in this block
|
|
const duration = Math.random() > 0.5 ? 1 : 2;
|
|
await prisma.task.create({
|
|
data: {
|
|
title: workEvents[Math.floor(Math.random() * workEvents.length)],
|
|
userId: user.id,
|
|
scheduledDate: new Date(dateStr),
|
|
dayOfWeek: d.getDay(),
|
|
startTime: `${currentHour.toString().padStart(2, '0')}:00`,
|
|
endTime: `${(currentHour + duration).toString().padStart(2, '0')}:00`,
|
|
projectId: pWork.id
|
|
}
|
|
});
|
|
currentHour += duration + 1; // leave at least 1h gap
|
|
} else {
|
|
currentHour += 1;
|
|
}
|
|
}
|
|
} else {
|
|
// Weekend Family events
|
|
const numFam = Math.floor(Math.random() * 3) + 2;
|
|
let famHour = 9;
|
|
for (let i = 0; i < numFam; i++) {
|
|
await prisma.task.create({
|
|
data: {
|
|
title: dailyTasks[Math.floor(Math.random() * dailyTasks.length)],
|
|
userId: user.id,
|
|
scheduledDate: new Date(dateStr),
|
|
dayOfWeek: d.getDay(),
|
|
startTime: `${famHour.toString().padStart(2, '0')}:00`,
|
|
endTime: `${(famHour + 1).toString().padStart(2, '0')}:00`,
|
|
projectId: pFamily.id
|
|
}
|
|
});
|
|
famHour += 2;
|
|
}
|
|
}
|
|
|
|
// Add April Fools extra
|
|
if (isAprilFools) {
|
|
await prisma.task.create({
|
|
data: {
|
|
title: "Attempt a prank, fail miserably, apologize to HR",
|
|
userId: user.id,
|
|
scheduledDate: new Date(dateStr),
|
|
dayOfWeek: d.getDay(),
|
|
startTime: "10:30",
|
|
endTime: "11:30",
|
|
projectId: pWork.id
|
|
}
|
|
});
|
|
}
|
|
|
|
// Add Birthday extras
|
|
if (isBirthday) {
|
|
for (let i = 0; i < birthdayTasks.length; i++) {
|
|
const time = 14 + i;
|
|
await prisma.task.create({
|
|
data: {
|
|
title: birthdayTasks[i],
|
|
userId: user.id,
|
|
scheduledDate: new Date(dateStr),
|
|
dayOfWeek: d.getDay(),
|
|
startTime: `${time}:00`,
|
|
endTime: `${time + 1}:00`,
|
|
projectId: pFamily.id
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Populate SomeDay Lists
|
|
if (kugelList) {
|
|
for(let i=0; i<3; i++) {
|
|
await prisma.task.create({
|
|
data: {
|
|
title: dailyTasks[Math.floor(Math.random() * dailyTasks.length)],
|
|
userId: user.id,
|
|
somedayListId: kugelList.id,
|
|
order: i
|
|
}
|
|
});
|
|
}
|
|
}
|
|
if (papaList) {
|
|
for(let i=0; i<3; i++) {
|
|
await prisma.task.create({
|
|
data: {
|
|
title: workEvents[Math.floor(Math.random() * workEvents.length)],
|
|
userId: user.id,
|
|
somedayListId: papaList.id,
|
|
order: i
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
console.log("Densley populated the calendar with wonderful colored events!");
|
|
}
|
|
|
|
main().catch(console.error).finally(() => prisma.$disconnect());
|