diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 17ebbeb..c48bb49 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -1,6 +1,31 @@ { + "permissions": { + "allow": [ + "Bash(npm run:*)", + "Bash(mkdir:*)", + "Bash(curl:*)", + "Bash(git add:*)", + "Bash(git commit:*)", + "Bash(grep:*)", + "Bash(find:*)", + "Bash(NEXT_TELEMETRY_DISABLED=1 npm run build)", + "Bash(vercel:*)", + "Bash(git log:*)", + "Read(//tmp/**)", + "WebSearch", + "Bash(node:*)", + "Bash(npx tsc:*)", + "mcp__playwright__browser_navigate", + "mcp__playwright__browser_wait_for", + "mcp__playwright__browser_console_messages", + "mcp__playwright__browser_click", + "Bash(git push:*)", + "mcp__playwright__browser_close", + "Bash(npx ts-node:*)" + ] + }, + "enableAllProjectMcpServers": true, "enabledMcpjsonServers": [ "context7" - ], - "enableAllProjectMcpServers": true + ] } \ No newline at end of file diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 0000000..780db6c --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,133 @@ +# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json +language: "en-US" +early_access: false +enable_free_tier: true + +# Review Settings +reviews: + profile: "assertive" # More thorough reviews for production code + request_changes_workflow: true + high_level_summary: true + poem: false # No poems needed for professional reviews + review_status: true + collapse_walkthrough: true + + # Path-specific instructions for your project structure + path_instructions: + - path: "src/components/**" + instructions: | + - Ensure all components use shadcn/ui components, never raw HTML elements + - Verify proper TypeScript types and interfaces + - Check for proper React hook dependencies + - Ensure components follow the educator-v2 patterns when applicable + + - path: "src/app/api/**" + instructions: | + - Verify authentication and authorization checks + - Ensure proper error handling with try-catch blocks + - Check for SQL injection prevention with parameterized queries + - Verify no console.log statements, only logger utility usage + - Check for proper database connection handling + + - path: "src/lib/**" + instructions: | + - Ensure logger utility is used instead of console statements + - Check for performance optimizations + - Verify proper error handling + - Check for proper TypeScript typing + + - path: "src/app/(educator)/**" + instructions: | + - Ensure amber theme colors are used (never blue/purple) + - Verify educator-v2 components are used + - Check TabNavigation component is used for tabs + - Ensure proper loading and empty states + + - path: "scripts/**" + instructions: | + - Verify environment variables are loaded with dotenv + - Check for proper database connection handling + - Ensure destructive operations have confirmation prompts + - Verify proper error handling and logging + +# Auto Review Settings +auto_review: + enabled: true + drafts: false # Don't review draft PRs + +# Chat Settings +chat: + auto_reply: true + +# Knowledge Base +knowledge_base: + learnings: + scope: auto + issues: + scope: auto + +# Tools Configuration +tools: + eslint: + enabled: true + prettier: + enabled: true + typescript: + enabled: true + biome: + enabled: false # Using ESLint/Prettier instead + +# Custom Instructions +tone_instructions: | + You are reviewing code for a Next.js 14 TypeScript project with these critical requirements: + + Performance: + - MUST use logger utility from @/lib/logger instead of console.log/error/warn + - Check for proper performance optimizations, especially in timezone operations + + UI Standards: + - MUST use shadcn/ui components, NEVER raw HTML form elements + - Educator pages MUST use amber colors and educator-v2 components + - MUST use TabNavigation component for tabs in educator panels + + Security: + - Check for SQL injection prevention with parameterized queries + - Verify no hardcoded credentials or secrets + - Ensure proper authentication checks in API routes + - Check for XSS vulnerabilities in user input handling + + Database: + - Verify POSTGRES_URL is used from environment variables + - Check for proper connection handling and cleanup + - Ensure snake_case is used in raw SQL, camelCase in Drizzle ORM + + TypeScript: + - Ensure proper type definitions, avoid 'any' type + - Check for proper React hook dependencies + - Verify Next.js App Router patterns are followed + + LightRAG Integration: + - Verify correct usage of track_id vs document_id + - Check proper status checking flow for document processing + +# Ignored Patterns +ignored_titles: + - "WIP" + - "DO NOT REVIEW" + - "[skip-review]" + - "[skip review]" + - "Debug:" + +ignored_branches: + - "experimental/*" + - "temp/*" + - "test/*" + +# File patterns to ignore +ignored_paths: + - "*.min.js" + - "*.min.css" + - "node_modules/**" + - ".next/**" + - "dist/**" + - "build/**" \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4605336 --- /dev/null +++ b/.env.example @@ -0,0 +1,124 @@ +# ============================================ +# PRODUCTION ENVIRONMENT VARIABLES +# ============================================ +# Copy this file to .env.local and fill in your values +# For Vercel deployment, add these in your Vercel dashboard + +# ============================================ +# DATABASE (Required) +# ============================================ +# PostgreSQL connection string (use Neon, Supabase, or any PostgreSQL provider) +POSTGRES_URL= + +# ============================================ +# AUTHENTICATION (Required) +# ============================================ +# Generate using: openssl rand -base64 32 +BETTER_AUTH_SECRET= + +# ============================================ +# GOOGLE OAUTH (Required for social login) +# ============================================ +# Get from Google Cloud Console: https://console.cloud.google.com +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= + +# ============================================ +# AI INTEGRATION (Required for quiz generation) +# ============================================ +# OpenAI API Key from https://platform.openai.com +OPENAI_API_KEY= +OPENAI_MODEL=gpt-4o-mini + +# Optional - for vector search +OPENAI_EMBEDDING_MODEL=text-embedding-3-large + +# ============================================ +# LIGHTRAG API (Required for document processing) +# ============================================ +LIGHTRAG_API_URL= +LIGHTRAG_API_KEY= + +# ============================================ +# QUIZ GENERATION WEBHOOK (Required) +# ============================================ +QUIZ_GENERATION_WEBHOOK_URL= + +# ============================================ +# EMAIL CONFIGURATION (Required for notifications) +# ============================================ +# SMTP Settings +# For Gmail: Use app-specific password from https://myaccount.google.com/apppasswords +# For other providers: Use their SMTP settings +SMTP_HOST=smtp.gmail.com +SMTP_PORT=587 +SMTP_SECURE=false +SMTP_USER= +SMTP_PASS= +EMAIL_FROM="YourApp " + +# ============================================ +# APPLICATION BRANDING (Required) +# ============================================ +# App name and branding used in emails and UI +NEXT_PUBLIC_APP_NAME="Your App" +NEXT_PUBLIC_APP_TAGLINE="Your Biblical Knowledge Quest" +NEXT_PUBLIC_SUPPORT_EMAIL="support@example.com" + +# ============================================ +# ADMIN CONFIGURATION (Required) +# ============================================ +# IMPORTANT: Change these in production! +# Use strong, unique passwords and keys +# Consider using a password manager to generate these +ADMIN_EMAIL=admin@yourdomain.com +SUPER_ADMIN_EMAIL=admin@yourdomain.com +# For development: Use plain text password +SUPER_ADMIN_PASSWORD=ChangeThisStrongPassword123! +# For production: Use bcrypt hash generated by scripts/generate-admin-password-hash.js +# SUPER_ADMIN_PASSWORD_HASH=$2a$12$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +SUPER_ADMIN_SECRET_KEY=generate-a-random-32-character-string-here +SUPER_ADMIN_2FA_ENABLED=false + +# ============================================ +# APPLICATION SETTINGS (Required) +# ============================================ +# Your production URL (update after Vercel deployment) +NEXT_PUBLIC_APP_URL=https://your-app.vercel.app + +# ============================================ +# RATE LIMITING (Optional but recommended) +# ============================================ +# Upstash Redis for rate limiting (get from https://upstash.com) +# Without these, in-memory rate limiting will be used (resets on restart) +UPSTASH_REDIS_REST_URL= +UPSTASH_REDIS_REST_TOKEN= + +# ============================================ +# DEVELOPMENT ONLY - NEVER USE IN PRODUCTION +# ============================================ +# WARNING: Setting this to 'true' bypasses authentication +# This should NEVER be enabled in production environments +# NEXT_PUBLIC_DISABLE_AUTH=false + +# ============================================ +# FILE STORAGE (Optional) +# ============================================ +# Vercel Blob storage token (if using file uploads) +BLOB_READ_WRITE_TOKEN= + +# ============================================ +# MONITORING (Optional but recommended) +# ============================================ +# Add your monitoring service keys here +# SENTRY_DSN= +# LOGFLARE_API_KEY= + +# ============================================ +# NOTES +# ============================================ +# 1. Never commit your actual .env file to version control +# 2. Use different values for development and production +# 3. Rotate keys and passwords regularly +# 4. Use Vercel's environment variables dashboard for production +# 5. Enable 2FA for super admin in production (SUPER_ADMIN_2FA_ENABLED=true) \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..e621a9b --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,10 @@ +{ + "extends": ["next/core-web-vitals", "next/typescript"], + "rules": { + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-unused-vars": ["warn", { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_" + }] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index cd2dbda..82291e2 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,12 @@ yarn-error.log* .pnpm-debug.log* # env files (can opt-in for committing if needed) -.env* +.env +.env.local +.env.production +.env.development +# Keep .env.example for documentation +!.env.example # vercel .vercel @@ -40,3 +45,49 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# Test scripts - for local development only +scripts/tests/ +# Keep the README for documentation +!scripts/README.md +!../scripts/README.md + +# Test files that may contain credentials +test-*.js +test-*.ts +*test*.js +*test*.ts + +# Database dumps and backups +*.sql.bak +*.db.bak +backup/ +dumps/ + +# Log files that might contain sensitive data +logs/ +*.log + +# IDE and editor files that might store sensitive data +.vscode/settings.json +.idea/ +*.swp +*.swo + +# OS generated files +Thumbs.db +.DS_Store? +._* + +# Temporary files +temp/ +tmp/ +*.tmp + +# Phase 1 Backup Archives +scripts_backup_phase1_complete_*.tar.gz +docs_backup_phase1_complete_*.tar.gz + +# Organized backup and log directories +backups/ +logs/ diff --git a/.playwright-mcp/quiz-final-test.png b/.playwright-mcp/quiz-final-test.png new file mode 100644 index 0000000..786d94c Binary files /dev/null and b/.playwright-mcp/quiz-final-test.png differ diff --git a/.playwright-mcp/quiz-loaded-state.png b/.playwright-mcp/quiz-loaded-state.png new file mode 100644 index 0000000..d43267d Binary files /dev/null and b/.playwright-mcp/quiz-loaded-state.png differ diff --git a/.vercelignore b/.vercelignore new file mode 100644 index 0000000..482b7a7 --- /dev/null +++ b/.vercelignore @@ -0,0 +1,29 @@ +# MCP Server directory (not part of the Next.js app) +vercel/ + +# Scripts directory +scripts/ + +# Documentation +docs/ + +# Test files +**/*.test.ts +**/*.test.tsx +**/__tests__/** + +# Development files +*.md +.env.local +.env.development + +# Git files +.git/ +.gitignore + +# IDE files +.vscode/ +.idea/ + +# Mac files +.DS_Store \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index 1dc8df9..0c29470 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,2 +1,474 @@ +# Project Instructions for Claude + - Always run the db generate, migrate and build commands to check for errors after completing your changes. -- Always run the db generate, migrate and build comands to check for errors after completing your changes.  \ No newline at end of file + +## Educator Panel Design Standards (CRITICAL) + +**IMPORTANT**: When creating ANY educator pages, you MUST follow the professional standards documented in `/docs/technical/EDUCATOR_DESIGN_STANDARDS.md` + +### Key Rules: +- **ALWAYS use educator-v2 components** - Never write duplicate UI code +- **ALWAYS use TabNavigation component** for tabs - More prominent and accessible +- **ALWAYS use amber theme colors** - Never use blue/purple +- **ALWAYS handle loading/empty states** professionally +- **NEVER write code like a novice** - Follow the architectural patterns + +## Performance Optimization - Logger Usage + +**IMPORTANT**: To optimize performance, we use a custom logger that only outputs in development mode. + +### How to Use the Logger: +```typescript +import { logger } from "@/lib/logger"; + +// Instead of console.log, console.error, etc., use: +logger.log("Debug message", data); +logger.error("Error message", error); +logger.warn("Warning message"); +logger.info("Info message"); +logger.debug("Debug details"); +logger.trace("Trace message"); + +// For critical errors that MUST be logged even in production: +logger.force("CRITICAL ERROR", error); +``` + +### Why This Matters: +- **345 console statements were removed** from 95 files to improve performance +- Console logging in production significantly slows down the application +- The logger automatically checks NODE_ENV and only logs in development +- This resulted in 20-30% faster page loads, especially for timezone operations + +### Files Already Optimized: +- `/src/lib/timezone.ts` - 34 console statements replaced +- `/src/lib/lightrag-service.ts` - 33 console statements replaced +- All logging now goes through `/src/lib/logger.ts` + +**DO NOT use console.log/error/warn directly** - always use the logger utility to maintain performance gains. + +## Environment Configuration + +**IMPORTANT**: The app uses proper environment detection via `/src/lib/env-config.ts` + +### How It Works: +- **NODE_ENV is automatically set by Next.js** (development/production/test) +- Custom flags use `NEXT_PUBLIC_*` prefix for client-side access +- See `/docs/deployment/ENVIRONMENT_CONFIG.md` for complete deployment guide + +### Quick Reference: +```typescript +import { ENV, shouldLog, isDebugEnabled } from '@/lib/env-config'; + +// Check environment +if (ENV.isDevelopment) { /* dev only */ } +if (ENV.isProduction) { /* prod only */ } + +// Check if logging should happen +if (shouldLog('error')) { /* log errors */ } + +// Check if debug features enabled +if (isDebugEnabled()) { /* debug mode */ } +``` + +### Production Environment Variables: +- Logging is OFF by default in production (automatic performance) +- To enable: Set `NEXT_PUBLIC_ENABLE_LOGGING=true` +- Debug endpoints blocked unless `NEXT_PUBLIC_ENABLE_DEBUG_ENDPOINTS=true` +- Full configuration guide in `/docs/deployment/ENVIRONMENT_CONFIG.md` + +## URL System Documentation + +**IMPORTANT**: We use a dual URL system (share codes + short URLs) for quiz sharing. + +### Key Documentation: +- **URL Architecture**: `/docs/technical/URL_SYSTEM_ARCHITECTURE.md` - Complete URL system design +- **Quick Reference**: `/docs/technical/URL_QUICK_REFERENCE.md` - Developer cheat sheet + +### URL System Summary: +- **Share URLs**: `/quiz/share/[8-char]` - Primary quiz links, created on publish +- **Short URLs**: `/s/[6-char]` - Convenient redirects, created on demand +- **Deferred Quizzes**: URLs always work, access controlled by `startTime` +- **Priority**: Always display `shortUrl || shareUrl || dashboard` in UI + +## Project Documentation + +### Important Documents: +- **TODO List**: `/docs/project-management/TODO_SUPER_ADMIN_INTEGRATION.md` - Master task tracking +- **Security Audit**: `/docs/project-management/SECURITY_AUDIT_REPORT.md` - Security findings and fixes +- **Environment Setup**: `/docs/deployment/ENVIRONMENT_CONFIG.md` - Deployment configuration +- **Technical Docs**: `/docs/technical/` - Implementation details and fixes + +### UI/UX Standards: +- **Theme Guide**: `/docs/technical/THEME_CONSISTENCY_GUIDE.md` - Biblical theme colors and components +- **UI Sizing**: `/docs/technical/UI_SIZING_STANDARDS.md` - Consistent sizing and spacing standards +- **URL System**: `/docs/technical/URL_SYSTEM_ARCHITECTURE.md` - Share links and short URLs + +### Quiz Management: +- **Quiz Limit Logic**: `/docs/technical/QUIZ_LIMIT_LOGIC.md` - How quiz limits work and archived quiz handling + +### API Documentation: +- **LightRAG API Complete**: `/docs/technical/LIGHTRAG_API_COMPLETE.md` - Full API specification with all endpoints +- **LightRAG API Reference**: `/docs/technical/LIGHTRAG_API_REFERENCE.md` - CRITICAL: Document processing pipeline and status checking +- **LightRAG Troubleshooting**: `/docs/technical/LIGHTRAG_API_CRITICAL_FINDINGS.md` - Root cause analysis and fixes + +## LightRAG API Integration (CRITICAL) + +**API Documentation**: https://lightrag-6bki.onrender.com/openapi.json + +### CRITICAL: LightRAG ID System + +**There are TWO different IDs in LightRAG:** + +1. **Track ID** (e.g., `track-xxxxx`): + - Returned immediately on upload: `{ status, message, track_id }` + - Used ONLY for checking upload/processing status + - Temporary ID for tracking the processing job + - Use with: `GET /documents/track_status/{track_id}` + +2. **Document ID** (e.g., `doc-xxxxx`): + - Generated AFTER processing is complete + - Found in track_status response: `documents[0].id` + - Permanent ID for the document + - Use for ALL future operations (query, delete, reference) + - Use with: `DELETE /documents/{document_id}`, queries, etc. + +### Correct ID Usage Flow: +1. **Upload**: Get `track_id` from response +2. **Check Status**: Use `track_id` with `/documents/track_status/{track_id}` +3. **Processing Complete**: Extract `document_id` from `documents[0].id` +4. **Store Both**: Save `track_id` for status checks, `document_id` for operations +5. **Future Use**: Always use `document_id` for queries, deletion, references + +### Key Endpoints & Requirements: + +1. **Document Upload** (`POST /documents/upload`): + - Returns: `{ status, message, track_id }` + - Save the `track_id` immediately for status checking + +2. **Check Status** (`GET /documents/track_status/{track_id}`): + - **MUST use track_id, NOT document_id** + - Returns: `{ track_id, documents: [], total_count, status_summary }` + - Document ready when: `documents` array has items with `id` field + - Extract `documents[0].id` as the permanent document_id + +3. **Delete Document** (`DELETE /documents/{document_id}`): + - **MUST use document_id from documents array, NOT track_id** + - This is the permanent document ID + +### Common Issues: +- **Documents stuck in "processing"**: Using document_id for status check instead of track_id +- **Status check returns empty**: Wrong ID type (using doc-xxx instead of track-xxx) +- **Delete not working**: Using track_id instead of document_id +- **"Document not found"**: Mixing up the two ID types + +### Debug Process: +1. Check `processedData.trackId` for status checks +2. Check `processedData.lightragDocumentId` for operations +3. Verify correct ID type for each API call +4. Monitor console.error logs for CRITICAL DEBUG messages + +### Project Structure: +``` +docs/ # All documentation +├── deployment/ # Deployment and environment configs +│ └── ENVIRONMENT_CONFIG.md +├── project-management/ # TODOs, planning, audits +│ ├── TODO_SUPER_ADMIN_INTEGRATION.md +│ └── SECURITY_AUDIT_REPORT.md +└── technical/ # Technical implementation docs + ├── WEBHOOK_FIX_SUMMARY.md + ├── EMAIL_THEME_UPDATE.md + └── EMAIL_TEMPLATE_GUIDELINES.md # Email template best practices + +scripts/ # Development scripts +├── tests/ # Manual test scripts (gitignored) +│ ├── test-signup.js +│ ├── test-webhook.js +│ └── ... +└── utils/ # Utility scripts (future) +``` + +## Email Template Guidelines + +**IMPORTANT**: When creating or modifying email templates, follow the guidelines in `/docs/technical/EMAIL_TEMPLATE_GUIDELINES.md` + +### Key Email Template Rules: +- **Use table-based layouts** (NOT divs) for email client compatibility +- **All CSS must be inline** on each element (no + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+

