AI-powered educational platform built with Angular 19 and Firebase. Features intelligent RAG-based learning assistant, adaptive exam system, and comprehensive admin dashboard for content management.
This repository demonstrates a complete AI-driven learning platform with three core layers:
- AI-Powered Learning (RAG System): Context-aware chat with PDF-based knowledge, section-specific retrieval, and session persistence (see implementation โ)
- Knowledge Assessment: Timed exams with auto-save, resume capability, and intelligent question shuffling to validate learning
- Content Management: Admin dashboard for managing Teachers (modules), Courses, Exams, and student analytics
| Role | Capabilities | Routes |
|---|---|---|
| Admin | Full CRUD on Teachers, Courses, Exams + Dashboard access | /crud, /course-crud, /exam-crud, /main |
| Students | View educational content, take exams, chat with AI teacher | /teacher/:id, /exam/:id, /pdf-viewer |
- Smart Shuffling: Questions and answers randomized per attempt
- Live Progress Tracking: Every answer auto-saved to Firestore
- Resume Capability: Interrupted exams continue with correct time calculation
- Timer Management:
- Exam duration (
timeToDoTheExam) - Retry cooldown (
timeToWait)
- Exam duration (
- Instant Results: Pass/fail based on configurable
passingPercentage
- Teachers Management: Educational modules with PDF content and section mapping
- Courses Management: Difficulty levels, date ranges, teacher assignments
- Exams Management: Multiple-choice questions with 2-6 answer options
- Results Analytics: Student performance tracking across exams
- PDF viewer for educational materials
- Section-based navigation with page mapping
This platform integrates with a sophisticated RAG (Retrieval-Augmented Generation) backend for the Teacher chat interface, featuring several production-grade optimizations:
sequenceDiagram
participant U as User (Angular)
participant F as Frontend
participant B as FastAPI Backend
participant V as Vector Store
participant L as LLM (OpenAI/Claude)
U->>F: "What is informed consent?"
F->>B: POST /stream_chat<br/>{message, session_id, pages: [10-15]}
B->>B: Load conversation history
B->>L: Reformulate question with context
L-->>B: "What is informed consent in business ethics?"
B->>V: Search similarity (k=14, filter: pages 10-15)
V-->>B: Return 14 relevant chunks
B->>L: Generate response (streaming)
loop Stream chunks
L-->>B: Token chunk
B-->>F: SSE chunk
F-->>U: Display in real-time
end
B->>B: Save to session history
Traditional RAG searches entire documents, leading to context noise. Our approach:
# Smart filtering by current section
retriever = vector_store.as_retriever(
search_kwargs={
"k": 14, # Top-14 most relevant chunks
"filter": {
"source": current_pdf_path,
"page": {"$in": current_section_pages} # Section-specific
}
}
)Impact: When a student is in "Section 3" (pages 15-20), the system only searches those specific pages instead of the entire 100-page document. This results in:
- ~70% reduction in irrelevant context retrieval
- Higher precision in answers
- Faster response times
The system uses an LLM to reformulate vague follow-up questions before retrieval:
User: "What is informed consent?"
AI: [retrieves context and responds]
User: "Can you give me an example?"
System internally reformulates to: "Can you give an example of informed consent in business ethics?"
[Then retrieves with the full context]
Why this matters: Maintains conversation continuity across multi-turn interactions without losing context.
- Real-time token-by-token response delivery via Server-Sent Events (SSE)
- Async FastAPI backend with LangChain streaming chains
- Better UX: Users see responses appear in real-time (ChatGPT-style)
- Optional Text-to-Speech: Toggle to enable voice playback of AI responses for accessibility and audio-based learning
- Conversation history stored in Redis with
${userUID}_${teacherId}session keys - Full message history (Human/AI pairs) persisted across sessions
- Survives page reloads, navigation, and server restarts
- Enables resuming learning sessions days later
- Fast retrieval (<10ms) for conversation context loading
Strict Context Adherence:
system_prompt = """
CRITICAL RULES:
1. ONLY use information from "Context:" section
2. If info not in context, respond: "I don't have that information..."
3. NEVER make up or infer information not in the documents
"""Special Learning Modes:
"Just ask me 2 serious questions..."โ Quiz mode with 2 challenging questions"Can you explain [topic]..."โ Detailed explanation with follow-up options- Automatic difficulty adaptation based on student responses
- API Framework: FastAPI (async, high-performance)
- LLM Integration: LangChain with OpenAI/Anthropic models
- Vector Store: Pinecone/Chroma with semantic search
- Embeddings: OpenAI text-embedding-3-small
- Session Storage: Redis (in-memory, <10ms retrieval)
- Message History: LangChain's
RedisChatMessageHistoryfor conversation persistence
A standalone, runnable example of the RAG endpoint is included in this repository:
๐ backend-sample/ - Complete FastAPI implementation with:
- Heavily commented code explaining each optimization
- Quick start guide for local testing
- All dependencies and environment setup
This sample demonstrates production-ready code that can be deployed immediately.
- Framework: Angular 19 (standalone components, signals)
- Backend: Firebase Authentication + Cloud Firestore
- UI: Angular Material + Tailwind CSS
- i18n: Transloco (English, Spanish, French)
- Build: Angular CLI 19 + Vite
# Node.js LTS (v22.x recommended)
node -v # v22.20.0
# Angular CLI
npm install -g @angular/cli- Create Firebase project at console.firebase.google.com
- Create environment files:
// src/environments/environment.development.ts
export const environment = {
BASEURL: 'your-firebase-api-url',
BACK_CHAT_URL: 'your-backend-url',
WEBSITE_NAME: 'Trainer Teacher',
firebase: {
apiKey: "your-api-key",
authDomain: "your-project.firebaseapp.com",
projectId: "your-project-id",
storageBucket: "your-project.appspot.com",
messagingSenderId: "your-sender-id",
appId: "your-app-id"
}
};// src/environments/environment.ts (production)
export const environment = {
// Same structure as development
};# Install dependencies
npm install
# Run development server
ng serve
# Navigate to http://localhost:4200
# Build for production
ng build# Set default Firebase project
firebase use default
# Deploy to Firebase Hosting
firebase deploysrc/app/
โโโ components/
โ โโโ auth/ # Login/register components
โ โโโ chat/ # Chat interface
โ โโโ evaluation/ # Exam taking component
โ โโโ left-menu/ # Navigation menu
โ โโโ school/ # Dashboard components
โ โ โโโ dashboard/
โ โ โโโ exam-result-list/
โ โ โโโ exams-list/
โ โ โโโ student-list/
โ โ โโโ teacher-list/
โ โโโ superadmin/ # CRUD components
โ โ โโโ teachers-crud/
โ โ โโโ course-crud/
โ โ โโโ exam-crud/
โ โโโ shared/ # Reusable components
โโโ guards/
โ โโโ admin.guard.ts # Admin access guard
โโโ models/
โ โโโ exam.ts # Exam, Question, Option
โ โโโ result.ts # Result, QuestionAndAnswer
โ โโโ teacher.ts # Teacher, Section
โ โโโ course.ts
โ โโโ user.ts
โ โโโ student.ts
โโโ pages/
โ โโโ mainselector-page/ # Landing page
โ โโโ school-main-page/ # Admin dashboard
โ โโโ teacher-main-page/ # Teacher content page
โโโ services/
โ โโโ auth.service.ts # Firebase authentication
โ โโโ exam.service.ts # Exam queries
โ โโโ exam-crud.service.ts # Exam CRUD operations
โ โโโ result.service.ts # Result tracking
โ โโโ teacher-crud.service.ts
โ โโโ course-crud.service.ts
โ โโโ user.service.ts
โโโ app.routes.ts # Route configuration
graph TD
A[Student opens /exam/:id] --> B[View Exam Intro]
B --> C{Check Eligibility}
C -->|Already Passed| D[Redirect]
C -->|Too Soon| E[Show Cooldown Timer]
C -->|Can Take| F[Shuffle Questions & Answers]
F --> G[Create Initial Result Entry]
G --> H[Start Timer]
H --> I[Answer Questions]
I --> J[Auto-save to Firestore]
J --> K{More Questions?}
K -->|Yes| I
K -->|No| L[Review Summary]
L --> M[Submit Exam]
M --> N[Calculate Score]
N --> O[Show Results]
// Protects /crud, /course-crud, /exam-crud routes
if (user && user.email === 'martin@martin.com') {
return true; // Admin access
}interface Exam {
id: string;
title: string;
questions: Question[];
passingPercentage: number; // e.g., 70
timeToWait: number; // Minutes before retry
timeToDoTheExam: number; // Exam duration in minutes
recruiterId?: string;
}
interface Question {
text: string;
options: Option[]; // 2-6 options
}
interface Option {
text: string;
isCorrect: boolean; // Only one correct per question
}interface Result {
userUID: string;
examId: string;
doingTheExamNow: boolean; // Resume flag
momentStartExam: string; // ISO timestamp
questions_answered: number;
correctAnswers: number;
examPassed?: boolean;
questions: QuestionAndAnswer[]; // Saved answers
}Transloco configuration with 3 languages:
availableLangs: ['en', 'es', 'fr']
defaultLang: 'en'Translation files in /public/i18n/:
en.jsones.jsonfr.json
# Build production bundle
ng build
# Deploy to Firebase
firebase deploy- Development: Uses
environment.development.ts - Production: Uses
environment.ts
Configured in angular.json:
{
"configurations": {
"production": {
"outputHashing": "all"
},
"development": {
"optimization": false,
"sourceMap": true,
"fileReplacements": [{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.development.ts"
}]
}
}
}@Component({
selector: 'app-exam',
imports: [CommonModule, MatIconModule],
standalone: true
})currentUserSig = signal<User | null>(null);
// Auto-updates components on change// Real-time data streams
exams$ = collectionData(examCollection) as Observable<Exam[]>;{
path: 'crud',
component: TeachersCRUDComponent,
canActivate: [adminGuard]
}- Setup: Configure Firebase and environment files
- Explore: Navigate the main selector and dashboard
- Take Exam: Experience the student workflow at
/exam/:id - Admin Panel: Access CRUD operations (requires admin email)
- Customize: Modify exam settings, questions, and content
- โ Auto-save Progress: Never lose exam answers
- โ Resume Capability: Continue interrupted exams
- โ Time Management: Accurate timer with resume support
- โ Anti-cheat: Question/answer shuffling
- โ Cooldown System: Prevent immediate retakes
- โ Role-based Access: Secure admin operations
- โ Multi-language: English, Spanish, French
This is an educational platform template. Feel free to fork and adapt for your use case.
MIT License - see LICENSE file for details
Built with โค๏ธ using Angular 19, Firebase, and modern web standards