a1c5fecd83
- Switch Prisma schema from SQLite to PostgreSQL - Add netlify.toml for Netlify deployment config - Add @netlify/plugin-nextjs for serverless Next.js - Remove Docker build files (Dockerfile, docker-compose, start.sh) - Remove auto-healer and scripts directories - Update next.config.ts (remove standalone output) - Database: falah_mobile_v1 on Contabo Postgres
229 lines
11 KiB
Markdown
229 lines
11 KiB
Markdown
# Falah Mobile — Micro Learning Platform Handover
|
||
|
||
## Project Overview
|
||
|
||
Falah Mobile is a Next.js 16 PWA serving a full Islamic lifestyle platform (Nur AI coaching, Halal marketplace, community, wallet, and **micro learning courses**). The micro learning module is the focus of this handover — a complete E2E system for browsing, purchasing, consuming, and certifying bite-sized (5 min) courses derived from books.
|
||
|
||
Production URL: `https://falahos.my/mobile`
|
||
Staging URL: `https://falahos.my:4014/mobile`
|
||
|
||
### Repository
|
||
|
||
| Detail | Value |
|
||
|:-------|:------|
|
||
| **Source path (server)** | `/root/falah-mobile` |
|
||
| **Gitea remote** | `http://git.falahos.my/wmj/falah-mobile.git` (internal: `localhost:3080/wmj/falah-mobile.git`) |
|
||
| **Gitea repo ID** | `1` |
|
||
| **Full name** | `wmj/falah-mobile` |
|
||
| **Default branch** | `main` |
|
||
| **Last commit** | `bfd3509` — "docs: update README with full CE feature docs, architecture, and deployment guide" |
|
||
| **GitHub mirror** | `https://github.com/maifors/falah-mobile.git` (auto-synced via Gitea cron) |
|
||
|
||
|
||
## ✅ What Is Complete (Live)
|
||
|
||
### Course Library — 4 Courses, 21 Modules, 6 Categories
|
||
|
||
| Course | Author | Modules | Category |
|
||
|--------|--------|:-------:|:---------|
|
||
| Atomic Habits | James Clear | 5 | Self Improvement |
|
||
| The Defining Decade | Meg Jay | 6 | Self Improvement |
|
||
| Simplicity Parenting | Kim John Payne | 5 | Self Improvement |
|
||
| Tao Te Ching | Lao Tzu | 5 | Self Improvement |
|
||
|
||
6 categories defined (Self Improvement ✅, Basic Quran/Hadith/Prayer/History/Finance — empty, ready for content).
|
||
|
||
### Course Content Delivery
|
||
- **Course listing** with category badges + search bar + category filter tabs
|
||
- **Course detail page** with module timeline, progress bar, quiz badges
|
||
- **Module page** with lesson content (markdown), Listen 🎧 button, Quiz section
|
||
- **TTS audio** using browser Web Speech API with female voice selection (preferred: Google UK English Female → Samantha → Microsoft Zira → fallback)
|
||
- **Markdown stripping** for TTS (strips `#`, `##`, `**bold**`, `*italic*`, `[links]`, `> quotes`, `- lists`, `1. lists`, `` `code` ``)
|
||
- **Quiz system** — 3–5 multiple-choice questions per module, submit/score/retry
|
||
- **Certificate issuance** — auto-issued when all modules completed, with PDF generation and serial number. Displayed as 🎓 View Certificate badge on course detail page.
|
||
|
||
### Payments & Subscription
|
||
| Product | Price | Status |
|
||
|---------|:-----:|:------:|
|
||
| Atomic Habits (one-time) | $4.99 | ❌ Not mapped in checkout (old courses only have 3 mapped) |
|
||
| The Defining Decade (one-time) | $4.99 | ❌ Not mapped in checkout |
|
||
| Simplicity Parenting (one-time) | $4.99 | ❌ Not mapped in checkout |
|
||
| Tao Te Ching (one-time) | $4.99 | ❌ Not mapped in checkout |
|
||
| Learn Pass Monthly | $9.99/mo | ✅ Live on Polar |
|
||
| Learn Pass Annual | $79.99/yr | ✅ Live on Polar |
|
||
| In-app toggle (monthly/annual) | — | ✅ LearnPassCard component |
|
||
|
||
**IMPORTANT:** The checkout API at `src/app/api/learn/checkout/route.ts` only has `PRODUCTS` mapping for the *original 3 courses* (atomic-habits, deep-work, 7-habits). New courses (defining-decade, simplicity-parenting, tao-te-ching) need their Polar price IDs added to this map for individual purchase to work.
|
||
|
||
### Demo Credentials
|
||
- `demo@falahos.my` / `password123` (Premium, FLH 10,000)
|
||
- `premium@falahos.my` / `Premium123!` (Premium, FLH 50,000)
|
||
|
||
### TTS Voice
|
||
- Client-side browser SpeechSynthesis with voice selection
|
||
- Pitch: 1.15, Rate: 0.9
|
||
|
||
---
|
||
|
||
## 📋 Pending / Next Steps
|
||
|
||
### Priority: Phase 5+ Course Content (27 more courses)
|
||
39-course library planned. Only 4 built. Remaining 35 courses span 6 categories:
|
||
- **Self Improvement** (14 more needed) — Deep Work, 7 Habits, Mindset, Learning How to Learn, You Are Awesome, Al-Ghazali, Rumi, Love Languages, Whole-Brain Child, Crucial Conversations, How to Talk So Kids Will Listen, etc.
|
||
- **Basic Quran** (0/8 courses) — need content creation
|
||
- **Basic Hadith** (0/6 courses) — need content creation
|
||
- **Basic Prayer & Worship** (0/6 courses) — need content creation
|
||
- **Basic Islamic History** (0/5 courses) — need content creation
|
||
- **Basic Islamic Finance** (0/4 courses) — need content creation
|
||
|
||
Each course follows the micro-learning template:
|
||
```
|
||
5 modules × 5 min each
|
||
3–5 multiple-choice questions per module (format: {questions: [{question, options[], correctIndex}]})
|
||
Key takeaway per module
|
||
```
|
||
|
||
Course seed file template: `/root/falah-mobile/scripts/seed-phase4.ts`
|
||
|
||
### Priority: Add New Courses to Checkout
|
||
The `PRODUCTS` map in `src/app/api/learn/checkout/route.ts` needs entries for each new course that has a Polar price. Create Polar products first, then add `"course-{slug}": { priceId, name, metadata, tier: "one_time" }` to the map.
|
||
|
||
### Priority: Course Image / Thumbnail Art
|
||
Course cards have emoji + gradient placeholders. Need proper cover images stored in `public/courses/` or served via Gitea.
|
||
|
||
### Other Backlog
|
||
- **Gitea course sync** — `/root/falah-mobile/scripts/init-gitea-courses.sh` syncs course content from Gitea. Script exists but needs testing.
|
||
- **Server-side TTS generation** — Current Web Speech API is client-side. Could use Azure Cognitive Services or ElevenLabs for higher quality.
|
||
- **Certificate PDF design** — Current PDF generation in `src/lib/learn.ts` (functions: `generateCertificatePdf`, `generateSerialNumber`, `buildVerifyUrl`). Design may need polish.
|
||
- **Admin dashboard** — No admin UI for course management. Courses are seeded via DB scripts.
|
||
- **Course progress analytics** — No analytics on completion rates, quiz scores, popular courses.
|
||
|
||
---
|
||
|
||
## 📦 Tech Stack
|
||
|
||
| Layer | Technology |
|
||
|-------|-----------|
|
||
| **Framework** | Next.js 16 (App Router, React Server Components) |
|
||
| **Language** | TypeScript |
|
||
| **Database** | SQLite (production: `/app/data/dev.db` on Docker volume) |
|
||
| **ORM** | Prisma v5.22 (schema at `prisma/schema.prisma`) |
|
||
| **Auth** | Ummah ID (external service) — JWT delegation |
|
||
| **Styling** | Tailwind CSS, dark theme (`#07090C` bg, `#C9A84C` gold, `#00C48C` green) |
|
||
| **Payments** | Polar.sh (checkout API, webhooks) |
|
||
| **TTS** | Browser Web Speech API (`SpeechSynthesisUtterance`) |
|
||
| **Certificate PDF** | Generated server-side (see `src/lib/learn.ts`) |
|
||
| **Deployment** | Docker (standalone Next.js output) |
|
||
| **Reverse Proxy** | Traefik (routes `/mobile/*` → `falah-mobile:3000`) |
|
||
| **Host** | Contabo VPS (Ubuntu 24.04) |
|
||
| **Git** | Gitea at `git.falahos.my` |
|
||
|
||
---
|
||
|
||
## 🏗 Architecture
|
||
|
||
### Deployment Flow
|
||
```
|
||
Source: /root/falah-mobile/
|
||
→ npm run build (produces .next/standalone)
|
||
→ docker build -t falah-mobile:latest .
|
||
→ docker compose up -d --no-deps falah-mobile
|
||
```
|
||
|
||
### Route Structure (Next.js App Router, basePath: "/mobile")
|
||
```
|
||
/mobile
|
||
/learn ← Course catalog with search + category tabs (client)
|
||
/learn/[slug] ← Course detail with module timeline (client)
|
||
/learn/[slug]/[moduleId] ← Module reader: content + TTS + quiz (client)
|
||
/api/learn
|
||
/courses ← GET: list courses (supports ?category=&search=)
|
||
/courses/[slug] ← GET: course detail + modules + enrollment
|
||
/categories ← GET: list all categories
|
||
/categories/seed ← POST: seed categories (dev only)
|
||
/checkout ← POST: create Polar.sh checkout or mock purchase
|
||
/progress ← POST: mark module complete (auto-issues certificate at 100%)
|
||
/tts ← GET: module text; POST: request audio
|
||
/certificates ← GET: user's certificates
|
||
/certificates/[serial] ← GET: single certificate
|
||
/sync ← POST: sync from Gitea
|
||
```
|
||
|
||
### Key Source Files
|
||
| File | Purpose |
|
||
|------|---------|
|
||
| `prisma/schema.prisma` | All data models (LearnCourse, LearnModule, LearnEnrollment, etc.) |
|
||
| `src/app/learn/page.tsx` | Course catalog with category tabs + search |
|
||
| `src/app/learn/[slug]/page.tsx` | Course detail + timeline + certificate badge |
|
||
| `src/app/learn/[slug]/[moduleId]/page.tsx` | Module reader + TTS + quiz |
|
||
| `src/app/api/learn/courses/route.ts` | Course listing API with category/search/filter |
|
||
| `src/app/api/learn/courses/[slug]/route.ts` | Course detail API |
|
||
| `src/app/api/learn/categories/route.ts` | Categories API |
|
||
| `src/app/api/learn/checkout/route.ts` | Polar checkout (update PRODUCTS map for new courses!) |
|
||
| `src/app/api/learn/progress/route.ts` | Progress + certificate issuance |
|
||
| `src/app/api/learn/tts/route.ts` | TTS text endpoint |
|
||
| `src/app/api/learn/certificates/route.ts` | User certificates |
|
||
| `src/lib/learn.ts` | Certificate PDF generation, serial number |
|
||
| `src/lib/prisma.ts` | Prisma client singleton |
|
||
| `src/lib/auth.ts` | JWT auth middleware |
|
||
| `src/components/LearnPassCard.tsx` | Subscription monthly/annual toggle |
|
||
| `scripts/seed-phase4.ts` | Course seed template |
|
||
| `Dockerfile` | Builds standalone Next.js production image |
|
||
|
||
---
|
||
|
||
## 🔧 Key Skills for Continuation
|
||
|
||
1. **Prisma ORM with SQLite** — schema changes (`db push`), seed scripts, query patterns
|
||
2. **Next.js 16 App Router** — file-based routing, server/client components, API routes
|
||
3. **React (useState, useEffect, useCallback, useMemo)** — all frontend pages are client components
|
||
4. **Polar.sh API** — checkout creation, webhook handling, subscription management
|
||
5. **Docker deployment** — multi-stage build, volume mounts, compose orchestration
|
||
6. **Tailwind CSS** — theming (dark mode, custom color palette)
|
||
7. **Web Speech API** — browser TTS voice selection
|
||
8. **SQLite** — direct DB manipulation for quick data fixes (seed scripts, format migrations)
|
||
|
||
---
|
||
|
||
## ⚙️ Common Commands
|
||
|
||
```bash
|
||
cd /root/falah-mobile
|
||
|
||
# Build
|
||
npm run build
|
||
|
||
# Deploy
|
||
docker build -t falah-mobile:latest .
|
||
docker compose up -d --no-deps falah-mobile
|
||
|
||
# DB operations
|
||
docker cp falah-mobile-falah-mobile-1:/app/data/dev.db /tmp/dev.db
|
||
# edit /tmp/dev.db with sqlite3
|
||
docker cp /tmp/dev.db falah-mobile-falah-mobile-1:/app/data/dev.db
|
||
docker restart falah-mobile-falah-mobile-1
|
||
|
||
# Prisma schema change
|
||
npx prisma db push # applies schema changes to SQLite directly
|
||
|
||
# Check logs
|
||
docker logs falah-mobile-falah-mobile-1
|
||
|
||
# Seed categories endpoint (dev only, on rebuild)
|
||
curl -X POST https://falahos.my/mobile/api/learn/categories/seed
|
||
|
||
# API test
|
||
curl -s https://falahos.my/mobile/api/learn/courses | python3 -m json.tool
|
||
```
|
||
|
||
---
|
||
|
||
## 🐛 Known Issues
|
||
|
||
1. **Health check slow** — Docker health check for mobile container takes 30s+ to become "healthy", but API works immediately (HTTP 200).
|
||
2. **`.env` permission error** — Container logs show `EACCES: permission denied, open '/app/.env'` despite env vars being loaded correctly via Docker compose.
|
||
3. **New courses not individually purchasable** — Checkout `PRODUCTS` map only has 3 old courses mapped. New courses need Polar price IDs added.
|
||
4. **Staging shares volume** — `falah-mobile-staging` and `falah-mobile` production share the same DB volume. Restarting staging after production writes can cause DB contention.
|
||
5. **No category icon for course thumbnails** — Thumbnail uses category's icon/color gradient, but some courses may have missing visuals.
|
||
6. **Course card click doesn't navigate on course detail page** — Module cards have `router.push()` but the nested "Listen" button's `stopPropagation()` may cause issues. Direct URL navigation works (`/mobile/learn/{slug}/{module-slug}`).
|