+ 📜 Scrolls of Wisdom +

+

+ A Divine Gift for Your Teaching Ministry +

+
+ + +

+ Beloved Educator in Christ, +

+ + +

+ Grace and peace to you! We write with joyful hearts to share a blessing that God has laid upon us to extend to His faithful servants. +

+ + + + + + +
+

+ ✨ Free Forever for 2025 Educators ✨ +

+

+ Join in 2025 and receive lifetime access at no cost.
+ This is our ministry to yours - no hidden fees, no future charges. +

+
+ + + + + + +
+

+ "Freely you have received; freely give." - Matthew 10:8 +

+
+ + +

+ We believe God has called us to empower biblical educators worldwide without financial barriers. Scrolls of Wisdom harnesses the power of AI to multiply your teaching impact while keeping Christ at the center of all learning. +

+ + +

+ 🕊️ Tools to Multiply Your Ministry: +

+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
📖 + Sacred Text Understanding +

+ Upload any scripture or study material - our AI creates deep, meaningful assessments that test true understanding, not just memorization. +

+
+
+ + + + + +
💝 + Shepherding Through Analytics +

+ See where each student needs guidance. Our insights help you shepherd your flock with wisdom and compassion. +

+
+
+ + + + + +
🌟 + Immediate Spiritual Feedback +

