
Mengenang Pahlawan (Remembering Heroes) is an AI-powered educational platform that transforms how Indonesians learn about their national heroes. It combines a comprehensive biographical database, interactive AI-simulated conversations with historical figures, gamified quizzes with daily point caps, and real-time tracking—all wrapped in a modern, responsive interface.
Why it matters
- Educational gamification: Daily quiz limits (5 per day) with point breakdowns (base points + perfect bonus + first-try bonus) encourage consistent learning without burnout.
- AI with guardrails: OpenAI-powered chat simulates conversations with heroes, but strict relevance checking prevents off-topic discussions—ensuring educational value.
- Smart recommendations: LLM analyzes viewing history, era, and themes to suggest related heroes—keeping users engaged across different periods.
- Real-time everything: Convex backend provides instant updates for points, quiz results, and profile changes without page refreshes.
- Multi-channel engagement: Resend emails with beautiful React Email templates for OTP verification, password resets, and quiz result summaries.
How it works (brief)
- Authentication: Users sign up via GitHub OAuth or email/password with OTP verification. Convex Auth manages sessions and email verification flows.
- Explore heroes: Browse 200+ heroes filtered by 5 eras (Colonial War, National Movement, Japanese Occupation, Revolution & Old Order, Post-1966) or search by name/aliases.
- Interactive learning: Each hero has detailed slides (biography summary + key facts), sources, timeline (birth/death), education, legacy, and official recognition details.
- AI conversations: Chat with simulated hero personas—OpenAI generates contextual responses based on biographical data, maintaining first-person narrative while clearly labeling facts vs. interpretation.
- Daily quizzes: Auto-generated multiple-choice questions (birth year, birthplace, era, recognition basis, historical highlights) with 3 options each. Earn 10 points per correct answer, +10 for perfect score, +3 for first-try bonus. After 5 scored quizzes, enter practice mode (no points).
- Points tracking: Real-time points badge with tooltip history, detailed modal showing all quiz attempts with breakdowns, and email summaries after each quiz.
Stack
- Frontend: React 19 + TypeScript, Wouter (routing)
- UI: Mantine 8 (charts, forms, modals, notifications) + Tailwind CSS 4 + Radix UI primitives
- Backend: Convex (serverless functions, real-time queries, HTTP routes, scheduling)
- Auth: Convex Auth (GitHub provider + Password with OTP)
- Email: Resend (OTP, password reset, quiz results) with React Email templates
- LLM: OpenAI (GPT-4o-mini for chat, recommendations, quiz generation)
- Build: Rsbuild + TypeScript + Biome (linting/formatting)
Key features deep-dive
1. Smart quiz generation
Quizzes are dynamically built from hero data using a “decoy bank” system:
- Birth year questions: Correct year + two nearby years as options
- Birthplace questions: Correct place + two random places from other heroes
- Era questions: Correct era + two other eras from the 5 available
- Recognition basis: Correct presidential decree basis + two from other heroes
- Highlights: True statement about the hero + two statements from other heroes
Each quiz shuffles questions and options to prevent memorization.
2. AI chat with educational guardrails
Two-stage LLM process ensures relevance:
- Judgment phase: LLM determines if the question is relevant to the hero (biographical questions, historical context, comparisons). Special handling for pronouns (“you/your”) and generic biographical questions (spouse, children, education).
- Response phase: If relevant, LLM generates first-person response clearly labeled as “[Fakta]” (facts from data) and “[Interpretasi]” (interpretive narrative). If irrelevant, politely redirects to hero-related topics.
Example flow:
- User: “Siapa istri kamu?” (Who is your wife?)
- System: Recognizes pronoun + biographical question → Relevant
- AI: “Ini simulasi edukatif…\n[Fakta] — [data from biography]\n[Interpretasi] — [first-person narrative about family life]“
3. Gamified points system
Daily cap prevents addiction while encouraging consistency:
- 5 scored quizzes per day (resets at 00:00 Singapore timezone)
- Point breakdown: Base (10 x correct answers) + Perfect (+10 if all correct) + First-try (+3)
- Practice mode: After daily cap or repeat hero on same day, quizzes still work but award 0 points
- Email receipts: Every quiz sends a Resend email with formatted results, breakdown, and timestamp
- History tracking: Modal shows all attempts with date, hero, score, points, and practice indicator
4. Real-time architecture
Convex powers instant updates:
- Optimistic UI: Points update immediately on quiz completion
- Live queries: Hero list, filters, and detail pages react to database changes
- Scheduled actions: Email sends are queued via
ctx.scheduler.runAfter()to avoid blocking mutations - Type-safe: Convex generates TypeScript types from schema for end-to-end safety
5. Multi-era filtering
Heroes are categorized by their primary era of struggle:
- Perang Kolonial (Colonial War, pre-1900)
- Pergerakan Nasional (National Movement, 1900-1942)
- Pendudukan Jepang (Japanese Occupation, 1942-1945)
- Revolusi & Orde Lama (Revolution & Old Order, 1945-1966)
- Sesudah 1966 (Post-1966)
Era is auto-inferred from birth year during data import but can be manually overridden.
Architecture highlights
Database schema (Convex tables)
- users: Extended Convex Auth user table with name, avatar storage ID, and email verification timestamp
- heroes: Slug, name, era, portrait URL, biography slides, sources, titles, birth/death, education, legacy, recognition decree, raw JSON
- quizAttempts: User + hero slug + total/correct + timestamp (audit trail)
- quizPoints: User + total points + last updated timestamp
- quizDaily: User + day (YYYY-MM-DD) + scored count + hero slugs attempted + perfect indicator
- quizAwards: User + hero slug + points awarded + breakdown + practice flag + timestamp
Authentication flow
- Sign up/Sign in: Email/password or GitHub OAuth
- Email verification: If email unverified, redirect to
/verify-email?email=...and send OTP via Resend - Password reset: User requests code → OTP sent → redirect to
/reset-password?email=...→ confirm new password - Route guards: Auth pages (login/register) redirect to
/pahlawanif logged in; dashboard pages redirect to/loginif not authenticated
LLM integration patterns
All LLM calls are Convex Actions (server-side only):
- agent.ts:
recommendHeroes(analyze viewing history + hero data → suggest 3 related heroes),chatAsHero(simulate conversation with relevance checking) - ai.ts:
generateForHero(build quiz questions from biographical data) - llm.ts: Reusable OpenAI client with
responses.create()API (platform-agnostic; supports custom base URLs)
No API keys exposed to client; all requests authenticated via Convex Auth.
Why this approach works
- Structured data + AI flexibility: Biographical facts come from curated JSON; AI adds conversational layer without hallucination risk.
- Daily caps: Prevent burnout and gaming the system while maintaining engagement.
- Email touchpoints: Reinforce learning via post-quiz summaries sent to inbox.
- Multi-modal learning: Read biographies → Chat with simulated persona → Test knowledge via quiz → Track progress.
- Mobile-first UI: Mantine + Tailwind ensures responsive experience on phones/tablets.
Future possibilities
- Voice narration of biographies (text-to-speech)
- Spaced repetition for quiz questions
- Social features: leaderboards, achievements, hero “collections”
- AR overlays at historical sites
- Multi-language support (English, Javanese, Sundanese)