/** * seed-data.mjs — Seed V1 Mobile SQLite DB with courses, forum, and Islamic finance data * Idempotent: safe to run multiple times (upserts/checks before creating) * Run via: docker cp seed-data.mjs falah_falah-mobile.X:/app/data/ && docker exec falah_falah-mobile.X node /app/data/seed-data.mjs */ import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); const DEMO_EMAIL = "demo@falahos.my"; async function seed() { console.log("🌱 Starting V1 Mobile seed..."); // ═══════════════════════════════════════════ // 1. FORUM CATEGORIES // ═══════════════════════════════════════════ const categories = [ { name: "General Discussion", description: "General Islamic discussions and community topics", icon: "MessageSquare", order: 1 }, { name: "Quran & Hadith", description: "Study and discussion of Quranic verses and hadith", icon: "BookOpen", order: 2 }, { name: "Fiqh & Rulings", description: "Islamic jurisprudence and daily rulings", icon: "Scale", order: 3 }, { name: "Family & Marriage", description: "Family relationships, marriage, and parenting in Islam", icon: "Heart", order: 4 }, { name: "Finance & Economy", description: "Islamic finance, halal investing, and economic topics", icon: "TrendingUp", order: 5 }, { name: "Announcements", description: "Official Falah platform announcements", icon: "Megaphone", order: 0 }, ]; let categoryIds = {}; for (const cat of categories) { const existing = await prisma.forumCategory.findUnique({ where: { name: cat.name } }); if (existing) { categoryIds[cat.name] = existing.id; console.log(` ā„¹ļø Forum category "${cat.name}" already exists (id: ${existing.id})`); } else { const created = await prisma.forumCategory.create({ data: cat }); categoryIds[cat.name] = created.id; console.log(` āœ… Created forum category: "${cat.name}"`); } } // ═══════════════════════════════════════════ // 2. DEMO USER (ensure exists with proper balance) // ═══════════════════════════════════════════ let demoUser = await prisma.user.findUnique({ where: { email: DEMO_EMAIL } }); if (!demoUser) { demoUser = await prisma.user.create({ data: { email: DEMO_EMAIL, name: "Demo User", flhBalance: 100000, isPremium: true, isPro: true, }, }); console.log(` āœ… Created demo user: ${DEMO_EMAIL} (id: ${demoUser.id})`); } else { // Update premium status and balance demoUser = await prisma.user.update({ where: { email: DEMO_EMAIL }, data: { flhBalance: 100000, isPremium: true, isPro: true }, }); console.log(` ā„¹ļø Demo user exists: balance=${demoUser.flhBalance}, premium=${demoUser.isPremium}`); } // ═══════════════════════════════════════════ // 3. FORUM THREADS // ═══════════════════════════════════════════ const threads = [ { title: "Welcome to Falah Community!", content: "Assalamu alaikum! Welcome to our community forum. This is a place for meaningful discussions, seeking knowledge, and supporting one another. Please introduce yourself!", category: "General Discussion", pinned: true, }, { title: "The Importance of Daily Dhikr", content: "Seeking reminders on the importance of daily remembrance of Allah. What are your favorite adhkar and how do you maintain consistency?", category: "General Discussion", pinned: false, }, { title: "Tips for Memorizing Juz Amma", content: "I have started memorizing Juz Amma and would love to hear tips and techniques that worked for others. Jazakum Allah khair!", category: "Quran & Hadith", pinned: false, }, { title: "Ruling on Cryptocurrency in Islam", content: "Assalamu alaikum, I would like to understand the Islamic ruling on cryptocurrency trading. Is it considered halal? What do the scholars say about Bitcoin and other digital assets?", category: "Fiqh & Rulings", pinned: false, }, { title: "Strengthening Family Bonds in Islam", content: "How do we strengthen our family relationships according to Islamic teachings? Looking for practical advice on being better spouses and parents.", category: "Family & Marriage", pinned: false, }, ]; for (const t of threads) { const catId = categoryIds[t.category]; if (!catId) continue; // Check if a thread with this title already exists const existing = await prisma.forumThread.findFirst({ where: { title: t.title } }); if (existing) { console.log(` ā„¹ļø Forum thread "${t.title}" already exists`); continue; } await prisma.forumThread.create({ data: { title: t.title, content: t.content, categoryId: catId, authorId: demoUser.id, pinned: t.pinned, shariahStatus: "approved", }, }); console.log(` āœ… Created forum thread: "${t.title}"`); } // ═══════════════════════════════════════════ // 4. LEARN COURSES // ═══════════════════════════════════════════ const courses = [ { slug: "intro-islamic-finance", title: "Introduction to Islamic Finance", author: "Falah Academy", description: "Learn the fundamentals of Islamic finance including the prohibition of riba (interest), the principles of halal investing, and the key contracts used in Islamic banking and finance.", difficulty: "beginner", published: true, moduleCount: 4, totalMinutes: 30, giteaPath: "courses/intro-islamic-finance", }, { slug: "zakat-made-easy", title: "Zakat Made Easy", author: "Falah Academy", description: "A comprehensive guide to understanding and calculating Zakat. Learn about nisab thresholds, different types of wealth, and how to fulfill this important pillar of Islam.", difficulty: "beginner", subscriptionOnly: false, published: true, moduleCount: 5, totalMinutes: 40, giteaPath: "courses/zakat-made-easy", }, { slug: "fiqh-of-salah", title: "Fiqh of Salah", author: "Falah Academy", description: "A detailed study of the Islamic prayer (salah) according to the Quran and Sunnah. Covers conditions, pillars, obligations, and common mistakes in prayer.", difficulty: "intermediate", published: true, moduleCount: 6, totalMinutes: 50, giteaPath: "courses/fiqh-of-salah", }, { slug: "waqf-endowment-guide", title: "Waqf Endowment Guide", author: "Falah Academy", description: "Understand the concept of Waqf (Islamic endowment) and how to set up perpetual charitable endowments that generate ongoing rewards.", difficulty: "intermediate", published: true, moduleCount: 3, totalMinutes: 25, giteaPath: "courses/waqf-endowment-guide", }, { slug: "sadaqah-and-community", title: "Sadaqah & Community Giving", author: "Falah Academy", description: "Explore the virtues of voluntary charity (sadaqah) in Islam and learn how to make the most impact through strategic community giving.", difficulty: "beginner", published: true, moduleCount: 3, totalMinutes: 20, giteaPath: "courses/sadaqah-and-community", }, ]; for (const course of courses) { const existing = await prisma.learnCourse.findUnique({ where: { slug: course.slug } }); if (existing) { console.log(` ā„¹ļø Course "${course.title}" already exists`); continue; } await prisma.learnCourse.create({ data: course }); console.log(` āœ… Created course: "${course.title}"`); } // ═══════════════════════════════════════════ // 5. AUTO-ENROLL DEMO USER IN ALL COURSES // ═══════════════════════════════════════════ const allCourses = await prisma.learnCourse.findMany({ where: { published: true } }); for (const course of allCourses) { const existing = await prisma.learnEnrollment.findUnique({ where: { userId_courseId: { userId: demoUser.id, courseId: course.id } }, }); if (!existing) { await prisma.learnEnrollment.create({ data: { userId: demoUser.id, courseId: course.id, purchaseType: "free", }, }); console.log(` āœ… Enrolled demo user in course: \"${course.title}\"`); } else { console.log(` ā„¹ļø Demo already enrolled in: \"${course.title}\"`); } } // ═══════════════════════════════════════════ // 6. LEARN MODULES (for each course) // ═══════════════════════════════════════════ const modules = { "intro-islamic-finance": [ { slug: "what-is-riba", title: "What is Riba?", keyTakeaway: "Riba (interest) is strictly prohibited in Islam. Understand the different types and why it matters.", duration: 8 }, { slug: "halal-investing", title: "Halal Investing Principles", keyTakeaway: "Investments must avoid riba, gharar (excessive uncertainty), and haram industries.", duration: 7 }, { slug: "islamic-contracts", title: "Islamic Contracts Overview", keyTakeaway: "Key contracts include Murabaha (cost-plus), Musharakah (partnership), and Ijarah (leasing).", duration: 8 }, { slug: "modern-fintech", title: "Modern Islamic Fintech", keyTakeaway: "Technology is making Islamic finance more accessible through digital wallets, tokenization, and smart contracts.", duration: 7 }, ], "zakat-made-easy": [ { slug: "what-is-zakat", title: "What is Zakat?", keyTakeaway: "Zakat is the third pillar of Islam — an obligatory charity on wealth that meets nisab threshold.", duration: 8 }, { slug: "calculating-nisab", title: "Calculating Nisab", keyTakeaway: "Nisab is the minimum amount of wealth before Zakat is due, equivalent to 85g of gold or 595g of silver.", duration: 8 }, { slug: "types-of-wealth", title: "Types of Zakatable Wealth", keyTakeaway: "Zakat applies to cash, gold/silver, business inventory, agricultural produce, livestock, and investments.", duration: 8 }, { slug: "zakat-calculation", title: "Calculating Your Zakat", keyTakeaway: "Zakat is 2.5% of qualifying wealth held for one lunar year (hawl).", duration: 8 }, { slug: "distributing-zakat", title: "Distributing Your Zakat", keyTakeaway: "Zakat must be given to 8 eligible categories, prioritizing local needs.", duration: 8 }, ], "fiqh-of-salah": [ { slug: "conditions-of-salah", title: "Conditions of Salah", keyTakeaway: "Salah has 9 preconditions including purity, facing qibla, and proper covering.", duration: 8 }, { slug: "pillars-of-salah", title: "Pillars of Salah", keyTakeaway: "The 14 pillars of salah are essential — missing any invalidates the prayer.", duration: 8 }, { slug: "obligations-of-salah", title: "Obligations of Salah", keyTakeaway: "The wajibaat (obligatory acts) of salah must be performed; intentional omission requires sujud al-sahw.", duration: 8 }, { slug: "sunnah-practices", title: "Sunnah Practices", keyTakeaway: "Following the sunnah practices of the Prophet ļ·ŗ in salah increases reward and perfects the prayer.", duration: 9 }, { slug: "common-mistakes", title: "Common Mistakes in Salah", keyTakeaway: "Common errors include rushing, incorrect recitation, and improper movements — learn to avoid them.", duration: 9 }, { slug: "congregational-prayer", title: "Congregational Prayer", keyTakeaway: "Praying in congregation (jama'ah) is 27 times more rewarding than praying alone.", duration: 8 }, ], "waqf-endowment-guide": [ { slug: "what-is-waqf", title: "What is Waqf?", keyTakeaway: "Waqf is a perpetual charitable endowment where the principal is preserved and benefits are continuously given.", duration: 8 }, { slug: "types-of-waqf", title: "Types of Waqf", keyTakeaway: "Waqf can be for family (waqf dhurri), charitable (waqf khayri), or combined purposes.", duration: 8 }, { slug: "digital-waqf", title: "Waqf in the Digital Age", keyTakeaway: "Digital waqf allows perpetual endowments using FLH tokens with automated yield distribution.", duration: 9 }, ], "sadaqah-and-community": [ { slug: "virtue-of-sadaqah", title: "The Virtue of Sadaqah", keyTakeaway: "Sadaqah purifies wealth, wards off calamities, and brings immense reward, especially when given secretly.", duration: 7 }, { slug: "types-of-sadaqah", title: "Types of Sadaqah", keyTakeaway: "Sadaqah includes both monetary giving and non-monetary acts like a smile or kind word (sadaqah jariyah).", duration: 7 }, { slug: "maximizing-impact", title: "Maximizing Community Impact", keyTakeaway: "Strategic giving through categorized causes (water, education, food, health) amplifies community benefit.", duration: 6 }, ], }; for (const [courseSlug, courseModules] of Object.entries(modules)) { const course = await prisma.learnCourse.findUnique({ where: { slug: courseSlug } }); if (!course) { console.log(` āš ļø Course "${courseSlug}" not found, skipping modules`); continue; } for (let i = 0; i < courseModules.length; i++) { const mod = courseModules[i]; const existing = await prisma.learnModule.findUnique({ where: { courseId_slug: { courseId: course.id, slug: mod.slug } }, }); if (existing) { continue; } await prisma.learnModule.create({ data: { courseId: course.id, order: i, title: mod.title, slug: mod.slug, keyTakeaway: mod.keyTakeaway, duration: mod.duration, content: `# ${mod.title}\n\n${mod.keyTakeaway}\n\n`, }, }); } console.log(` āœ… Created ${courseModules.length} modules for "${course.title}"`); } // ═══════════════════════════════════════════ // SUMMARY // ═══════════════════════════════════════════ const courseCount = await prisma.learnCourse.count(); const moduleCount = await prisma.learnModule.count(); const threadCount = await prisma.forumThread.count(); const categoryCount = await prisma.forumCategory.count(); const userCount = await prisma.user.count(); console.log("\nšŸ“Š Seed Summary:"); console.log(` Users: ${userCount}`); console.log(` Forum Categories: ${categoryCount}`); console.log(` Forum Threads: ${threadCount}`); console.log(` Courses: ${courseCount}`); console.log(` Course Modules: ${moduleCount}`); console.log("āœ… Seed complete!"); } seed() .catch((e) => { console.error("āŒ Seed failed:", e.message); process.exit(1); }) .finally(() => prisma.$disconnect());