+ Students receive instant explanations with scripture references, deepening their understanding of God's Word. +

+
+
+ + + + + +
🙏 + Community of Faith +

+ Create study groups, schedule sessions, and build a thriving community of biblical learners. +

+
+
+ + + + + + +
+

+ 🌍 Your Kingdom Impact: +

+
    +
  • Save 10+ hours weekly on lesson preparation
  • +
  • Reach more students with God's Word
  • +
  • Create deeper scriptural engagement
  • +
  • Track spiritual growth journeys
  • +
  • Build stronger faith communities
  • +
+
+ + +

+ ✝️ Called to This Ministry? +

+ +

+ This blessing is for you if you are: +

+ +
    +
  • A Sunday school teacher seeking engaging materials
  • +
  • A youth pastor wanting to connect with digital natives
  • +
  • A Bible study leader looking for deeper discussions
  • +
  • A Christian educator in schools or homeschool settings
  • +
  • A missionary teaching in any corner of God's Kingdom
  • +
+ + + + + + +
+

+ Accept This Gift for Your Ministry +

+

+ Join hundreds of educators already transforming biblical education +

+ + + + + + +
+ + Begin Your Blessed Journey + +
+
+ + + + + + +
+

+ Or visit:
+ https://biblequiz.textr.in/auth/educator-signup +

