Files
falah-mobile/scripts/seed-courses.ts
T
root cfff74e2db feat: Souq native integration + auth simplification + CE-wide enhancements
Souq Marketplace:
- Native souq pages: browse+filters, create listing, detail+seller profile, orders+chat
- New API: reviews (POST), sellers/[id], upload (multipart), polar-checkout webhook
- Listings API enhanced: minPrice, maxPrice, sortBy, deliveryDays filters
- Seller workflow: start order, mark delivered, upload files, confirm delivery
- Wallet: 5 Polar.sh FLH tiers, production checkout, mock fallback, success banner
- Fix: order redirect /souq/history → /souq/orders

Auth System:
- Unified auth page, removed OAuth provider routing (2 files deleted)
- Deleted oauth.ts (319 lines) — simplified auth chain
- Streamlined login/register API routes

Prisma Schema (+179 lines):
- New models: Listing, Purchase, Review, Group/GroupMember
- Gamification: DailyStreak, XpTransaction, Achievement, UserLevel
- Learning: LearnCourse/Module/Enrollment/Certificate
- Notifications, Referrals, Dhikr, PremiumBenefits

Deleted legacy code:
- src/app/api/marketplace/* (3 files) — replaced by /api/souq/*
- src/app/api/files/[listingId]/route.ts — replaced by /api/souq/upload
- src/app/api/seller/[sellerId]/route.ts — replaced by /api/souq/sellers/[id]

Infrastructure:
- Dockerfile: standalone output, Prisma runtime migration
- docker-compose.yml: Polar env vars, healthcheck fix
- docker-compose.staging.yml: staging on port 4014
- .gitea/workflows/ci.yml: CI pipeline
2026-06-24 07:02:03 +02:00

297 lines
10 KiB
TypeScript

/**
* seed-courses.ts — Seed initial micro learning courses into the database.
*
* Run: npx tsx scripts/seed-courses.ts
* Or via curl: POST /api/learn/seed (for production use)
*
* This seeds the first published courses from the Gitea content repo,
* or directly defines course/module structure for the MVP.
*/
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
const COURSES = [
{
slug: "atomic-habits",
title: "Atomic Habits",
author: "James Clear",
description:
"Master the science of habit formation in just 25 minutes. Learn how small daily changes compound into remarkable results through the 1% rule, identity-based habits, and the 4 laws of behavior change.",
imageUrl: null,
moduleCount: 5,
totalMinutes: 25,
difficulty: "beginner",
giteaPath: "courses/atomic-habits",
priceFlh: 499, // 4.99 in FLH cents
priceUsd: 4.99,
subscriptionOnly: false,
published: true,
modules: [
{
order: 1,
title: "The 1% Rule",
slug: "the-1-percent-rule",
keyTakeaway:
"Small habits don't just add up — they compound. Improving just 1% every day leads to being 37x better after one year.",
duration: 5,
content: `# The 1% Rule
Habits are the compound interest of self-improvement. The same way that money multiplies through compound interest, the effects of your habits multiply as you repeat them.
## The Math of Small Changes
If you get 1% better each day for one year, you'll end up 37 times better. Conversely, getting 1% worse each day for a year will decline you nearly to zero.
Success is the product of daily habits — not once-in-a-lifetime transformations.
## Why We Ignore Small Changes
We expect linear progress but live in a world of delayed returns. The most powerful outcomes are invisible during the early stages. This is the "Valley of Disappointment" — you do the right things but don't see results immediately.
## The Plateau of Latent Potential
Just like a ice cube melts at 32°F after hours of warming from 20°F to 31°F, your habits break through when you cross a critical threshold. Don't judge your success by what you see today. Your work is accumulating.
## Your Action Step
Identify one habit you want to build. Ask: "Can I make it 1% better today?"`,
quizData: JSON.stringify([
{
question: "If you get 1% better every day, how much better will you be after one year?",
options: ["About 3x better", "About 37x better", "About 10x better", "About 100x better"],
correctIndex: 1,
},
{
question: "What is the 'Valley of Disappointment'?",
options: [
"A period where habits feel boring",
"The phase where you work but see no results",
"The time between starting a new habit",
"When you lose motivation completely",
],
correctIndex: 1,
},
{
question: "At what temperature does ice melt?",
options: ["30°F", "32°F", "35°F", "40°F"],
correctIndex: 1,
},
]),
},
{
order: 2,
title: "Identity-Based Habits",
slug: "identity-based-habits",
keyTakeaway:
"The most effective way to change your habits is to focus on who you want to become, not what you want to achieve.",
duration: 5,
content: `# Identity-Based Habits
There are three levels of change: outcomes, processes, and identity. Most people focus on outcomes (what you get) instead of identity (who you are).
## The Two-Step Process
1. **Decide the type of person you want to be.**
2. **Prove it to yourself with small wins.**
Your identity emerges from your habits. Every action is a vote for the type of person you wish to become.
## The Habit Loop
Every habit follows a four-step loop:
- **Cue** — The trigger that initiates the behavior
- **Craving** — The motivational force behind the habit
- **Response** — The actual habit you perform
- **Reward** — The benefit you gain from the habit
## Your Action Step
Instead of saying "I want to run a marathon," say "I am a runner." Then go for a 5-minute jog.`,
quizData: JSON.stringify([
{
question: "What are the three levels of change mentioned?",
options: [
"Outcomes, Processes, Identity",
"Goals, Actions, Results",
"Start, Middle, End",
"Mind, Body, Soul",
],
correctIndex: 0,
},
{
question: "Each action is a ___ for the type of person you wish to become.",
options: ["Reminder", "Vote", "Proof", "Promise"],
correctIndex: 1,
},
]),
},
{
order: 3,
title: "The 4 Laws of Behavior Change",
slug: "the-4-laws",
keyTakeaway:
"To build a good habit: make it obvious, attractive, easy, and satisfying. To break a bad habit: invert each law.",
duration: 5,
content: `# The 4 Laws of Behavior Change
## Law 1: Make It Obvious
Design your environment so the cues for good habits are visible and the cues for bad habits are invisible.
## Law 2: Make It Attractive
Use temptation bundling — pair an action you want to do with an action you need to do.
## Law 3: Make It Easy
The most effective form of learning is practice, not planning. Reduce friction. The Two-Minute Rule: when you start a new habit, it should take less than two minutes.
## Law 4: Make It Satisfying
Use immediate rewards. What is immediately rewarded is repeated. What is immediately punished is avoided.
## The Inversion (Breaking Bad Habits)
- Make it **invisible**
- Make it **unattractive**
- Make it **difficult**
- Make it **unsatisfying**`,
quizData: JSON.stringify([
{
question: "What is Law 1 of behavior change?",
options: ["Make It Easy", "Make It Obvious", "Make It Attractive", "Make It Satisfying"],
correctIndex: 1,
},
{
question: "The Two-Minute Rule states that a new habit should take:",
options: ["Less than 5 minutes", "Less than 2 minutes", "Exactly 2 minutes", "As long as needed"],
correctIndex: 1,
},
]),
},
{
order: 4,
title: "Habit Stacking",
slug: "habit-stacking",
keyTakeaway:
"The best way to build a new habit is to anchor it to an existing one using the formula: After [CURRENT HABIT], I will [NEW HABIT].",
duration: 5,
content: `# Habit Stacking
One of the best ways to build a new habit is to identify a current habit you already do each day and then stack your new behavior on top.
## The Formula
> After [CURRENT HABIT], I will [NEW HABIT].
## Examples
- After I pour my morning coffee, I will meditate for 60 seconds.
- After I sit down to dinner, I will say one thing I'm grateful for.
- After I take off my work shoes, I will change into my workout clothes.
## The Key: Pairing Specificity
The more specific your plan, the more likely you are to follow through. Use implementation intentions:
> "I will [BEHAVIOR] at [TIME] in [LOCATION]."`,
quizData: JSON.stringify([
{
question: "What is habit stacking?",
options: [
"Doing multiple habits at once",
"Anchoring a new habit to an existing one",
"Stacking rewards on top of each other",
"Creating a list of habits",
],
correctIndex: 1,
},
]),
},
{
order: 5,
title: "Design Your Environment",
slug: "design-your-environment",
keyTakeaway:
"Your surroundings shape your behavior more than willpower. Design your environment for success by reducing friction for good habits and increasing it for bad ones.",
duration: 5,
content: `# Design Your Environment
Willpower is overrated. The most reliable way to stick to good habits is to design your environment so that the right choice is the easy choice.
## Friction
Every habit is initiated by a cue. If you want to make a habit a big part of your life, make the cue a big part of your environment.
- Want to read more? Keep a book on your pillow.
- Want to drink more water? Fill a bottle and place it on your desk.
- Want to practice guitar? Leave it in the middle of the room.
## One Space, One Use
Don't mix contexts. Your bed is for sleep. Your desk is for work. When you mix contexts, you mix habits.
## Commitment Devices
A commitment device is a choice you make in the present that locks in better behavior in the future. Delete the games from your phone. Unsubscribe from junk food delivery.
## Your Final Action Step
Choose ONE habit to focus on this week. Apply all 4 laws. Track it. Repeat.`,
quizData: JSON.stringify([
{
question: "What is a commitment device?",
options: [
"A promise to yourself",
"A present choice that locks in better future behavior",
"A device that tracks habits",
"An accountability partner",
],
correctIndex: 1,
},
{
question: "Wanting to read more — where should you keep the book?",
options: ["On your shelf", "On your pillow", "On your desk", "In your bag"],
correctIndex: 1,
},
]),
},
],
},
];
async function main() {
console.log("🌱 Seeding micro learning courses...\n");
for (const courseData of COURSES) {
const { modules, ...courseFields } = courseData;
// Upsert the course
const course = await prisma.learnCourse.upsert({
where: { slug: courseFields.slug },
create: courseFields,
update: courseFields,
});
console.log(` 📖 Course: ${course.title} (${course.slug})`);
// Upsert each module
for (const mod of modules) {
await prisma.learnModule.upsert({
where: {
courseId_slug: { courseId: course.id, slug: mod.slug },
},
create: { ...mod, courseId: course.id },
update: { ...mod, courseId: course.id },
});
console.log(` 📝 Module ${mod.order}: ${mod.title}`);
}
}
console.log(`\n✅ Seeded ${COURSES.length} course(s) successfully.`);
}
main()
.catch((e) => {
console.error("❌ Seed failed:", e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});