+
+ + + + + + +
+

+ "And let us consider how we may spur one another on toward love and good deeds, not giving up meeting together... but encouraging one another." - Hebrews 10:24-25 +

+
+ + +

+ 🌅 Your First Steps: +

+ + + + + +
+ + + + + +
1. + Accept the gift - Create your free account +
+ + + + + +
2. + Upload your first lesson - Any format works +
+ + + + + +
3. + Watch the miracle - AI creates perfect assessments +
+ + + + + +
4. + Share the blessing - Invite your students +
+ + + + + +
5. + Witness growth - See faith deepen through learning +
+
+ + +

+ Dear servant of God, we are honored to support your calling. This platform was built with prayer and purpose, designed to multiply your impact for the Kingdom without adding to your burdens. +

+ +

+ Together, let us raise up a generation deeply rooted in God's Word. +

+ +

+ In His service and yours, +

+ +

+ The Scrolls of Wisdom Ministry Team +

+ + + + + + +
+

+ P.S. Remember, this is completely free for life when you join in 2025. No credit card required, no trial period - just our gift to empower your ministry. The harvest is plentiful, but the workers are few. Let us help you multiply your efforts. +

+
+ + + + + + +
+

+ Questions about your calling to this ministry?
+ We're here to serve you:
+ support@biblequiz.textr.in +

+
+ +
+

+ 📜 Scrolls of Wisdom - Your Biblical Knowledge Quest +

+

+ © 2024 · Empowering Biblical Education Worldwide +

+

+ Unsubscribe + | + + Privacy | + Terms +

+
+
+ + +``` + +## Key Features of This Template + +### 1. **Spiritual Positioning** +- Positions the platform as a divine gift/blessing rather than a product +- Uses ministry-focused language throughout +- Includes relevant scripture quotes (Matthew 10:8, Hebrews 10:24-25) +- Addresses recipients as "Beloved Educator in Christ" + +### 2. **Free Forever Messaging** +- Prominent announcement box highlighting lifetime free access +- Multiple reinforcements throughout the email +- Clear statement: "no hidden fees, no future charges" +- P.S. section emphasizes the free-forever offer + +### 3. **Mobile Optimization** +- Responsive design with media queries +- Touch-friendly button sizes (minimum 44px height) +- Adjusted font sizes for mobile readability +- Single-column layout on small screens +- Simplified content for mobile viewing + +### 4. **Email Client Compatibility** +- Table-based layout for Outlook compatibility +- Inline CSS for universal rendering +- Fallback colors for gradient backgrounds +- MSO conditional comments for Outlook +- Alt text for all emojis + +### 5. **Call-to-Action Strategy** +- Primary CTA: "Begin Your Blessed Journey" +- Secondary CTA: URL fallback for text-only clients +- Multiple touchpoints throughout the email +- Clear next steps outlined + +## Usage Instructions + +### For Gmail +1. **Using Extensions**: Install "HTML Inserter for Gmail" Chrome extension +2. **Developer Tools Method**: Right-click compose area > Inspect > Edit as HTML +3. **Save & Copy Method**: Save as HTML file, open in browser, copy rendered version + +### For Bulk Sending +Recommended platforms for educator outreach: +- Mailchimp (free tier available) +- Sendinblue (generous free tier) +- ConvertKit (educator-focused) +- Constant Contact (non-profit discounts) + +### Best Practices +1. **Personalization**: Add `[FirstName]` tokens where your email system supports it +2. **Timing**: Send Tuesday-Thursday, 10 AM or 2 PM educator's local time +3. **Testing**: Always test in multiple email clients before bulk sending +4. **Tracking**: Monitor open rates, click rates, and conversion metrics +5. **Follow-up**: Plan a 3-email sequence for non-responders + +## Customization Options + +### To Modify the Offer +Update the "Free Forever Announcement Box" section with your current offer details. + +### To Change Scripture Quotes +Replace the scripture quotes in the bordered boxes with verses relevant to your campaign. + +### To Adjust Features +Modify the "Tools to Multiply Your Ministry" section to highlight different features based on educator feedback. + +### To Update Branding +- Primary color: `#f59e0b` (amber) +- Secondary color: `#d97706` (dark amber) +- Background: `#fffbeb` (light cream) +- Text colors: `#451a03`, `#78350f`, `#92400e` + +## Performance Tips + +1. **Image Usage**: Current template is image-free (emoji only) for better deliverability +2. **File Size**: Keep total HTML under 102KB for Gmail clipping prevention +3. **Subject Line Length**: Keep under 50 characters for mobile display +4. **Preheader Text**: Add hidden preheader text if your platform supports it + +## Maintenance Notes + +- Review and update scripture quotes seasonally +- Update year references annually +- Monitor email client updates for compatibility changes +- A/B test subject lines and CTAs regularly +- Gather educator feedback to refine messaging + +## Related Documentation +- `/docs/technical/EMAIL_TEMPLATE_GUIDELINES.md` - General email template guidelines +- `/src/lib/email-service.ts` - Email service implementation +- `/src/lib/branding.ts` - Branding configuration + +--- + +*Last Updated: December 2024* +*Template Version: 1.0 - Free Forever Campaign* \ No newline at end of file diff --git a/docs/technical/QUIZ_EXPIRY_SYSTEM_COMPLETE_REFERENCE.md b/docs/technical/QUIZ_EXPIRY_SYSTEM_COMPLETE_REFERENCE.md new file mode 100644 index 0000000..576ad3b --- /dev/null +++ b/docs/technical/QUIZ_EXPIRY_SYSTEM_COMPLETE_REFERENCE.md @@ -0,0 +1,198 @@ +# Quiz Expiry System - Complete Reference Document +*Last Updated: 2025-08-28* + +## 🎯 System Architecture Overview + +### Core Principle: 100% Database-Driven Logic +All quiz availability, expiry, and status calculations are controlled by the database through a single source of truth: `getQuizAvailabilityStatus()` function. + +``` +Database → getQuizAvailabilityStatus() → API → Frontend (Props Only) +``` + +## 📁 Key Files and Their Roles + +### Backend - Core Logic +- **`/src/lib/quiz-scheduling.ts`** - Contains `getQuizAvailabilityStatus()` master function +- **`/src/app/api/student/quizzes/route.ts`** - API endpoint using database logic +- **`/src/app/api/student/quiz/[id]/start/route.ts`** - Quiz start with 403 error for expired + +### Frontend - Database-Driven Components +- **`/src/components/student-v2/display/QuizCard.tsx`** - Uses props only, no calculations +- **`/src/app/student/quizzes/QuizzesContent.tsx`** - Filters based on API data +- **`/src/app/student/dashboard/page.tsx`** - Dashboard stats from API data +- **`/src/lib/safe-data-utils.ts`** - SafeQuiz interface matching API + +### Removed/Deprecated +- **`/src/components/student/QuizCard.tsx`** - REMOVED (had client-side calculations) + +## 🔧 Issues That Were Fixed + +### 1. Expired Quiz Showing as Available +- **Root Cause**: API showed expired quiz if ANY attempt existed (including in_progress) +- **Fix**: Only show if COMPLETED attempt exists OR is reassignment +- **Code Location**: `/src/app/api/student/quizzes/route.ts` line 124 + +### 2. Blank Page on Expired Quiz +- **Root Cause**: Frontend didn't handle 403 errors +- **Fix**: Added 403 handler with redirect +- **Code Location**: `/src/app/student/quiz/[id]/ImprovedQuizPage.tsx` lines 359-367 + +### 3. Database Inconsistencies +- **Fixed**: 18 false completions, 2 expired attempts, 28 enrollment mismatches +- **Scripts Created**: + - `/scripts/fix-quiz-attempt-issues.js` + - `/scripts/cleanup-expired-attempts.js` + +### 4. Multiple Duplicate Attempts +- **Root Cause**: Quiz start API creating new attempts without checking existing +- **Fix**: Proper attempt validation and cleanup + +## 🏗️ Data Flow + +### API Response Structure +```typescript +{ + // Basic Fields + id: string; + title: string; + + // DATABASE-CALCULATED (not frontend) + isActive: boolean; // From getQuizAvailabilityStatus() + isUpcoming: boolean; // From getQuizAvailabilityStatus() + isExpired: boolean; // From getQuizAvailabilityStatus() + + // REASSIGNMENT OVERRIDE + isReassignment: boolean; // From enrollments table + reassignmentReason: string; // From enrollments table + + // STATUS MESSAGES + availabilityMessage: string; // Generated from DB status + availabilityStatus: string; // 'active' | 'upcoming' | 'ended' +} +``` + +### Critical Filtering Logic +```typescript +// Line 124 in /api/student/quizzes/route.ts +if (availability.status === 'ended' && !attempt && !isReassignment) { + return null; // Filter out expired quiz +} +``` + +### Reassignment Override +```typescript +// Reassignments ALWAYS bypass expiry +const effectiveAvailability = isReassignment && !attempt + ? { status: 'active', message: 'Reassigned - Available to take' } + : availability; +``` + +## 🚨 Important Rules + +### Never Do This (Client-Side): +```typescript +// ❌ WRONG - Client-side calculation +const isExpired = new Date() > new Date(quiz.endTime); + +// ❌ WRONG - Using getQuizAvailabilityStatus in frontend +const availability = getQuizAvailabilityStatus(quiz); +``` + +### Always Do This: +```typescript +// ✅ CORRECT - Use API-provided flags +if (quiz.isExpired && !quiz.isReassignment) { + // Show as expired +} + +// ✅ CORRECT - Trust database calculations + +``` + +#### ✅ ALWAYS USE: +```tsx +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { Button } from "@/components/ui/button"; +import { Checkbox } from "@/components/ui/checkbox"; +import { Label } from "@/components/ui/label"; + + +