diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..e4351a6c522e361828db85d13296a8b2934a8af3
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,53 @@
+# Python cache
+__pycache__/
+*.py[cod]
+*$py.class
+*.so
+.Python
+
+# Virtual environments
+venv/
+env/
+ENV/
+
+# IDE
+.vscode/
+.idea/
+*.swp
+*.swo
+
+# Git
+.git/
+.gitignore
+
+# Data files (will be regenerated)
+backend/data/students.json
+
+# Documentation (not needed in runtime)
+*.md
+!README.md
+
+# Local development files
+.env
+.env.local
+
+# OS files
+.DS_Store
+Thumbs.db
+
+# Logs
+*.log
+
+# PowerShell scripts (local dev only)
+*.ps1
+
+# Backup files
+*.backup
+*.bak
+
+# Render config (not needed for HuggingFace)
+render.yaml
+
+# Railway config (not needed for HuggingFace)
+Procfile
+runtime.txt
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..a6344aac8c09253b3b630fb776ae94478aa0275b
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,35 @@
+*.7z filter=lfs diff=lfs merge=lfs -text
+*.arrow filter=lfs diff=lfs merge=lfs -text
+*.bin filter=lfs diff=lfs merge=lfs -text
+*.bz2 filter=lfs diff=lfs merge=lfs -text
+*.ckpt filter=lfs diff=lfs merge=lfs -text
+*.ftz filter=lfs diff=lfs merge=lfs -text
+*.gz filter=lfs diff=lfs merge=lfs -text
+*.h5 filter=lfs diff=lfs merge=lfs -text
+*.joblib filter=lfs diff=lfs merge=lfs -text
+*.lfs.* filter=lfs diff=lfs merge=lfs -text
+*.mlmodel filter=lfs diff=lfs merge=lfs -text
+*.model filter=lfs diff=lfs merge=lfs -text
+*.msgpack filter=lfs diff=lfs merge=lfs -text
+*.npy filter=lfs diff=lfs merge=lfs -text
+*.npz filter=lfs diff=lfs merge=lfs -text
+*.onnx filter=lfs diff=lfs merge=lfs -text
+*.ot filter=lfs diff=lfs merge=lfs -text
+*.parquet filter=lfs diff=lfs merge=lfs -text
+*.pb filter=lfs diff=lfs merge=lfs -text
+*.pickle filter=lfs diff=lfs merge=lfs -text
+*.pkl filter=lfs diff=lfs merge=lfs -text
+*.pt filter=lfs diff=lfs merge=lfs -text
+*.pth filter=lfs diff=lfs merge=lfs -text
+*.rar filter=lfs diff=lfs merge=lfs -text
+*.safetensors filter=lfs diff=lfs merge=lfs -text
+saved_model/**/* filter=lfs diff=lfs merge=lfs -text
+*.tar.* filter=lfs diff=lfs merge=lfs -text
+*.tar filter=lfs diff=lfs merge=lfs -text
+*.tflite filter=lfs diff=lfs merge=lfs -text
+*.tgz filter=lfs diff=lfs merge=lfs -text
+*.wasm filter=lfs diff=lfs merge=lfs -text
+*.xz filter=lfs diff=lfs merge=lfs -text
+*.zip filter=lfs diff=lfs merge=lfs -text
+*.zst filter=lfs diff=lfs merge=lfs -text
+*tfevents* filter=lfs diff=lfs merge=lfs -text
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..9f36a96573fb585cc41bd527ece8bda56040c2c2
Binary files /dev/null and b/.gitignore differ
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..d0b88cbf1bbc267df223865c0c64224a90d8e347
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,35 @@
+# Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
+# Dockerfile for TalimBot - AI-Powered Student Grouping System
+
+FROM python:3.11
+
+# Create non-root user (Hugging Face security requirement)
+RUN useradd -m -u 1000 user
+USER user
+
+# Set environment variables
+ENV HOME=/home/user \
+ PATH=/home/user/.local/bin:$PATH \
+ PYTHONUNBUFFERED=1
+
+# Set working directory
+WORKDIR /app
+
+# Copy requirements and install dependencies
+COPY --chown=user ./requirements.txt /app/requirements.txt
+RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
+
+# Copy the entire backend folder (contains main.py, static files, etc.)
+COPY --chown=user ./backend /app/backend
+
+# Copy resources_references folder (optional, for documentation)
+COPY --chown=user ./resources_references /app/resources_references
+
+# Expose port 7860 (Hugging Face Spaces requirement)
+EXPOSE 7860
+
+# Change to backend directory where main.py is located
+WORKDIR /app/backend
+
+# Run the FastAPI application on port 7860
+CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
diff --git a/HUGGINGFACE_DEPLOYMENT.md b/HUGGINGFACE_DEPLOYMENT.md
new file mode 100644
index 0000000000000000000000000000000000000000..003389a93747e95a7dcf4242ca650ae8b6382c19
--- /dev/null
+++ b/HUGGINGFACE_DEPLOYMENT.md
@@ -0,0 +1,232 @@
+# Hugging Face Spaces Deployment Guide for TalimBot
+
+## Status: Ready to Deploy ✅
+
+All necessary files have been created and committed. Follow the steps below to complete the deployment.
+
+---
+
+## Files Created
+
+1. **Dockerfile** - Docker configuration for HF Spaces (port 7860)
+2. **.dockerignore** - Excludes unnecessary files from Docker build
+3. **README_HF.md** - Hugging Face Space description with metadata
+
+---
+
+## Step 1: Get Your Hugging Face Access Token
+
+1. Go to: https://huggingface.co/settings/tokens
+2. Click **"New token"**
+3. Name it: `TalimBot Deploy`
+4. Type: **Write** (must have write permissions)
+5. Click **"Generate a token"**
+6. **COPY THE TOKEN** (you won't see it again!)
+
+---
+
+## Step 2: Push to Hugging Face
+
+The git remote is already configured. Now push your code:
+
+```powershell
+git push huggingface main
+```
+
+When prompted:
+- **Username**: `parinazAkef` (your HF username)
+- **Password**: Paste your **access token** (not your actual password!)
+
+---
+
+## Step 3: Configure Environment Secret
+
+1. Go to: https://huggingface.co/spaces/parinazAkef/talimbot
+2. Click the **Settings** tab (top of page)
+3. Scroll to **"Variables and secrets"**
+4. Click **"New secret"**
+5. Name: `OPENROUTER_API_KEY`
+6. Value: Your OpenRouter API key (starts with `sk-or-v1-`)
+7. Click **"Save"**
+
+**✅ You've already done this step!**
+
+---
+
+## Step 4: Wait for Build
+
+After pushing, Hugging Face will:
+1. Show "Building" status (3-5 minutes)
+2. Pull Docker image, install dependencies
+3. Start your FastAPI app on port 7860
+4. Show "Running" status when ready
+
+---
+
+## Step 5: Access Your Live App
+
+Once status shows **"Running"** (green), your app will be available at:
+
+**Primary URL:**
+```
+https://huggingface.co/spaces/parinazAkef/talimbot
+```
+
+**Direct URL (no HF frame):**
+```
+https://parinazakef-talimbot.hf.space
+```
+
+---
+
+## Step 6: Test the Application
+
+### Teacher Login
+1. Go to your HF Space URL
+2. Click on **"معلم"** (Teacher)
+3. Password: `teacher123`
+4. You should see the teacher dashboard
+
+### Student Login
+1. Click on **"دانش آموز"** (Student)
+2. Enter national code: `0921111111` (demo account)
+3. You should see: **پریناز عاکف** dashboard
+
+### Test Grouping
+1. Login as teacher
+2. Use **"پر کردن دادههای تست"** to generate 10 sample students
+3. Click **"شروع گروهبندی"**
+4. Enter course name (e.g., "ریاضی")
+5. Wait 30-60 seconds for AI grouping
+6. Check results!
+
+---
+
+## Troubleshooting
+
+### If Build Fails
+
+**Error: "Port 7860 not listening"**
+- Fixed! Our Dockerfile uses `--port 7860`
+
+**Error: "OPENROUTER_API_KEY not found"**
+- Go to Space Settings → Add secret `OPENROUTER_API_KEY`
+
+**Error: "File not found: main.py"**
+- Fixed! Dockerfile copies `backend/` folder and sets working directory
+
+### If Push Fails
+
+**Error: "Authentication failed"**
+- Make sure you're using an **access token**, not your password
+- Generate new token with **Write** permissions
+
+**Error: "Repository not found"**
+- Check space URL: https://huggingface.co/spaces/parinazAkef/talimbot
+- Make sure space exists and is public
+
+---
+
+## File Structure (Docker Container)
+
+```
+/app/
+ ├── requirements.txt
+ ├── backend/
+ │ ├── main.py # FastAPI app (runs on port 7860)
+ │ ├── grouping_logic.py # AI grouping algorithm
+ │ ├── data/
+ │ │ └── students.json.backup # Initial data template
+ │ └── static/
+ │ ├── pages/ # HTML pages
+ │ ├── assets/ # CSS, JS files
+ │ └── Icons/ # Images
+ └── resources_references/ # Documentation
+```
+
+---
+
+## Environment Variables
+
+The Space automatically provides:
+- `OPENROUTER_API_KEY` (from Secrets)
+- `PORT=7860` (HF Spaces requirement)
+
+Your FastAPI app reads `OPENROUTER_API_KEY` via:
+```python
+api_key = os.getenv("OPENROUTER_API_KEY")
+```
+
+---
+
+## Next Steps After Deployment
+
+1. **Update GitHub README** - Add HF Space badge and link
+2. **Share URL** - Send to users/colleagues
+3. **Monitor Usage** - Check Logs tab in HF Space
+4. **Add to Profile** - Pin Space to your HF profile
+
+---
+
+## Updating Your App
+
+To push changes:
+
+```powershell
+# Make your code changes
+git add .
+git commit -m "Your update description"
+
+# Push to GitHub (optional)
+git push fork main
+
+# Push to Hugging Face (triggers rebuild)
+git push huggingface main
+```
+
+HF will automatically rebuild and redeploy!
+
+---
+
+## Comparison: Railway vs Hugging Face
+
+| Feature | Railway | Hugging Face |
+|---------|---------|--------------|
+| Free Tier | 500 hours/month | Unlimited (24/7) |
+| Sleep Mode | No | No |
+| Cold Start | No | No |
+| Iran Access | Sometimes blocked | More accessible |
+| Custom Domain | Yes (paid) | Yes (subdomain free) |
+| Secrets | Environment variables | Secrets (encrypted) |
+| Logs | Real-time | Real-time |
+| Auto-deploy | Git push | Git push |
+
+---
+
+## Contact & Support
+
+- **Hugging Face Docs**: https://huggingface.co/docs/hub/spaces-sdks-docker
+- **Your Space**: https://huggingface.co/spaces/parinazAkef/talimbot
+- **OpenRouter Docs**: https://openrouter.ai/docs
+
+---
+
+## Summary
+
+✅ **Completed:**
+- Created Dockerfile (port 7860)
+- Created .dockerignore
+- Created README_HF.md
+- Committed files to git
+- Added HF remote
+
+🔄 **Your Action Required:**
+1. Get HF access token from https://huggingface.co/settings/tokens
+2. Run: `git push huggingface main`
+3. Enter username + token when prompted
+4. Wait for "Running" status
+5. Test at: https://parinazakef-talimbot.hf.space
+
+---
+
+Good luck! 🚀
diff --git a/MANUAL_UPDATE_INSTRUCTIONS.md b/MANUAL_UPDATE_INSTRUCTIONS.md
new file mode 100644
index 0000000000000000000000000000000000000000..6aeaed55bd09e4f969c8921cc4d29c761a1aeaf4
--- /dev/null
+++ b/MANUAL_UPDATE_INSTRUCTIONS.md
@@ -0,0 +1,150 @@
+# Manual Update Instructions for HuggingFace Space
+
+Since git push is timing out, you can update the files manually on HuggingFace.
+
+## Files to Update
+
+### 1. backend/static/pages/login.html
+
+**Go to:** https://huggingface.co/spaces/TalimBot/talimbot/blob/main/backend/static/pages/login.html
+
+**Click "Edit" button, then find and replace these sections:**
+
+**CHANGE 1 (around line 90):**
+
+Find:
+```html
+
+
کد ملی ۱۰ رقمی خود را وارد کنید
+```
+
+Replace with:
+```html
+
+ کد ملی خود را بدون صفر ابتدایی وارد کنید
+```
+
+**CHANGE 2 (around line 207):**
+
+Find:
+```javascript
+ if (selectedRole === 'student') {
+ let nationalCode = document.getElementById('nationalCode').value.trim();
+
+ if (!nationalCode) {
+ showError('لطفاً کد ملی خود را وارد کنید');
+ return;
+ }
+
+ if (nationalCode.length !== 10) {
+ showError('کد ملی باید ۱۰ رقم باشد');
+ return;
+ }
+
+ // Remove leading zero if present
+ if (nationalCode.startsWith('0')) {
+ nationalCode = nationalCode.substring(1);
+ }
+```
+
+Replace with:
+```javascript
+ if (selectedRole === 'student') {
+ let nationalCode = document.getElementById('nationalCode').value.trim();
+
+ if (!nationalCode) {
+ showError('لطفاً کد ملی خود را وارد کنید');
+ return;
+ }
+
+ // Check if starts with zero and show warning
+ if (nationalCode.startsWith('0')) {
+ showError('لطفاً صفر ابتدایی را از کد ملی حذف کنید');
+ return;
+ }
+
+ // No length restriction - just check if it matches a student in database
+```
+
+**Then click "Commit changes to main"**
+
+---
+
+### 2. backend/static/pages/group-view.html
+
+**Go to:** https://huggingface.co/spaces/TalimBot/talimbot/blob/main/backend/static/pages/group-view.html
+
+**Click "Edit" button, then find and replace this section:**
+
+**CHANGE (around line 379):**
+
+Find:
+```html
+
+
+ MBTI: ${member.mbti || 'ندارد'}
+
+
+ سبک: ${member.learningStyle || 'ندارد'}
+
+
+ نمره: ${member.grade.toFixed(2)}
+
+
+```
+
+Replace with:
+```html
+
+
+ MBTI: ${member.mbti || 'ندارد'}
+
+
+ سبک: ${member.learningStyle || 'ندارد'}
+
+ ${member.ams ? `
+ AMS: ${member.ams}
+ ` : ''}
+ ${member.cooperative ? `
+ همکاری: ${member.cooperative}
+ ` : ''}
+
+```
+
+**Then click "Commit changes to main"**
+
+---
+
+## What These Changes Do
+
+1. **Login page**: Removes the 10-digit limit and shows a clear error if someone tries to enter a leading zero
+2. **Group view page**: Hides teammates' grades (معدل) and shows AMS and Cooperative scores instead
+
+## After Making Changes
+
+The Space will automatically rebuild (takes 2-3 minutes) and you'll see the changes live at:
+https://talimbot-talimbot.hf.space/pages/login.html
+
+---
+
+**Alternative: Try pushing again later when connection is better**
+
+If you prefer to keep trying git push, you can run:
+```powershell
+git push huggingface main --force
+```
+
+But given the network issues, manual editing on the website is faster and more reliable.
diff --git a/Procfile b/Procfile
new file mode 100644
index 0000000000000000000000000000000000000000..90bf8771de1fbc2f53fe8f07bde825099610e57b
--- /dev/null
+++ b/Procfile
@@ -0,0 +1 @@
+web: cd backend && uvicorn main:app --host 0.0.0.0 --port $PORT
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..141654b49db7e48cf73887afd07cfa852b2d258e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,278 @@
+---
+title: TalimBot
+emoji: 🎓
+colorFrom: blue
+colorTo: indigo
+sdk: docker
+pinned: false
+license: mit
+---
+
+# TalimBot - AI-Powered Student Grouping System
+
+An intelligent educational platform that uses advanced psychology principles and AI to create optimal learning groups for adolescent students (ages 15-16).
+
+## Overview
+
+TalimBot is a comprehensive web-based system designed to help teachers form balanced, effective study groups by analyzing student personalities, learning styles, academic motivation, and cooperative skills. The system uses OpenAI's GPT-4o to create groups that maximize learning potential through Zone of Proximal Development (ZPD) theory and complementary personality matching.
+
+## Key Features
+
+### For Teachers
+- **AI-Powered Grouping**: Automated group formation using educational psychology principles
+- **Multi-Factor Analysis**: Considers 7 key criteria with weighted priorities:
+ - ZPD Optimization (30%) - Grade-based peer tutoring scaffolding
+ - MBTI Complementarity (25%) - Personality type balance
+ - VARK Diversity (20%) - Learning style variety
+ - Academic Motivation (15%) - AMS score distribution
+ - Cooperative Skills (10%) - Teamwork ability balance
+ - Course-Specific Requirements
+ - Student Preferences (5%)
+- **Real-time Dashboard**: Monitor student profile completion and grouping status
+- **Data Management**: Import/export student data via JSON, fill test data
+- **Result Control**: Show/hide grouping results to students
+- **Flexible Reset Options**:
+ - Reset grouping only (preserve student data)
+ - Reset all data (complete system reset)
+
+### For Students
+- **Profile Management**: Complete personality and learning assessments
+- **Integrated Tests**:
+ - MBTI personality test (16 types)
+ - VARK learning style questionnaire (Visual, Aural, Read/Write, Kinesthetic)
+ - AMS academic motivation scale (28 questions, 0-196 score)
+ - Cooperative learning skills assessment (25 questions, 0-125 score)
+- **Peer Preferences**: Select up to 4 preferred groupmates
+- **Group View**: See assigned group members and AI reasoning (when visible)
+- **Progress Tracking**: Monitor test completion status
+
+## Technical Architecture
+
+### Backend
+- **Framework**: FastAPI (Python)
+- **Database**: JSON file-based storage (students.json)
+- **AI Integration**: OpenRouter API with GPT-4o model
+- **Authentication**: Password-based teacher authentication, national code verification for students
+
+### Frontend
+- **UI Framework**: Tailwind CSS
+- **Language Support**: Persian (RTL layout) with Vazirmatn font
+- **Pages**:
+ - Login page (student/teacher authentication)
+ - Student dashboard (profile management, tests)
+ - Teacher dashboard (grouping management, analytics)
+ - Group view (display assigned groups)
+ - AMS questionnaire (academic motivation assessment)
+ - Cooperative questionnaire (teamwork skills assessment)
+
+### Deployment
+- **Platform**: Railway.app
+- **Server**: Uvicorn ASGI server
+- **Static Files**: Served via FastAPI StaticFiles
+- **Environment Variables**: OPENROUTER_API_KEY
+
+## Project Structure
+
+```
+talimbot/
+├── backend/
+│ ├── main.py # FastAPI application and API endpoints
+│ ├── grouping_logic.py # AI grouping algorithm
+│ ├── data/
+│ │ ├── students.json # Student data (gitignored)
+│ │ └── students.json.backup # Clean backup template
+│ └── static/
+│ ├── pages/ # HTML pages
+│ │ ├── login.html
+│ │ ├── student-dashboard.html
+│ │ ├── teacher-dashboard.html
+│ │ ├── group-view.html
+│ │ ├── ams-questionnaire.html
+│ │ ├── cooperative-questionnaire.html
+│ │ └── student-data.html
+│ ├── assets/
+│ │ ├── js/
+│ │ │ ├── data.js # API client functions
+│ │ │ └── grouping.js # Grouping utilities
+│ │ └── css/
+│ │ └── styles.css # Custom styles
+│ └── index.html # Landing page
+├── resources_references/ # Documentation and reference files
+│ ├── RAILWAY_DEPLOYMENT.md # Deployment guide
+│ ├── TEST_RESULTS_AND_SOLUTION.md
+│ ├── angizesh_tahsili.txt # AMS questionnaire source
+│ ├── cooperative.txt # Cooperative questionnaire source
+│ ├── students_class_notebook.txt # Original student data
+│ └── sample-student-data.json # JSON import example
+├── requirements.txt # Python dependencies
+├── runtime.txt # Python version for Railway
+├── Procfile # Railway start command
+└── .gitignore # Git ignore rules
+
+```
+
+## Installation and Setup
+
+### Prerequisites
+- Python 3.11+
+- OpenRouter API key (get from https://openrouter.ai/keys)
+
+### Local Development
+
+1. Clone the repository:
+```bash
+git clone https://github.com/talimbot/talimbot.git
+cd talimbot
+```
+
+2. Install dependencies:
+```bash
+pip install -r requirements.txt
+```
+
+3. Set environment variable:
+```bash
+# Windows PowerShell
+$env:OPENROUTER_API_KEY="your-api-key-here"
+
+# Linux/Mac
+export OPENROUTER_API_KEY="your-api-key-here"
+```
+
+4. Run the server:
+```bash
+cd backend
+uvicorn main:app --reload --host 0.0.0.0 --port 8000
+```
+
+5. Access the application:
+```
+http://localhost:8000
+```
+
+### Railway Deployment
+
+1. Fork this repository to your GitHub account
+
+2. Create a new project on Railway.app
+
+3. Connect your GitHub repository
+
+4. Add environment variable in Railway dashboard:
+ - Key: `OPENROUTER_API_KEY`
+ - Value: Your OpenRouter API key
+
+5. Railway will auto-deploy using the Procfile
+
+## Usage Guide
+
+### Teacher Workflow
+
+1. **Login**: Access teacher dashboard with password (default: teacher123)
+
+2. **Monitor Students**: View student profile completion status
+
+3. **Fill Test Data** (Optional): Use the test data generator to fill 10 sample students for testing
+
+4. **Import Data** (Optional): Upload JSON file with student information
+
+5. **Perform Grouping**:
+ - Enter course name
+ - Click "Start Grouping" button
+ - Wait for AI processing (30-60 seconds)
+ - Review generated groups with detailed reasoning
+
+6. **Show Results**: Toggle result visibility to allow students to view their groups
+
+7. **Reset Options**:
+ - Reset Grouping: Clear groups, keep student data
+ - Reset All Data: Complete system wipe
+
+### Student Workflow
+
+1. **Login**: Enter student number (S001-S030) and national code
+
+2. **Complete Profile**:
+ - Take MBTI personality test (external link)
+ - Complete VARK learning style questionnaire
+ - Fill AMS academic motivation scale (28 questions)
+ - Complete cooperative skills assessment (25 questions)
+ - Select up to 4 preferred groupmates (optional)
+
+3. **Save Information**: Click "Save All Information" button
+
+4. **View Group**: Access group view page to see assigned group (when teacher makes it visible)
+
+## Grouping Algorithm
+
+The AI grouping system follows a sophisticated 7-tier priority framework:
+
+1. **ZPD Optimization (30%)**: Mixes high and medium performers for peer tutoring
+2. **MBTI Complementarity (25%)**: Pairs complementary personality types (e.g., ENFP+INTJ)
+3. **VARK Diversity (20%)**: Ensures multiple learning styles in each group
+4. **Academic Motivation (15%)**: Distributes high-motivation students across groups
+5. **Cooperative Skills (10%)**: Balances teamwork abilities
+6. **Course-Specific Requirements**: Adapts to subject matter needs
+7. **Student Preferences (5%)**: Honors preferences when they don't compromise other criteria
+
+Groups are typically 5 students each, with some groups of 4 to avoid very small groups.
+
+## Data Structure
+
+### Student Object
+```json
+{
+ "studentNumber": "S001",
+ "name": "Student Name",
+ "nationalCode": "1234567890",
+ "mbti": "INTJ",
+ "learningStyle": "Visual",
+ "ams": "150",
+ "cooperative": "95",
+ "grade": 18.5,
+ "preferredStudents": ["S002", "S003"],
+ "group": 1
+}
+```
+
+## API Endpoints
+
+- `GET /api/students` - Get all students
+- `GET /api/student/{student_number}` - Get specific student
+- `PUT /api/student/{student_number}` - Update student data
+- `POST /api/grouping/perform` - Execute AI grouping
+- `GET /api/grouping/status` - Get grouping statistics
+- `POST /api/grouping/reset` - Reset grouping only
+- `POST /api/data/reset-all` - Reset all data
+- `POST /api/grouping/toggle-visibility` - Show/hide results
+- `POST /api/auth/teacher` - Verify teacher password
+- `POST /api/auth/student` - Authenticate student
+- `GET /api/student/{student_number}/group` - Get student's group
+
+## Security Notes
+
+- Student data stored in students.json (excluded from version control)
+- Teacher password: "teacher123" (change in production)
+- National codes used for student authentication
+- API key required for AI grouping functionality
+
+## Educational Foundation
+
+This system is based on:
+- **Vygotsky's Zone of Proximal Development (ZPD)**: Optimal learning occurs when students work slightly above their current level with peer support
+- **MBTI Complementarity Research**: Diverse personality types enhance team creativity and problem-solving
+- **VARK Learning Theory**: Multiple learning styles improve knowledge retention
+- **Academic Motivation Scale (AMS)**: Measures intrinsic and extrinsic motivation factors
+- **Cooperative Learning Principles**: Teamwork skills are essential for collaborative success
+
+## License
+
+This project is for educational purposes.
+
+## Contributors
+
+Developed for educational psychology research and classroom implementation.
+
+## Support
+
+For issues or questions, please refer to the documentation in the `resources_references/` folder.
diff --git a/README_HF.md b/README_HF.md
new file mode 100644
index 0000000000000000000000000000000000000000..cc89bfda529af82b2a81c3d06884edd4e4d8cd90
--- /dev/null
+++ b/README_HF.md
@@ -0,0 +1,54 @@
+---
+title: TalimBot
+emoji: 🎓
+colorFrom: teal
+colorTo: cyan
+sdk: docker
+pinned: false
+license: mit
+---
+
+# TalimBot - AI-Powered Student Grouping System
+
+An intelligent educational platform that uses advanced psychology principles and AI to create optimal learning groups for adolescent students (ages 15-16).
+
+## Features
+
+- **AI-Powered Grouping**: Automated group formation using OpenAI GPT-4o
+- **Educational Psychology**: Based on ZPD theory, MBTI complementarity, VARK learning styles
+- **Teacher Dashboard**: Monitor students and manage grouping
+- **Student Dashboard**: Complete personality and learning assessments
+- **Persian Language**: Full RTL support with Vazirmatn font
+
+## Tech Stack
+
+- **Backend**: FastAPI (Python 3.11)
+- **Frontend**: Vanilla JavaScript, Tailwind CSS
+- **AI**: OpenRouter API with GPT-4o
+- **Deployment**: Hugging Face Spaces (Docker)
+
+## Usage
+
+1. **Teacher Login**: Use password to access teacher dashboard
+2. **Student Login**: Enter national code (کد ملی) to access student dashboard
+3. **Complete Profiles**: Students fill MBTI, VARK, AMS, and Cooperative assessments
+4. **Create Groups**: Teacher runs AI grouping algorithm
+5. **View Results**: Students see their assigned groups
+
+## Demo Account
+
+For demonstration purposes, login with:
+- National Code: 0921111111
+- Name: پریناز عاکف
+
+This account is for demo only and won't be included in grouping.
+
+## Configuration
+
+This Space requires the `OPENROUTER_API_KEY` environment variable to be set in the Secrets section.
+
+Get your free API key at: https://openrouter.ai/keys
+
+## License
+
+MIT License - For educational purposes
diff --git a/backend/README.md b/backend/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..964baa495b03a387bf554f086f0a2f41f9ebdebd
--- /dev/null
+++ b/backend/README.md
@@ -0,0 +1,53 @@
+# TalimBot Backend
+
+FastAPI backend server for the TalimBot student grouping system.
+
+## Quick Start
+
+```bash
+# Install dependencies (one time only)
+pip install -r requirements.txt
+
+# Start the server
+python main.py
+```
+
+Server will run on `http://localhost:8000`
+
+## API Endpoints
+
+- `GET /` - Health check
+- `GET /api/students` - Get all students
+- `GET /api/student/{id}` - Get specific student
+- `PUT /api/student/{id}` - Update student info
+- `POST /api/grouping/perform` - Perform AI grouping
+- `GET /api/grouping/status` - Get grouping statistics
+- `POST /api/grouping/toggle-visibility` - Show/hide results to students
+- `POST /api/grouping/reset` - Reset grouping
+
+## Configuration
+
+### OpenRouter API Key
+Located in `grouping_logic.py`:
+```python
+OPENROUTER_API_KEY = 'your-key-here'
+```
+
+### Teacher Password
+Located in `main.py` (SystemData model):
+```python
+teacherPassword: str = "teacher123"
+```
+
+## Data Storage
+
+Student data is stored in `data/students.json` (auto-created on first run)
+
+## Dependencies
+
+- fastapi - Web framework
+- uvicorn - ASGI server
+- pydantic - Data validation
+- aiohttp - Async HTTP client for API calls
+
+See `requirements.txt` for versions.
diff --git a/backend/__pycache__/grouping_logic.cpython-310.pyc b/backend/__pycache__/grouping_logic.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c53c889a22330cf5c5d0488044c1f9c0de53a279
Binary files /dev/null and b/backend/__pycache__/grouping_logic.cpython-310.pyc differ
diff --git a/backend/__pycache__/main.cpython-310.pyc b/backend/__pycache__/main.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b219cbaa160f10528ca6a72243137290b8f2c3ec
Binary files /dev/null and b/backend/__pycache__/main.cpython-310.pyc differ
diff --git a/backend/data/students.json b/backend/data/students.json
new file mode 100644
index 0000000000000000000000000000000000000000..0e4f06b77e1b993ce9a9b276ea027b251cb559f6
--- /dev/null
+++ b/backend/data/students.json
@@ -0,0 +1,388 @@
+{
+ "students": [
+ {
+ "studentNumber": "S001",
+ "name": "یاسمن آدینه پور",
+ "nationalCode": "929986644",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.77,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S002",
+ "name": "پریا احمدزاده",
+ "nationalCode": "980085330",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 17.28,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S003",
+ "name": "فاطمه اکبرزاده",
+ "nationalCode": "970154550",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 16.71,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S004",
+ "name": "آناهیتا الهی مهر",
+ "nationalCode": "26425955",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.05,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S005",
+ "name": "مریم امیری",
+ "nationalCode": "980093341",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.87,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S006",
+ "name": "باران برادران رحیمی",
+ "nationalCode": "960043985",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.07,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S007",
+ "name": "مایسا بصیری امین",
+ "nationalCode": "960089446",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.33,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S008",
+ "name": "دلارام ثابت عهد",
+ "nationalCode": "960125620",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.55,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S009",
+ "name": "شاینا جان محمدی",
+ "nationalCode": "960068041",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.47,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S010",
+ "name": "آیدا جوان",
+ "nationalCode": "95112313",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 16.77,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S011",
+ "name": "سارینا حاجی آبادی",
+ "nationalCode": "999216751",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 16.08,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S012",
+ "name": "هستی حسن پور جوان",
+ "nationalCode": "960074198",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.55,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S013",
+ "name": "فاطمه حسینی",
+ "nationalCode": "2400410259",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.07,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S014",
+ "name": "غزل خسروی",
+ "nationalCode": "929995767",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 15.05,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S015",
+ "name": "غزل ذباح",
+ "nationalCode": "960110186",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.25,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S016",
+ "name": "نازنین زهرا راشکی",
+ "nationalCode": "3661516087",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 17.02,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S017",
+ "name": "ویونا روح نواز",
+ "nationalCode": "314458344",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.7,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S018",
+ "name": "روژینا سعادتی",
+ "nationalCode": "960051023",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.2,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S019",
+ "name": "ترنم شعبانی",
+ "nationalCode": "950083100",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.37,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S020",
+ "name": "ستایش شفابخش",
+ "nationalCode": "960126899",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.36,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S021",
+ "name": "فاطمه شیرزادخان",
+ "nationalCode": "980120756",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.33,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S022",
+ "name": "آرزو علی جوی",
+ "nationalCode": "960054316",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 17.98,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S023",
+ "name": "آناهیتا قنادزاده",
+ "nationalCode": "960089836",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.84,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S024",
+ "name": "نیایش کارگر",
+ "nationalCode": "929956052",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 17.74,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S025",
+ "name": "باران کبریایی نسب",
+ "nationalCode": "980119588",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.82,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S026",
+ "name": "زینب کیانوش",
+ "nationalCode": "970072678",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.58,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S027",
+ "name": "ستایش محمودی",
+ "nationalCode": "929904656",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.33,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S028",
+ "name": "ستایش مشتاقی",
+ "nationalCode": "361282217",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 17.67,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S029",
+ "name": "مهتاب معلمی",
+ "nationalCode": "960070265",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.56,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S030",
+ "name": "باران وحدتی",
+ "nationalCode": "929916913",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 15.02,
+ "preferredStudents": [],
+ "group": null
+ }
+ ],
+ "courseName": "ریاضی",
+ "groupingComplete": true,
+ "groupingResults": {
+ "groups": [
+ {
+ "groupNumber": 1,
+ "students": [
+ "S001",
+ "S003",
+ "S004"
+ ],
+ "reasoning": "این گروه شامل ۲ درونگرا (S001, S003) و ۱ برونگرا (S004) است. همچنین این گروه شامل یک دانشآموز با سبک یادگیری بصری (S001)، یک دانشآموز با سبک یادگیری حرکتی (S003) و یک دانشآموز با سبک یادگیری بصوتی (S004) است. همچنین نمرات این دانشآموزان به ترتیب 18.77، 16.71 و 19.05 است که یک توازن خوب بین نمرات دانشآموزان در این گروه ایجاد میکند."
+ },
+ {
+ "groupNumber": 2,
+ "students": [
+ "S002"
+ ],
+ "reasoning": "این گروه شامل یک برونگرا (S002) است که با توجه به دادههای ورودی تنها دانشآموز برونگرا در دادهها است. همچنین این دانشآموز با سبک یادگیری بصوتی و نمره 17.28 انتخاب شده است."
+ }
+ ]
+ },
+ "resultsVisible": false,
+ "teacherPassword": "teacher123"
+}
\ No newline at end of file
diff --git a/backend/data/students.json.backup b/backend/data/students.json.backup
new file mode 100644
index 0000000000000000000000000000000000000000..0e4f06b77e1b993ce9a9b276ea027b251cb559f6
--- /dev/null
+++ b/backend/data/students.json.backup
@@ -0,0 +1,388 @@
+{
+ "students": [
+ {
+ "studentNumber": "S001",
+ "name": "یاسمن آدینه پور",
+ "nationalCode": "929986644",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.77,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S002",
+ "name": "پریا احمدزاده",
+ "nationalCode": "980085330",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 17.28,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S003",
+ "name": "فاطمه اکبرزاده",
+ "nationalCode": "970154550",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 16.71,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S004",
+ "name": "آناهیتا الهی مهر",
+ "nationalCode": "26425955",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.05,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S005",
+ "name": "مریم امیری",
+ "nationalCode": "980093341",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.87,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S006",
+ "name": "باران برادران رحیمی",
+ "nationalCode": "960043985",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.07,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S007",
+ "name": "مایسا بصیری امین",
+ "nationalCode": "960089446",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.33,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S008",
+ "name": "دلارام ثابت عهد",
+ "nationalCode": "960125620",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.55,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S009",
+ "name": "شاینا جان محمدی",
+ "nationalCode": "960068041",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.47,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S010",
+ "name": "آیدا جوان",
+ "nationalCode": "95112313",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 16.77,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S011",
+ "name": "سارینا حاجی آبادی",
+ "nationalCode": "999216751",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 16.08,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S012",
+ "name": "هستی حسن پور جوان",
+ "nationalCode": "960074198",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.55,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S013",
+ "name": "فاطمه حسینی",
+ "nationalCode": "2400410259",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.07,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S014",
+ "name": "غزل خسروی",
+ "nationalCode": "929995767",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 15.05,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S015",
+ "name": "غزل ذباح",
+ "nationalCode": "960110186",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.25,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S016",
+ "name": "نازنین زهرا راشکی",
+ "nationalCode": "3661516087",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 17.02,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S017",
+ "name": "ویونا روح نواز",
+ "nationalCode": "314458344",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.7,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S018",
+ "name": "روژینا سعادتی",
+ "nationalCode": "960051023",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.2,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S019",
+ "name": "ترنم شعبانی",
+ "nationalCode": "950083100",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.37,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S020",
+ "name": "ستایش شفابخش",
+ "nationalCode": "960126899",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.36,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S021",
+ "name": "فاطمه شیرزادخان",
+ "nationalCode": "980120756",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.33,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S022",
+ "name": "آرزو علی جوی",
+ "nationalCode": "960054316",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 17.98,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S023",
+ "name": "آناهیتا قنادزاده",
+ "nationalCode": "960089836",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.84,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S024",
+ "name": "نیایش کارگر",
+ "nationalCode": "929956052",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 17.74,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S025",
+ "name": "باران کبریایی نسب",
+ "nationalCode": "980119588",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.82,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S026",
+ "name": "زینب کیانوش",
+ "nationalCode": "970072678",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.58,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S027",
+ "name": "ستایش محمودی",
+ "nationalCode": "929904656",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 19.33,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S028",
+ "name": "ستایش مشتاقی",
+ "nationalCode": "361282217",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 17.67,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S029",
+ "name": "مهتاب معلمی",
+ "nationalCode": "960070265",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 18.56,
+ "preferredStudents": [],
+ "group": null
+ },
+ {
+ "studentNumber": "S030",
+ "name": "باران وحدتی",
+ "nationalCode": "929916913",
+ "mbti": null,
+ "learningStyle": null,
+ "ams": null,
+ "cooperative": null,
+ "grade": 15.02,
+ "preferredStudents": [],
+ "group": null
+ }
+ ],
+ "courseName": "ریاضی",
+ "groupingComplete": true,
+ "groupingResults": {
+ "groups": [
+ {
+ "groupNumber": 1,
+ "students": [
+ "S001",
+ "S003",
+ "S004"
+ ],
+ "reasoning": "این گروه شامل ۲ درونگرا (S001, S003) و ۱ برونگرا (S004) است. همچنین این گروه شامل یک دانشآموز با سبک یادگیری بصری (S001)، یک دانشآموز با سبک یادگیری حرکتی (S003) و یک دانشآموز با سبک یادگیری بصوتی (S004) است. همچنین نمرات این دانشآموزان به ترتیب 18.77، 16.71 و 19.05 است که یک توازن خوب بین نمرات دانشآموزان در این گروه ایجاد میکند."
+ },
+ {
+ "groupNumber": 2,
+ "students": [
+ "S002"
+ ],
+ "reasoning": "این گروه شامل یک برونگرا (S002) است که با توجه به دادههای ورودی تنها دانشآموز برونگرا در دادهها است. همچنین این دانشآموز با سبک یادگیری بصوتی و نمره 17.28 انتخاب شده است."
+ }
+ ]
+ },
+ "resultsVisible": false,
+ "teacherPassword": "teacher123"
+}
\ No newline at end of file
diff --git a/backend/grouping_logic.py b/backend/grouping_logic.py
new file mode 100644
index 0000000000000000000000000000000000000000..ab3077e3be6c091f9787bd8d70d183d06c402c84
--- /dev/null
+++ b/backend/grouping_logic.py
@@ -0,0 +1,334 @@
+import requests
+import json
+import os
+from typing import List, Dict, Any, Optional
+
+# API Configuration
+OPENROUTER_API_URL = 'https://openrouter.ai/api/v1/chat/completions'
+
+def analyze_mbti(mbti: str) -> Dict[str, str]:
+ """Helper to break down MBTI into explicit tags"""
+ if not mbti or len(mbti) < 4:
+ return {"type": "Unknown", "tags": []}
+
+ m = mbti.upper()
+ return {
+ "energy": 'Introvert (درونگرا)' if m[0] == 'I' else 'Extrovert (برونگرا)',
+ "info": 'Intuitive' if m[1] == 'N' else 'Sensing',
+ "decision": 'Thinking' if m[2] == 'T' else 'Feeling',
+ "structure": 'Judging' if m[3] == 'J' else 'Perceiving'
+ }
+
+def group_students_with_ai(students: List[Any], course_name: str, api_key: Optional[str] = None) -> Dict[str, Any]:
+ """
+ Group students using OpenRouter API (ChatGPT) with advanced educational psychology principles
+ Args:
+ students: List of student objects
+ course_name: Name of the course
+ api_key: OpenRouter API key (optional, falls back to env var)
+ """
+ # Get API key from parameter or environment variable
+ openrouter_key = api_key or os.getenv('OPENROUTER_API_KEY', '')
+
+ # Clean the API key - remove any whitespace and newlines
+ if openrouter_key:
+ openrouter_key = openrouter_key.strip().replace('\n', '').replace('\r', '')
+
+ if not openrouter_key or openrouter_key == '':
+ raise Exception(
+ "OpenRouter API key not configured! "
+ "Please add OPENROUTER_API_KEY in Railway Variables tab. "
+ "Get your free key at: https://openrouter.ai/keys"
+ )
+
+ # Validate API key format (but don't log the key)
+ if not openrouter_key.startswith('sk-or-v1-'):
+ raise Exception(
+ f"Invalid API key format. OpenRouter keys should start with 'sk-or-v1-'. "
+ f"Please check your OPENROUTER_API_KEY in Railway Variables."
+ )
+
+ # Sanitization & Data Enrichment
+ valid_student_ids = set(s.studentNumber for s in students)
+
+ student_data = []
+ for s in students:
+ mbti_details = analyze_mbti(s.mbti)
+ student_data.append({
+ "id": s.studentNumber,
+ "name": s.name,
+ "mbti": s.mbti,
+ "mbti_analysis": mbti_details,
+ "learningStyle": s.learningStyle,
+ "ams": s.ams if hasattr(s, 'ams') else None,
+ "cooperative": s.cooperative if hasattr(s, 'cooperative') else None,
+ "grade": s.grade,
+ "preferredStudents": [id for id in (s.preferredStudents or []) if id in valid_student_ids]
+ })
+
+ # Dynamic Group Size Logic
+ total_students = len(students)
+ if total_students < 4:
+ size_guidance = "a single group"
+ elif total_students < 8:
+ size_guidance = "groups of 3-4 students"
+ else:
+ # Prefer groups of 5, but use groups of 4 if needed to avoid very small groups
+ # Examples: 30 students = 6 groups of 5
+ # 27 students = 5 groups of 5 + 1 group of 2 (bad) → instead: 3 groups of 5 + 3 groups of 4 (good)
+ # 25 students = 5 groups of 5
+ # 22 students = 4 groups of 5 + 1 group of 2 (bad) → instead: 2 groups of 5 + 3 groups of 4 (good)
+ remainder = total_students % 5
+ if remainder == 1:
+ # e.g., 21 students: would be 4 groups of 5 + 1 of 1 → instead make 3 groups of 5 + 2 groups of 3
+ size_guidance = "groups of 5 students, with some groups of 3-4 if needed to avoid groups smaller than 3"
+ elif remainder == 2:
+ # e.g., 22 students: would be 4 groups of 5 + 1 of 2 → instead make 2 groups of 5 + 3 groups of 4
+ size_guidance = "groups of 5 students, with some groups of 4 if needed to avoid groups of 2"
+ else:
+ size_guidance = "groups of 5 students"
+
+ # The Enhanced Prompt
+ prompt = f"""You are an expert educational psychologist specializing in adolescent team formation and Vygotsky's Zone of Proximal Development (ZPD). Create optimal learning groups for "{course_name}" course with 15-16 year old students.
+
+INPUT DATA:
+{json.dumps(student_data, ensure_ascii=False, indent=2)}
+
+TOTAL STUDENTS: {total_students}
+GROUPING STRATEGY: Prefer {size_guidance}. IMPORTANT: Avoid creating groups with only 1-2 students. If the math doesn't work out evenly with groups of 5, adjust by creating some groups of 4 to balance the numbers. For example:
+- 30 students = 6 groups of 5 ✓
+- 27 students = 3 groups of 5 + 3 groups of 4 ✓ (NOT 5 groups of 5 + 1 group of 2 ✗)
+- 25 students = 5 groups of 5 ✓
+- 22 students = 2 groups of 5 + 3 groups of 4 ✓ (NOT 4 groups of 5 + 1 group of 2 ✗)
+
+STUDENT AGE CONTEXT (15-16 years - Adolescence):
+- High need for peer acceptance and social belonging
+- Developing abstract thinking and metacognition
+- Identity formation through social interactions
+- Sensitivity to feedback from peers
+- Collaborative learning enhances engagement
+
+GROUPING FRAMEWORK - PRIORITY ORDER:
+
+1. **ZPD OPTIMIZATION (Zone of Proximal Development)** - 30%
+ - Mix academic performance (grade field) to create ZPD scaffolding
+ - Place high performers (معدل بالا) with medium performers for peer tutoring
+ - Avoid grouping all high or all low performers together
+ - Target: Each group should have grade variance of 1-2 points to maximize learning
+
+2. **MBTI COMPLEMENTARITY (NOT Similarity)** - 25%
+ Research-based MBTI pairings for adolescent teamwork:
+ - ENFP + INTJ: Visionary creativity with strategic planning
+ - ENTP + INFJ: Innovation meets deep insight and empathy
+ - ENTJ + INFP: Leadership with values-driven creativity
+ - ESTJ + ISFP: Organization with practical creativity
+ - ESFJ + INTP: Social cohesion with analytical thinking
+ - ESTP + ISFJ: Action-oriented with detail consciousness
+ - ENFJ + ISTP: Motivational leadership with technical problem-solving
+ - ESFP + ISTJ: Enthusiasm with reliability and structure
+
+ KEY PRINCIPLES:
+ - Balance E (Extrovert) and I (Introvert): 2-3 of each per group
+ - Complement T (Thinking) with F (Feeling) for balanced decision-making
+ - Mix N (Intuitive) with S (Sensing) for big-picture + detail focus
+ - Combine J (Judging) with P (Perceiving) for structure + flexibility
+
+3. **VARK DIVERSITY (Learning Styles)** - 20%
+ - Include different learning styles in each group:
+ * Visual (دیداری): Diagrams, charts, spatial understanding
+ * Aural (شنیداری): Discussions, verbal explanations
+ * Read/Write: Text-based learning, note-taking
+ * Kinesthetic (حرکتی): Hands-on, experiential learning
+ - Diversity ensures multiple teaching approaches within group
+ - Adolescents learn best when exposed to varied learning methods
+
+4. **ACADEMIC MOTIVATION (AMS Score)** - 15%
+ - AMS field: Academic Motivation Scale (0-196)
+ - Balance high and moderate motivation levels
+ - High motivation students (>140) can inspire others
+ - Avoid grouping all low-motivation (<100) students together
+ - Target: Each group has at least one high-motivation member
+
+5. **COOPERATIVE LEARNING SKILLS** - 10%
+ - Cooperative field: Cooperation ability (0-125)
+ - High cooperation students (>88) act as social facilitators
+ - Mix cooperation levels for peer modeling
+ - Students with strong cooperation skills help integrate introverts
+
+6. **COURSE-SPECIFIC REQUIREMENTS** - Based on "{course_name}":
+ - Math/Science: Prioritize T (Thinking) types, Visual/Kinesthetic learners
+ - Literature/Humanities: Include F (Feeling) types, Read/Write learners
+ - Projects/Labs: Need high Kinesthetic and ESTP/ISTP types
+ - Discussion-based: Ensure Aural learners and E (Extrovert) types
+
+7. **STUDENT PREFERENCES** - 5% (Secondary consideration)
+ - Honor "preferredStudents" field ONLY if it doesn't compromise above criteria
+ - Adolescents benefit from working outside comfort zones
+ - Strategic separation can reduce cliques and expand social circles
+
+CRITICAL RULES:
+✓ ALL students MUST be assigned to a group
+✓ PREFER groups of 5 students to minimize total number of groups
+✓ Adjust group sizes (use groups of 4) to avoid creating groups with only 1-2 students
+✓ Each group should have 3-5 students (never 1-2 students alone)
+✓ Each group needs MBTI balance: 2-3 Introverts + 2-3 Extroverts
+✓ Each group needs grade diversity: Mix high (>18) with medium (16-18) performers
+✓ Prioritize complementary MBTI types over similar types
+✓ Use provided data fields - DO NOT invent values
+✓ **ABSOLUTELY CRITICAL**: Each student ID can appear in EXACTLY ONE group. NO DUPLICATES. Verify this before outputting.
+✓ Double-check: Count total students in all groups = input students count
+
+OUTPUT FORMAT (Valid JSON Only):
+{{
+ "groups": [
+ {{
+ "groupNumber": 1,
+ "students": ["S001", "S002", "S003", "S004"],
+ "reasoning": "توضیحات کامل به فارسی - شامل: (1) تحلیل ZPD: معدلها و چگونگی یادگیری همیاری (2) تکمیل MBTI: چرا این تیپها با هم سازگارند (3) تنوع VARK (4) سطح انگیزش و همکاری (5) مناسب بودن برای درس {course_name}. مثال: 'این گروه دارای ZPD مطلوب است: S001 (معدل 19.5) و S002 (معدل 17.2) به S003 (معدل 16) کمک میکنند. تکمیل MBTI: ENFP (S001) با خلاقیت و INTJ (S002) با برنامهریزی استراتژیک همکاری میکنند. تنوع یادگیری: 2 Visual، 1 Aural، 1 Kinesthetic. انگیزش بالا (AMS>150) در S001 الهامبخش است.'"
+ }}
+ ]
+}}"""
+
+ # Make API call using requests library
+ headers = {
+ 'Content-Type': 'application/json',
+ 'Authorization': f'Bearer {openrouter_key}',
+ 'HTTP-Referer': 'https://talimbot.up.railway.app',
+ 'X-Title': 'TalimBot'
+ }
+
+ payload = {
+ 'model': 'openai/gpt-4o', # Using GPT-4o for better accuracy and reasoning
+ 'messages': [
+ {
+ 'role': 'system',
+ 'content': 'You are a precise algorithmic grouping assistant. You MUST output ONLY valid JSON - no markdown, no code blocks, no extra text. Start directly with { and end with }. CRITICAL RULE: Each student can appear in EXACTLY ONE group - no duplicates allowed. You rely on the explicit "mbti_analysis" fields provided in the user prompt for your reasoning. Verify that all student IDs appear exactly once across all groups.'
+ },
+ {
+ 'role': 'user',
+ 'content': prompt
+ }
+ ],
+ 'temperature': 0.2 # Lower temperature for more consistent, logical grouping
+ }
+
+ print(f"Sending request to OpenRouter API...")
+
+ response = requests.post(
+ OPENROUTER_API_URL,
+ headers=headers,
+ json=payload,
+ timeout=60
+ )
+
+ print(f"Response status: {response.status_code}")
+ print(f"Response preview: {response.text[:200]}")
+
+ if response.status_code == 401:
+ try:
+ error_data = response.json()
+ error_msg = error_data.get('error', {}).get('message', 'Unauthorized')
+ except:
+ error_msg = response.text
+
+ raise Exception(
+ f"OpenRouter Authentication Error: {error_msg}. "
+ f"Your API key is configured but invalid. Please:\n"
+ f"1. Go to https://openrouter.ai/keys\n"
+ f"2. Check if your key is active and has credits\n"
+ f"3. Create a NEW key if needed\n"
+ f"4. Update OPENROUTER_API_KEY in Railway Variables"
+ )
+
+ if response.status_code == 402:
+ raise Exception(
+ "OpenRouter Payment Required: Your account has no credits. "
+ "Add credits at https://openrouter.ai/credits"
+ )
+
+ if not response.ok:
+ try:
+ error_data = response.json()
+ error_detail = error_data.get('error', {}).get('message', response.text)
+ except:
+ error_detail = response.text
+ raise Exception(f"API request failed ({response.status_code}): {error_detail}")
+
+ data = response.json()
+ content = data['choices'][0]['message']['content']
+ print(f"🔍 DEBUG: Got response content, length: {len(content)}")
+
+ # Parse Result - Extract JSON from markdown code blocks if present
+ try:
+ # Try direct JSON parse first
+ grouping_result = json.loads(content)
+ except json.JSONDecodeError as e:
+ # Try to extract JSON from markdown code blocks
+ import re
+
+ # Look for JSON in ```json ... ``` or ``` ... ``` blocks
+ json_match = re.search(r'```(?:json)?\s*(\{.*?\})\s*```', content, re.DOTALL)
+ if json_match:
+ try:
+ grouping_result = json.loads(json_match.group(1))
+ print(f"✅ Extracted JSON from markdown code block")
+ except json.JSONDecodeError:
+ print(f"Failed to parse JSON from code block: {json_match.group(1)[:200]}")
+ raise Exception("Invalid JSON from API (even after markdown extraction)")
+ else:
+ # Try to find JSON object in the content
+ json_match = re.search(r'\{.*"groups".*\}', content, re.DOTALL)
+ if json_match:
+ try:
+ grouping_result = json.loads(json_match.group(0))
+ print(f"✅ Extracted JSON object from response")
+ except json.JSONDecodeError:
+ print(f"Failed to parse extracted JSON: {json_match.group(0)[:200]}")
+ raise Exception("Invalid JSON from API (extraction failed)")
+ else:
+ print(f"❌ No JSON found in response. Full content:\n{content}")
+ raise Exception("Invalid JSON from API - no valid JSON structure found")
+
+ # Failsafe: Add missing students if AI messed up
+ assigned_students = set()
+ for group in grouping_result['groups']:
+ if 'students' in group:
+ assigned_students.update(group['students'])
+
+ all_ids = [s.studentNumber for s in students]
+ missing = [id for id in all_ids if id not in assigned_students]
+
+ if missing:
+ print(f'AI missed students, adding to last group: {missing}')
+ if grouping_result['groups']:
+ grouping_result['groups'][-1]['students'].extend(missing)
+ grouping_result['groups'][-1]['reasoning'] += f" (سیستم دانشآموزان {', '.join(missing)} را به این گروه اضافه کرد)"
+ else:
+ grouping_result['groups'].append({
+ "groupNumber": 1,
+ "students": missing,
+ "reasoning": "گروه بازیابی شده توسط سیستم"
+ })
+
+ return grouping_result
+
+async def random_grouping(students: List[Any]) -> Dict[str, Any]:
+ """Fallback random grouping if API fails"""
+ import random
+
+ shuffled = students.copy()
+ random.shuffle(shuffled)
+
+ group_size = 5
+ num_groups = (len(shuffled) + group_size - 1) // group_size
+
+ groups = []
+ for i in range(num_groups):
+ group_students = shuffled[i * group_size:(i + 1) * group_size]
+ groups.append({
+ "groupNumber": i + 1,
+ "students": [s.studentNumber for s in group_students],
+ "reasoning": "گروهبندی تصادفی (API در دسترس نبود)"
+ })
+
+ return {"groups": groups}
diff --git a/backend/main.py b/backend/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..e7cd4acc083fb231373788c5afd32ac2a9430766
--- /dev/null
+++ b/backend/main.py
@@ -0,0 +1,428 @@
+from fastapi import FastAPI, HTTPException
+from fastapi.middleware.cors import CORSMiddleware
+from fastapi.staticfiles import StaticFiles
+from fastapi.responses import FileResponse
+from pydantic import BaseModel
+from typing import List, Optional, Dict, Any
+import json
+import os
+from pathlib import Path
+from dotenv import load_dotenv
+
+# Load environment variables from .env file (for local development)
+load_dotenv()
+
+app = FastAPI()
+
+# CORS configuration - allow all origins for flexibility
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=["*"],
+ allow_credentials=True,
+ allow_methods=["*"],
+ allow_headers=["*"],
+)
+
+# Data file path
+DATA_FILE = Path(__file__).parent / "data" / "students.json"
+DATA_FILE.parent.mkdir(exist_ok=True)
+
+# Pydantic models
+class Student(BaseModel):
+ studentNumber: str
+ name: str
+ nationalCode: str = ""
+ mbti: Optional[str] = None
+ learningStyle: Optional[str] = None
+ ams: Optional[str] = None
+ cooperative: Optional[str] = None
+ grade: float
+ preferredStudents: List[str] = []
+ group: Optional[int] = None
+
+class StudentUpdate(BaseModel):
+ mbti: Optional[str] = None
+ learningStyle: Optional[str] = None
+ ams: Optional[str] = None
+ cooperative: Optional[str] = None
+ preferredStudents: Optional[List[str]] = None
+
+class GroupingRequest(BaseModel):
+ courseName: str
+
+class TeacherAuthRequest(BaseModel):
+ password: str
+
+class StudentAuthRequest(BaseModel):
+ studentNumber: str
+ nationalCode: str
+
+class SystemData(BaseModel):
+ students: List[Student]
+ courseName: str = ""
+ groupingComplete: bool = False
+ groupingResults: Optional[Dict[str, Any]] = None
+ resultsVisible: bool = False
+ teacherPassword: str = "teacher123"
+
+# Initialize data
+def load_data() -> SystemData:
+ if DATA_FILE.exists():
+ with open(DATA_FILE, 'r', encoding='utf-8') as f:
+ data = json.load(f)
+ return SystemData(**data)
+ else:
+ # Initialize with real 30 students from class data
+ initial_students = [
+ Student(studentNumber='S001', name='یاسمن آدینه پور', nationalCode='929986644', grade=18.77),
+ Student(studentNumber='S002', name='پریا احمدزاده', nationalCode='980085330', grade=17.28),
+ Student(studentNumber='S003', name='فاطمه اکبرزاده', nationalCode='970154550', grade=16.71),
+ Student(studentNumber='S004', name='آناهیتا الهی مهر', nationalCode='26425955', grade=19.05),
+ Student(studentNumber='S005', name='مریم امیری', nationalCode='980093341', grade=18.87),
+ Student(studentNumber='S006', name='باران برادران رحیمی', nationalCode='960043985', grade=19.07),
+ Student(studentNumber='S007', name='مایسا بصیری امین', nationalCode='960089446', grade=19.33),
+ Student(studentNumber='S008', name='دلارام ثابت عهد', nationalCode='960125620', grade=19.55),
+ Student(studentNumber='S009', name='شاینا جان محمدی', nationalCode='960068041', grade=19.47),
+ Student(studentNumber='S010', name='آیدا جوان', nationalCode='95112313', grade=16.77),
+ Student(studentNumber='S011', name='سارینا حاجی آبادی', nationalCode='999216751', grade=16.08),
+ Student(studentNumber='S012', name='هستی حسن پور جوان', nationalCode='960074198', grade=19.55),
+ Student(studentNumber='S013', name='فاطمه حسینی', nationalCode='2400410259', grade=19.07),
+ Student(studentNumber='S014', name='غزل خسروی', nationalCode='929995767', grade=15.05),
+ Student(studentNumber='S015', name='غزل ذباح', nationalCode='960110186', grade=19.25),
+ Student(studentNumber='S016', name='نازنین زهرا راشکی', nationalCode='3661516087', grade=17.02),
+ Student(studentNumber='S017', name='ویونا روح نواز', nationalCode='314458344', grade=18.70),
+ Student(studentNumber='S018', name='روژینا سعادتی', nationalCode='960051023', grade=18.20),
+ Student(studentNumber='S019', name='ترنم شعبانی', nationalCode='950083100', grade=19.37),
+ Student(studentNumber='S020', name='ستایش شفابخش', nationalCode='960126899', grade=18.36),
+ Student(studentNumber='S021', name='فاطمه شیرزادخان', nationalCode='980120756', grade=19.33),
+ Student(studentNumber='S022', name='آرزو علی جوی', nationalCode='960054316', grade=17.98),
+ Student(studentNumber='S023', name='آناهیتا قنادزاده', nationalCode='960089836', grade=18.84),
+ Student(studentNumber='S024', name='نیایش کارگر', nationalCode='929956052', grade=17.74),
+ Student(studentNumber='S025', name='باران کبریایی نسب', nationalCode='980119588', grade=18.82),
+ Student(studentNumber='S026', name='زینب کیانوش', nationalCode='970072678', grade=18.58),
+ Student(studentNumber='S027', name='ستایش محمودی', nationalCode='929904656', grade=19.33),
+ Student(studentNumber='S028', name='ستایش مشتاقی', nationalCode='361282217', grade=17.67),
+ Student(studentNumber='S029', name='مهتاب معلمی', nationalCode='960070265', grade=18.56),
+ Student(studentNumber='S030', name='باران وحدتی', nationalCode='929916913', grade=15.02),
+ ]
+
+ data = SystemData(students=initial_students)
+ save_data(data)
+ return data
+
+def save_data(data: SystemData):
+ with open(DATA_FILE, 'w', encoding='utf-8') as f:
+ json.dump(data.dict(), f, ensure_ascii=False, indent=2)
+
+# API Endpoints
+@app.get("/")
+def read_root():
+ return {"message": "TalimBot API is running"}
+
+@app.get("/api/students")
+def get_all_students():
+ data = load_data()
+ return {"students": data.students}
+
+@app.get("/api/student/{student_number}")
+def get_student(student_number: str):
+ # Return demo account if requested
+ if student_number == "DEMO":
+ return Student(
+ studentNumber="DEMO",
+ name="پریناز عاکف",
+ nationalCode="0921111111",
+ grade=0.0,
+ mbti=None,
+ learningStyle=None,
+ ams=None,
+ cooperative=None,
+ preferredStudents=[],
+ group=None
+ )
+
+ data = load_data()
+ student = next((s for s in data.students if s.studentNumber == student_number), None)
+ if not student:
+ raise HTTPException(status_code=404, detail="Student not found")
+ return student
+
+@app.put("/api/student/{student_number}")
+def update_student(student_number: str, updates: StudentUpdate):
+ # Silently ignore updates to demo account (pretend it worked)
+ if student_number == "DEMO":
+ demo_student = Student(
+ studentNumber="DEMO",
+ name="پریناز عاکف",
+ nationalCode="0921111111",
+ grade=0.0,
+ mbti=updates.mbti,
+ learningStyle=updates.learningStyle,
+ ams=updates.ams,
+ cooperative=updates.cooperative,
+ preferredStudents=updates.preferredStudents or [],
+ group=None
+ )
+ return {"success": True, "student": demo_student}
+
+ data = load_data()
+ student = next((s for s in data.students if s.studentNumber == student_number), None)
+ if not student:
+ raise HTTPException(status_code=404, detail="Student not found")
+
+ # Update only provided fields
+ update_dict = updates.dict(exclude_unset=True)
+ for key, value in update_dict.items():
+ setattr(student, key, value)
+
+ save_data(data)
+ return {"success": True, "student": student}
+
+class GroupingRequest(BaseModel):
+ courseName: str
+
+@app.post("/api/grouping/perform")
+async def perform_grouping(request: GroupingRequest):
+ data = load_data()
+
+ # Get API key from environment variable
+ api_key = os.getenv("OPENROUTER_API_KEY")
+
+ if not api_key:
+ raise HTTPException(
+ status_code=500,
+ detail="OpenRouter API key not configured. Please set OPENROUTER_API_KEY in Railway Variables tab"
+ )
+
+ # Get students with complete info (mbti and learningStyle required)
+ students_with_info = [s for s in data.students if s.mbti and s.learningStyle]
+
+ if len(students_with_info) == 0:
+ raise HTTPException(status_code=400, detail="No students have completed their profiles yet")
+
+ try:
+ # Import grouping logic
+ from grouping_logic import group_students_with_ai
+
+ # group_students_with_ai is now synchronous (uses requests library)
+ # Run it in a thread pool to avoid blocking
+ import asyncio
+ from concurrent.futures import ThreadPoolExecutor
+
+ loop = asyncio.get_event_loop()
+ with ThreadPoolExecutor() as executor:
+ grouping_result = await loop.run_in_executor(
+ executor,
+ lambda: group_students_with_ai(students_with_info, request.courseName, api_key)
+ )
+
+ # Apply grouping to students
+ for student in data.students:
+ student.group = None
+
+ for group in grouping_result["groups"]:
+ for student_number in group["students"]:
+ student = next((s for s in data.students if s.studentNumber == student_number), None)
+ if student:
+ student.group = group["groupNumber"]
+
+ data.courseName = request.courseName
+ data.groupingComplete = True
+ data.groupingResults = grouping_result
+ data.resultsVisible = False # Teacher must manually show results
+
+ save_data(data)
+ return {"success": True, "results": grouping_result}
+
+ except Exception as e:
+ raise HTTPException(status_code=500, detail=str(e))
+
+@app.get("/api/grouping/status")
+def get_grouping_status():
+ data = load_data()
+ students_with_info = [s for s in data.students if s.mbti and s.learningStyle]
+ students_grouped = [s for s in data.students if s.group is not None]
+
+ return {
+ "totalStudents": len(data.students),
+ "studentsWithCompleteInfo": len(students_with_info),
+ "studentsGrouped": len(students_grouped),
+ "groupingComplete": data.groupingComplete,
+ "resultsVisible": data.resultsVisible,
+ "courseName": data.courseName,
+ "groups": data.groupingResults.get("groups", []) if data.groupingResults else []
+ }
+
+class PasswordRequest(BaseModel):
+ password: str
+
+@app.post("/api/grouping/toggle-visibility")
+def toggle_results_visibility(request: PasswordRequest):
+ data = load_data()
+ if request.password != data.teacherPassword:
+ raise HTTPException(status_code=403, detail="Invalid password")
+
+ data.resultsVisible = not data.resultsVisible
+ save_data(data)
+ return {"success": True, "resultsVisible": data.resultsVisible}
+
+@app.post("/api/grouping/reset")
+def reset_grouping(request: PasswordRequest):
+ data = load_data()
+ if request.password != data.teacherPassword:
+ raise HTTPException(status_code=403, detail="Invalid password")
+
+ # Clear ONLY grouping-related data, keep student profiles intact
+ for student in data.students:
+ student.group = None
+
+ data.groupingComplete = False
+ data.groupingResults = None
+ data.resultsVisible = False
+ data.courseName = ""
+
+ save_data(data)
+ return {"success": True}
+
+@app.post("/api/data/reset-all")
+def reset_all_data(request: PasswordRequest):
+ data = load_data()
+ if request.password != data.teacherPassword:
+ raise HTTPException(status_code=403, detail="Invalid password")
+
+ # Clear ALL student data fields AND grouping
+ for student in data.students:
+ student.group = None
+ student.mbti = None
+ student.learningStyle = None
+ student.ams = None
+ student.cooperative = None
+ student.preferredStudents = []
+
+ data.groupingComplete = False
+ data.groupingResults = None
+ data.resultsVisible = False
+ data.courseName = ""
+
+ save_data(data)
+ return {"success": True}
+
+@app.post("/api/auth/teacher")
+def check_teacher_password(request: TeacherAuthRequest):
+ data = load_data()
+ return {"valid": request.password == data.teacherPassword}
+
+@app.post("/api/auth/student")
+def authenticate_student(request: StudentAuthRequest):
+ # Special demo account - not stored in database
+ # Check for national code without leading zero (frontend strips it)
+ if request.nationalCode == "921111111":
+ demo_student = Student(
+ studentNumber="DEMO",
+ name="پریناز عاکف",
+ nationalCode="921111111",
+ grade=0.0,
+ mbti=None,
+ learningStyle=None,
+ ams=None,
+ cooperative=None,
+ preferredStudents=[],
+ group=None
+ )
+ return {"valid": True, "student": demo_student}
+
+ data = load_data()
+ student = next((s for s in data.students if s.studentNumber == request.studentNumber), None)
+ if not student:
+ raise HTTPException(status_code=404, detail="Student not found")
+
+ if student.nationalCode != request.nationalCode:
+ raise HTTPException(status_code=401, detail="Invalid national code")
+
+ return {"valid": True, "student": student}
+
+class NationalCodeAuthRequest(BaseModel):
+ nationalCode: str
+
+@app.post("/api/auth/student-by-nationalcode")
+def authenticate_student_by_nationalcode(request: NationalCodeAuthRequest):
+ # Special demo account - not stored in database
+ # Check for national code without leading zero (frontend strips it)
+ if request.nationalCode == "921111111":
+ demo_student = Student(
+ studentNumber="DEMO",
+ name="پریناز عاکف",
+ nationalCode="921111111",
+ grade=0.0,
+ mbti=None,
+ learningStyle=None,
+ ams=None,
+ cooperative=None,
+ preferredStudents=[],
+ group=None
+ )
+ return {"valid": True, "student": demo_student}
+
+ data = load_data()
+ # Find student by national code (without leading zero)
+ student = next((s for s in data.students if s.nationalCode == request.nationalCode), None)
+ if not student:
+ raise HTTPException(status_code=404, detail="کد ملی در سیستم یافت نشد")
+
+ return {"valid": True, "student": student}
+
+@app.get("/api/student/{student_number}/group")
+def get_student_group(student_number: str):
+ # Demo account has no group
+ if student_number == "DEMO":
+ raise HTTPException(status_code=404, detail="Demo account is not part of any group")
+
+ data = load_data()
+
+ if not data.resultsVisible:
+ raise HTTPException(status_code=403, detail="Results are not yet visible")
+
+ student = next((s for s in data.students if s.studentNumber == student_number), None)
+ if not student:
+ raise HTTPException(status_code=404, detail="Student not found")
+
+ if student.group is None:
+ raise HTTPException(status_code=404, detail="Student not assigned to a group yet")
+
+ # Find all students in the same group
+ group_members = [s for s in data.students if s.group == student.group]
+
+ # Find the group details from results
+ group_info = None
+ if data.groupingResults:
+ for g in data.groupingResults.get("groups", []):
+ if g["groupNumber"] == student.group:
+ group_info = g
+ break
+
+ return {
+ "groupNumber": student.group,
+ "members": group_members,
+ "reasoning": group_info.get("reasoning", "") if group_info else "",
+ "courseName": data.courseName
+ }
+
+@app.get("/api/data/backup")
+def get_data_backup():
+ """Download complete student data as JSON backup for safekeeping"""
+ data = load_data()
+ return data.dict()
+
+# ============================================
+# STATIC FILE SERVING (Frontend HTML/CSS/JS)
+# ============================================
+
+# Define static directory path
+STATIC_DIR = Path(__file__).parent / "static"
+
+# Mount static files FIRST - this handles all non-API routes
+app.mount("/", StaticFiles(directory=str(STATIC_DIR), html=True), name="static")
+
+if __name__ == "__main__":
+ import uvicorn
+ uvicorn.run(app, host="0.0.0.0", port=8000)
diff --git a/backend/requirements.txt b/backend/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0549d5212e0b5d34cb0cd50a46451a3a4225070b
--- /dev/null
+++ b/backend/requirements.txt
@@ -0,0 +1,6 @@
+fastapi==0.104.1
+uvicorn==0.24.0
+pydantic==2.5.0
+requests==2.31.0
+python-multipart==0.0.6
+python-dotenv==1.0.0
diff --git a/backend/static/Icons/Additional/teacherIcon.png b/backend/static/Icons/Additional/teacherIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..11ea63b048234b9661ca53b6dcd970607a768d2e
Binary files /dev/null and b/backend/static/Icons/Additional/teacherIcon.png differ
diff --git a/backend/static/Icons/Additional/teacherIcon2.jpg b/backend/static/Icons/Additional/teacherIcon2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..00ba55f45c28c016de9dd78f3a9b0c622fdb2c99
Binary files /dev/null and b/backend/static/Icons/Additional/teacherIcon2.jpg differ
diff --git a/backend/static/Icons/logo/Icon.png b/backend/static/Icons/logo/Icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9dcbecafe8f1fa3138980865b9d392967f6940d
Binary files /dev/null and b/backend/static/Icons/logo/Icon.png differ
diff --git a/backend/static/Icons/logo/Logo_blueBackground.jpg b/backend/static/Icons/logo/Logo_blueBackground.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e8c775a86dbb733ff780963bb10ea73e203966b6
Binary files /dev/null and b/backend/static/Icons/logo/Logo_blueBackground.jpg differ
diff --git a/backend/static/Icons/logo/Logo_noBackground.jpg b/backend/static/Icons/logo/Logo_noBackground.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..317d414f287b697d891103c98647a6c043f1c671
Binary files /dev/null and b/backend/static/Icons/logo/Logo_noBackground.jpg differ
diff --git a/backend/static/Icons/logo/logo.png b/backend/static/Icons/logo/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9dcbecafe8f1fa3138980865b9d392967f6940d
Binary files /dev/null and b/backend/static/Icons/logo/logo.png differ
diff --git a/backend/static/Icons/studentIcon.png b/backend/static/Icons/studentIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..1b3b4f96bca1bfada5b15c165a4469773a630aab
Binary files /dev/null and b/backend/static/Icons/studentIcon.png differ
diff --git a/backend/static/Icons/teacherIcon3.png b/backend/static/Icons/teacherIcon3.png
new file mode 100644
index 0000000000000000000000000000000000000000..d19f6da898b38cb3391cb2705d7c09fdfdf44bf3
Binary files /dev/null and b/backend/static/Icons/teacherIcon3.png differ
diff --git a/backend/static/assets/css/styles.css b/backend/static/assets/css/styles.css
new file mode 100644
index 0000000000000000000000000000000000000000..a3e7640bc78e2af49a383cc469c3c574b8720124
--- /dev/null
+++ b/backend/static/assets/css/styles.css
@@ -0,0 +1,727 @@
+/* سیستم گروهبندی دانشجویان - طراحی مدرن فارسی */
+
+@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;600;700&display=swap');
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+:root {
+ --primary-color: #381c80;
+ --primary-dark: #2a1560;
+ --secondary-color: #1e3a8a;
+ --accent-color: #5b21b6;
+ --success-color: #10b981;
+ --warning-color: #f59e0b;
+ --danger-color: #ef4444;
+ --text-dark: #1f2937;
+ --text-light: #6b7280;
+ --bg-light: #f8fafc;
+ --bg-white: #ffffff;
+ --border-color: #e2e8f0;
+ --shadow-sm: 0 1px 2px 0 rgba(56, 28, 128, 0.05);
+ --shadow-md: 0 4px 6px -1px rgba(56, 28, 128, 0.1), 0 2px 4px -1px rgba(56, 28, 128, 0.06);
+ --shadow-lg: 0 10px 15px -3px rgba(56, 28, 128, 0.15), 0 4px 6px -2px rgba(56, 28, 128, 0.08);
+ --shadow-xl: 0 20px 25px -5px rgba(56, 28, 128, 0.2), 0 10px 10px -5px rgba(56, 28, 128, 0.1);
+}
+
+body {
+ font-family: 'Vazirmatn', sans-serif;
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
+ min-height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+ color: var(--text-dark);
+ line-height: 1.8;
+ direction: rtl;
+ text-align: right;
+}
+
+/* صفحات مختلف با تصاویر پسزمینه */
+body.login-page {
+ background: url('images/blueBackground.jpg') no-repeat center center fixed;
+ background-size: cover;
+}
+
+body.dashboard-page {
+ background: url('images/darkBlueMixed.png') no-repeat center center fixed;
+ background-size: cover;
+ align-items: flex-start;
+}
+
+body.teacher-page {
+ background: url('images/darkBluePlain.jpg') no-repeat center center fixed;
+ background-size: cover;
+ align-items: flex-start;
+}
+
+/* اورلی برای خوانایی بهتر متن */
+body.login-page::before,
+body.dashboard-page::before,
+body.teacher-page::before {
+ content: '';
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(56, 28, 128, 0.15);
+ z-index: -1;
+}
+
+/* انیمیشنها */
+@keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes spin {
+ to { transform: rotate(360deg); }
+}
+
+/* کانتینرها */
+.container {
+ background: rgba(255, 255, 255, 0.98);
+ backdrop-filter: blur(10px);
+ border-radius: 20px;
+ box-shadow: var(--shadow-xl);
+ padding: 35px;
+ max-width: 480px;
+ width: 100%;
+ animation: fadeInUp 0.5s ease;
+ border: 1px solid rgba(255, 255, 255, 0.3);
+}
+
+.dashboard-container {
+ max-width: 1150px;
+ padding: 25px;
+ background: transparent;
+ box-shadow: none;
+ border: none;
+}
+
+/* لوگو و هدر */
+.logo-section {
+ text-align: center;
+ margin-bottom: 20px;
+}
+
+.logo-section img {
+ max-width: 200px;
+ height: auto;
+ margin-bottom: 15px;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 25px;
+}
+
+.header h1 {
+ font-size: 1.7rem;
+ font-weight: 700;
+ color: var(--primary-color);
+ margin-bottom: 8px;
+}
+
+.header p {
+ color: var(--text-light);
+ font-size: 0.95rem;
+}
+
+/* انتخاب نقش */
+.role-selector {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12px;
+ margin-bottom: 20px;
+}
+
+.role-option {
+ padding: 18px 12px;
+ border: 2px solid var(--border-color);
+ border-radius: 12px;
+ text-align: center;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ background: var(--bg-white);
+}
+
+.role-option:hover {
+ border-color: var(--primary-color);
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-md);
+}
+
+.role-option.selected {
+ border-color: var(--primary-color);
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
+ color: white;
+}
+
+.role-option .icon {
+ font-size: 2.2rem;
+ margin-bottom: 8px;
+}
+
+.role-option h3 {
+ font-size: 0.95rem;
+ font-weight: 600;
+}
+
+/* فرمها */
+.form-group {
+ margin-bottom: 18px;
+}
+
+.form-group label {
+ display: block;
+ font-weight: 600;
+ margin-bottom: 8px;
+ color: var(--text-dark);
+ font-size: 0.9rem;
+}
+
+.form-group input,
+.form-group select,
+.form-group textarea {
+ width: 100%;
+ padding: 12px 15px;
+ border: 2px solid var(--border-color);
+ border-radius: 10px;
+ font-size: 0.95rem;
+ transition: all 0.3s ease;
+ background: var(--bg-white);
+ font-family: 'Vazirmatn', sans-serif;
+}
+
+.form-group input:focus,
+.form-group select:focus,
+.form-group textarea:focus {
+ outline: none;
+ border-color: var(--primary-color);
+ box-shadow: 0 0 0 3px rgba(56, 28, 128, 0.1);
+}
+
+.form-row {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 15px;
+}
+
+/* دکمهها */
+.btn {
+ width: 100%;
+ padding: 13px 20px;
+ border: none;
+ border-radius: 10px;
+ font-size: 0.95rem;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ text-align: center;
+ text-decoration: none;
+ display: inline-block;
+ font-family: 'Vazirmatn', sans-serif;
+}
+
+/* دکمههای جمعوجور که در وسط کانتینر قرار میگیرند (یک سوم/نیم عرض) */
+.btn--compact {
+ display: block;
+ width: 33%;
+ max-width: 360px;
+ min-width: 160px;
+ margin: 0.35rem auto;
+ padding: 10px 12px;
+ border-radius: 10px;
+}
+
+.btn-primary {
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
+ color: white;
+}
+
+.btn-primary:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-lg);
+}
+
+.btn-primary:active {
+ transform: translateY(0);
+}
+
+.btn-secondary {
+ background: var(--bg-light);
+ color: var(--text-dark);
+ border: 2px solid var(--border-color);
+}
+
+.btn-secondary:hover {
+ background: var(--border-color);
+}
+
+.btn-success {
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
+ color: white;
+}
+
+.btn-success:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-lg);
+}
+
+/* کارتها */
+.card {
+ background: rgba(255, 255, 255, 0.98);
+ backdrop-filter: blur(10px);
+ border-radius: 16px;
+ padding: 22px;
+ margin-bottom: 18px;
+ border: 1px solid rgba(255, 255, 255, 0.4);
+ box-shadow: 0 8px 32px rgba(56, 28, 128, 0.12);
+ transition: all 0.3s ease;
+}
+
+/* Header card tweaks: centered title and positioned logout button */
+.header-card {
+ padding-top: 14px;
+ padding-bottom: 14px;
+}
+
+.header-card .logout-btn {
+ position: absolute;
+ right: 18px; /* put logout on the right like previous layout */
+ top: 14px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 8px 12px;
+ color: var(--text-dark);
+ background: var(--bg-light);
+ border: 1px solid var(--border-color);
+ border-radius: 10px;
+ text-decoration: none;
+ font-weight: 700;
+ transition: all 0.18s ease;
+}
+
+.header-card .logout-btn:hover {
+ background: rgba(56, 28, 128, 0.04);
+ transform: translateY(-2px);
+}
+
+/* two-column grid used in teacher page to align cards horizontally */
+.two-col-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 16px;
+}
+
+@media (max-width: 900px) {
+ .two-col-grid {
+ grid-template-columns: 1fr;
+ }
+}
+
+/* small inline button variant for header logout when needed */
+.btn--small {
+ display: inline-block;
+ width: auto;
+ padding: 8px 12px;
+}
+
+/* Group results layout */
+#groupResultsList {
+ display: flex;
+ gap: 16px;
+ flex-wrap: wrap;
+}
+
+.group-card {
+ flex: 1 1 calc(50% - 16px);
+ max-width: calc(50% - 16px);
+ box-sizing: border-box;
+ padding: 18px;
+ background: var(--bg-light);
+ border-radius: 12px;
+ border-right: 4px solid var(--primary-color);
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.group-card-header {
+ color: var(--primary-color);
+ margin: 0;
+ font-size: 1.05rem;
+}
+
+.group-reasoning {
+ color: var(--text-light);
+ font-size: 0.9rem;
+ margin: 0;
+}
+
+.group-members-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ max-height: 220px;
+ overflow: auto;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.group-member-item {
+ padding: 10px;
+ background: white;
+ border-radius: 8px;
+ font-size: 0.9rem;
+}
+
+@media (max-width: 900px) {
+ .group-card {
+ flex-basis: 100%;
+ max-width: 100%;
+ }
+}
+
+/* cap the overall results area so it doesn't push the whole page too far; individual groups scroll internally */
+#groupResultsCard .card-body {
+ max-height: 520px;
+ overflow: auto;
+}
+
+.card:hover {
+ box-shadow: 0 12px 40px rgba(56, 28, 128, 0.18);
+ transform: translateY(-3px);
+}
+
+.card-header {
+ font-size: 1.15rem;
+ font-weight: 700;
+ color: var(--primary-color);
+ margin-bottom: 15px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.card-body {
+ color: var(--text-dark);
+}
+
+/* اطلاعات نمایشی */
+.info-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
+ gap: 12px;
+ margin-bottom: 15px;
+}
+
+.info-display {
+ background: var(--bg-light);
+ padding: 12px 15px;
+ border-radius: 10px;
+ border-right: 3px solid var(--primary-color);
+}
+
+.info-display .label {
+ font-weight: 500;
+ color: var(--text-light);
+ font-size: 0.8rem;
+ margin-bottom: 4px;
+}
+
+.info-display .value {
+ font-size: 1.05rem;
+ color: var(--text-dark);
+ font-weight: 700;
+}
+
+/* لینکهای تست */
+.links-section {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12px;
+ margin-bottom: 15px;
+}
+
+.external-link {
+ padding: 16px 12px;
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
+ border: none;
+ border-radius: 12px;
+ text-align: center;
+ text-decoration: none;
+ color: white;
+ font-weight: 600;
+ transition: all 0.3s ease;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 6px;
+ font-size: 0.9rem;
+ box-shadow: 0 4px 12px rgba(56, 28, 128, 0.2);
+}
+
+.external-link:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 8px 20px rgba(56, 28, 128, 0.3);
+ background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 100%);
+}
+
+.external-link .icon {
+ font-size: 1.8rem;
+}
+
+/* هشدارها */
+.alert {
+ padding: 12px 16px;
+ border-radius: 10px;
+ margin-bottom: 15px;
+ font-weight: 500;
+ font-size: 0.9rem;
+}
+
+.alert-info {
+ background: rgba(56, 28, 128, 0.1);
+ color: var(--primary-color);
+ border: 1px solid rgba(56, 28, 128, 0.3);
+}
+
+.alert-success {
+ background: rgba(16, 185, 129, 0.1);
+ color: var(--success-color);
+ border: 1px solid rgba(16, 185, 129, 0.3);
+}
+
+.alert-warning {
+ background: rgba(245, 158, 11, 0.1);
+ color: var(--warning-color);
+ border: 1px solid rgba(245, 158, 11, 0.3);
+}
+
+/* آمار */
+.stats-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
+ gap: 15px;
+ margin-bottom: 20px;
+}
+
+.stat-card {
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
+ color: white;
+ padding: 20px;
+ border-radius: 12px;
+ text-align: center;
+}
+
+.stat-card .stat-value {
+ font-size: 2.2rem;
+ font-weight: 700;
+ margin-bottom: 5px;
+}
+
+.stat-card .stat-label {
+ font-size: 0.9rem;
+ opacity: 0.95;
+}
+
+/* لیست گروه */
+.group-list {
+ list-style: none;
+}
+
+.group-member {
+ background: var(--bg-light);
+ padding: 12px 15px;
+ border-radius: 10px;
+ margin-bottom: 10px;
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ transition: all 0.3s ease;
+}
+
+.group-member:hover {
+ background: var(--border-color);
+ transform: translateX(5px);
+}
+
+.group-member .member-icon {
+ font-size: 1.4rem;
+}
+
+.group-member .member-info {
+ flex: 1;
+}
+
+.group-member .member-name {
+ font-weight: 600;
+ color: var(--text-dark);
+ font-size: 0.95rem;
+ margin-bottom: 3px;
+}
+
+.group-member .member-details {
+ font-size: 0.8rem;
+ color: var(--text-light);
+}
+
+/* چکباکسها */
+.checkbox-group {
+ max-height: 250px;
+ overflow-y: auto;
+ border: 2px solid var(--border-color);
+ border-radius: 10px;
+ padding: 8px;
+}
+
+.checkbox-item {
+ padding: 10px;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ cursor: pointer;
+ border-radius: 8px;
+ transition: all 0.2s ease;
+}
+
+.checkbox-item:hover {
+ background: var(--bg-light);
+}
+
+.checkbox-item input[type="checkbox"] {
+ width: 18px;
+ height: 18px;
+ cursor: pointer;
+}
+
+.checkbox-item label {
+ cursor: pointer;
+ margin: 0;
+ font-weight: 500;
+ font-size: 0.9rem;
+}
+
+/* لینک بازگشت */
+.back-link {
+ display: inline-block;
+ margin-bottom: 15px;
+ color: var(--primary-color);
+ text-decoration: none;
+ font-weight: 600;
+ transition: all 0.3s ease;
+ font-size: 0.95rem;
+}
+
+.back-link:hover {
+ transform: translateX(5px);
+}
+
+/* حالت خالی */
+.empty-state {
+ text-align: center;
+ padding: 35px 20px;
+}
+
+.empty-state .icon {
+ font-size: 3.5rem;
+ opacity: 0.3;
+ margin-bottom: 15px;
+}
+
+.empty-state h3 {
+ font-size: 1.2rem;
+ color: var(--text-dark);
+ margin-bottom: 10px;
+}
+
+.empty-state p {
+ color: var(--text-light);
+ font-size: 0.9rem;
+}
+
+/* لودینگ */
+.loading {
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ border: 3px solid rgba(255, 255, 255, 0.3);
+ border-radius: 50%;
+ border-top-color: white;
+ animation: spin 1s ease-in-out infinite;
+}
+
+/* طراحی ریسپانسیو */
+@media (max-width: 768px) {
+ .container {
+ padding: 25px;
+ }
+
+ .header h1 {
+ font-size: 1.5rem;
+ }
+
+ .role-selector {
+ grid-template-columns: 1fr;
+ }
+
+ .links-section {
+ grid-template-columns: 1fr;
+ }
+
+ .stats-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .form-row {
+ grid-template-columns: 1fr;
+ }
+
+ .info-grid {
+ grid-template-columns: 1fr;
+ }
+}
+
+@media (min-width: 769px) and (max-width: 1024px) {
+ .dashboard-container {
+ max-width: 900px;
+ }
+}
+
+/* تنظیمات اسکرول */
+::-webkit-scrollbar {
+ width: 8px;
+}
+
+::-webkit-scrollbar-track {
+ background: var(--bg-light);
+}
+
+::-webkit-scrollbar-thumb {
+ background: var(--primary-color);
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: var(--primary-dark);
+}
+
+/* ترانزیشنهای نرم */
+a, button, input, select, .role-option, .card, .external-link, .checkbox-item {
+ transition: all 0.3s ease;
+}
diff --git a/backend/static/assets/js/data.js b/backend/static/assets/js/data.js
new file mode 100644
index 0000000000000000000000000000000000000000..c2382272534ec015085a2cf14822bb433c278b44
--- /dev/null
+++ b/backend/static/assets/js/data.js
@@ -0,0 +1,244 @@
+// Student Grouping System - Data Management
+// This file handles all data operations using Backend API
+
+// Backend API Configuration
+// Auto-detects if running on Railway deployment or localhost
+function getApiBaseUrl() {
+ // When deployed to Railway, it will use the same domain
+ // Railway serves both frontend and backend from the same URL
+ // So we use relative paths for API calls
+ if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
+ // PRODUCTION: Running on Railway - use relative paths
+ return '/api';
+ }
+
+ // DEVELOPMENT: Running locally
+ return 'http://localhost:8000/api';
+}
+
+const API_BASE_URL = getApiBaseUrl();
+
+// Utility function for API calls
+async function apiCall(endpoint, options = {}) {
+ try {
+ const response = await fetch(`${API_BASE_URL}${endpoint}`, {
+ ...options,
+ headers: {
+ 'Content-Type': 'application/json',
+ ...options.headers
+ }
+ });
+
+ if (!response.ok) {
+ const error = await response.json();
+ throw new Error(error.detail || 'API request failed');
+ }
+
+ return await response.json();
+ } catch (error) {
+ console.error('API Error:', error);
+ throw error;
+ }
+}
+
+// Get all data (for backward compatibility)
+async function getData() {
+ const students = await getAllStudents();
+ const status = await getGroupingStats();
+ return {
+ students: students,
+ courseName: status.courseName,
+ groupingComplete: status.groupingComplete,
+ resultsVisible: status.resultsVisible,
+ teacherPassword: 'teacher123'
+ };
+}
+
+// Get student by student number
+async function getStudent(studentNumber) {
+ try {
+ return await apiCall(`/student/${studentNumber}`);
+ } catch (error) {
+ return null;
+ }
+}
+
+// Update student information
+async function updateStudent(studentNumber, updates) {
+ try {
+ const result = await apiCall(`/student/${studentNumber}`, {
+ method: 'PUT',
+ body: JSON.stringify(updates)
+ });
+ return result.success;
+ } catch (error) {
+ return false;
+ }
+}
+
+// Get all students
+async function getAllStudents() {
+ const result = await apiCall('/students');
+ return result.students;
+}
+
+// Check if a student number exists in the system
+async function studentExists(studentNumber) {
+ const student = await getStudent(studentNumber);
+ return student !== null;
+}
+
+// Get students with complete information (REQUIRED fields only: MBTI and Learning Style)
+async function getStudentsWithCompleteInfo() {
+ const students = await getAllStudents();
+ return students.filter(s => s.mbti && s.learningStyle);
+}
+
+// Check if a student has complete profile (all fields filled)
+async function hasCompleteProfile(studentNumber) {
+ const student = await getStudent(studentNumber);
+ if (!student) return false;
+
+ return !!(student.mbti && student.learningStyle &&
+ student.ams !== null && student.cooperative !== null);
+}
+
+// Get completion percentage for a student
+async function getProfileCompletion(studentNumber) {
+ const student = await getStudent(studentNumber);
+ if (!student) return 0;
+
+ let completed = 0;
+ const total = 4;
+
+ if (student.mbti) completed++;
+ if (student.learningStyle) completed++;
+ if (student.ams !== null) completed++;
+ if (student.cooperative !== null) completed++;
+
+ return Math.round((completed / total) * 100);
+}
+
+// Get grouping statistics
+async function getGroupingStats() {
+ return await apiCall('/grouping/status');
+}
+
+// Check if grouping is complete
+async function isGroupingComplete() {
+ const stats = await getGroupingStats();
+ return stats.groupingComplete;
+}
+
+// Get course name
+async function getCourseName() {
+ const stats = await getGroupingStats();
+ return stats.courseName;
+}
+
+// Check teacher password
+async function checkTeacherPassword(password) {
+ try {
+ const result = await apiCall('/auth/teacher', {
+ method: 'POST',
+ body: JSON.stringify({ password })
+ });
+ return result.valid;
+ } catch (error) {
+ return false;
+ }
+}
+
+// Get student's group (only if results are visible)
+async function getStudentGroup(studentNumber) {
+ try {
+ return await apiCall(`/student/${studentNumber}/group`);
+ } catch (error) {
+ if (error.message.includes('not yet visible')) {
+ return { error: 'results_not_visible', message: 'نتایج هنوز توسط معلم نمایش داده نشده است.' };
+ }
+ if (error.message.includes('not assigned')) {
+ return { error: 'not_assigned', message: 'شما هنوز به گروهی اختصاص داده نشدهاید.' };
+ }
+ throw error;
+ }
+}
+
+// Reset grouping only (keep student data)
+async function resetGrouping(password) {
+ return await apiCall('/grouping/reset', {
+ method: 'POST',
+ body: JSON.stringify({ password })
+ });
+}
+
+// Reset ALL data (student profiles + grouping)
+async function resetAllData(password) {
+ return await apiCall('/data/reset-all', {
+ method: 'POST',
+ body: JSON.stringify({ password })
+ });
+}
+
+// Toggle results visibility
+async function toggleResultsVisibility(password) {
+ return await apiCall('/grouping/toggle-visibility', {
+ method: 'POST',
+ body: JSON.stringify({ password })
+ });
+}
+
+// Legacy functions for backward compatibility (these are handled by backend now)
+function saveData(data) {
+ console.warn('saveData is deprecated - data is automatically saved to backend');
+}
+
+function initializeData() {
+ console.log('Data is managed by backend');
+ return true;
+}
+
+function addNewStudent(studentNumber, name, grade = 15) {
+ console.warn('addNewStudent should be done through admin panel');
+ return { success: false, message: 'Use backend API for adding students' };
+}
+
+function saveStudents(students) {
+ console.warn('saveStudents is deprecated - use backend API');
+}
+
+function deleteStudent(studentNumber) {
+ console.warn('deleteStudent should be done through admin panel');
+ return false;
+}
+
+function setGroupingComplete(status) {
+ console.warn('setGroupingComplete is handled by backend');
+}
+
+function setCourseName(name) {
+ console.warn('setCourseName is handled by backend');
+}
+
+function resetData() {
+ console.warn('resetData should be done through teacher dashboard');
+}
+
+// Export functions for use in other files
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = {
+ getData,
+ getStudent,
+ updateStudent,
+ getAllStudents,
+ studentExists,
+ getStudentsWithCompleteInfo,
+ hasCompleteProfile,
+ getProfileCompletion,
+ isGroupingComplete,
+ getCourseName,
+ checkTeacherPassword,
+ getGroupingStats,
+ getStudentGroup
+ };
+}
diff --git a/backend/static/assets/js/grouping.js b/backend/static/assets/js/grouping.js
new file mode 100644
index 0000000000000000000000000000000000000000..6d94520303c994b576facf2ddb59a40e3ade1c0b
--- /dev/null
+++ b/backend/static/assets/js/grouping.js
@@ -0,0 +1,159 @@
+// Grouping Logic with Backend API Integration
+// This file handles the student grouping process through the backend
+
+// API_BASE_URL is defined in data.js (loaded first)
+// No need to redeclare it here to avoid "already been declared" error
+
+/**
+ * Main grouping function - calls backend API
+ * @param {string} courseName - The name of the course
+ * @returns {Promise} - Grouping results
+ */
+async function performGrouping(courseName) {
+ try {
+ console.log(`Requesting grouping from backend for course: ${courseName}`);
+
+ const response = await fetch(`${API_BASE_URL}/grouping/perform`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ courseName
+ })
+ });
+
+ if (!response.ok) {
+ const error = await response.json();
+ throw new Error(error.detail || 'Grouping failed');
+ }
+
+ const result = await response.json();
+ console.log('Grouping successful!', result);
+ return result.results;
+ } catch (error) {
+ console.error('Grouping error:', error);
+ throw error;
+ }
+}
+
+/**
+ * Get grouping statistics
+ * @returns {Promise} - Statistics about current grouping
+ */
+async function getGroupingStats() {
+ try {
+ const response = await fetch(`${API_BASE_URL}/grouping/status`);
+ if (!response.ok) {
+ throw new Error('Failed to get grouping status');
+ }
+ return await response.json();
+ } catch (error) {
+ console.error('Error getting grouping stats:', error);
+ throw error;
+ }
+}
+
+/**
+ * Toggle visibility of results to students
+ * @param {string} password - Teacher password
+ * @returns {Promise} - New visibility status
+ */
+async function toggleResultsVisibility(password) {
+ try {
+ const response = await fetch(`${API_BASE_URL}/grouping/toggle-visibility`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ password })
+ });
+
+ if (!response.ok) {
+ const error = await response.json();
+ throw new Error(error.detail || 'Failed to toggle visibility');
+ }
+
+ const result = await response.json();
+ return result;
+ } catch (error) {
+ console.error('Error toggling visibility:', error);
+ throw error;
+ }
+}
+
+/**
+ * Reset grouping (clear all group assignments)
+ * @param {string} password - Teacher password
+ */
+async function resetGrouping(password) {
+ try {
+ const response = await fetch(`${API_BASE_URL}/grouping/reset`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ password })
+ });
+
+ if (!response.ok) {
+ const error = await response.json();
+ throw new Error(error.detail || 'Failed to reset grouping');
+ }
+
+ return await response.json();
+ } catch (error) {
+ console.error('Error resetting grouping:', error);
+ throw error;
+ }
+}
+
+/**
+ * Get student's group information
+ * @param {string} studentNumber - Student number
+ * @returns {Promise} - Group information
+ */
+async function getStudentGroup(studentNumber) {
+ try {
+ const response = await fetch(`${API_BASE_URL}/student/${studentNumber}/group`);
+
+ if (!response.ok) {
+ const error = await response.json();
+ if (error.detail.includes('not yet visible')) {
+ return {
+ error: 'not_visible',
+ message: 'نتایج هنوز توسط استاد نمایش داده نشده است.'
+ };
+ }
+ if (error.detail.includes('not assigned')) {
+ return {
+ error: 'not_assigned',
+ message: 'شما هنوز به گروهی اختصاص داده نشدهاید.'
+ };
+ }
+ throw new Error(error.detail);
+ }
+
+ return await response.json();
+ } catch (error) {
+ console.error('Error getting student group:', error);
+ throw error;
+ }
+}
+
+// Legacy function - now handled by backend
+function applyGrouping(groupingResult, courseName) {
+ console.warn('applyGrouping is now handled automatically by the backend');
+}
+
+// Export functions
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = {
+ performGrouping,
+ getGroupingStats,
+ toggleResultsVisibility,
+ resetGrouping,
+ getStudentGroup,
+ applyGrouping
+ };
+}
diff --git a/backend/static/index.html b/backend/static/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..903dd5808b2361d191525d64ccd61ea3cd42ab0c
--- /dev/null
+++ b/backend/static/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ TalimBot - سیستم گروهبندی هوشمند
+
+
+
+ در حال انتقال به صفحه ورود...
+
+
diff --git a/backend/static/pages/ams-questionnaire.html b/backend/static/pages/ams-questionnaire.html
new file mode 100644
index 0000000000000000000000000000000000000000..bb7fc73619b8ab8769a2e9daff631fd5723524e1
--- /dev/null
+++ b/backend/static/pages/ams-questionnaire.html
@@ -0,0 +1,436 @@
+
+
+
+
+
+ پرسشنامه انگیزش تحصیلی (AMS) - سیستم گروهبندی
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TalimBot
+
پرسشنامه انگیزش تحصیلی
+
+
+
+
+
+
+ بازگشت به داشبورد
+
+
+
+
+
+
+
+
+
+
پرسشنامه انگیزش تحصیلی (AMS)
+
لطفاً برای هر جمله مشخص کنید که تا چه حد درباره شما درست است
+
+
+
+
+ 0 از 28 سؤال پاسخ داده شده
+
+
+
+
+
+
+
+
+
+
+
+
+
+
نتایج پرسشنامه انگیزش تحصیلی
+
+
+
+
+
+
+
+
+
+
+
+ ذخیره و بازگشت
+
+
+ بستن
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/backend/static/pages/cooperative-questionnaire.html b/backend/static/pages/cooperative-questionnaire.html
new file mode 100644
index 0000000000000000000000000000000000000000..09093655ceeefd9bbb0e0811b94873c94cec0a51
--- /dev/null
+++ b/backend/static/pages/cooperative-questionnaire.html
@@ -0,0 +1,401 @@
+
+
+
+
+
+ پرسشنامه یادگیری مشارکتی - سیستم گروهبندی
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TalimBot
+
پرسشنامه یادگیری مشارکتی
+
+
+
+
+
+
+ بازگشت به داشبورد
+
+
+
+
+
+
+
+
+
+
پرسشنامه یادگیری مشارکتی
+
بر اساس مدل جانسون و جانسون، ۱۹۹۴
+
لطفاً میزان موافقت خود را با هر جمله مشخص کنید
+
+
+
+
+ 0 از 25 سؤال پاسخ داده شده
+
+
+
+
+
+
+
+
+
+
+
+
+
+
نتایج پرسشنامه یادگیری مشارکتی
+
+
+
+
+
+
+
+
+
+
+
+ ذخیره و بازگشت
+
+
+ بستن
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/backend/static/pages/group-view.html b/backend/static/pages/group-view.html
new file mode 100644
index 0000000000000000000000000000000000000000..9512ab4d458e7f74b491f84043f4b3cb382f4f0c
--- /dev/null
+++ b/backend/static/pages/group-view.html
@@ -0,0 +1,405 @@
+
+
+
+
+
+ گروه من - سیستم گروهبندی
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TalimBot
+
سیستم گروهبندی هوشمند
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
گروه مطالعاتی شما
+
+
+
+
+
+
+
+
+
+
در حال بارگذاری اطلاعات گروه...
+
+
+
+
+
+
+
+
+
+
+
گروهبندی هنوز انجام نشده است
+
معلم هنوز فرآیند گروهبندی را تکمیل نکرده است.
+
لطفاً بعداً دوباره بررسی کنید یا با معلم خود تماس بگیرید.
+
+
+
+ بازگشت به داشبورد
+
+
+ بروزرسانی صفحه
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
پروفایل من در گروه
+
+
+
+ نوع شخصیت MBTI
+ -
+
+
+ سبک یادگیری
+ -
+
+
+ نمره
+ -
+
+
+
+
+
+
+
+
+
+
+
+ بازگشت به داشبورد
+
+
+
+
+
+ بروزرسانی اطلاعات
+
+
+
+
+
+
+
+
+
+
+
+
خطا در بارگذاری اطلاعات!
+
قادر به بارگذاری اطلاعات گروه نیستیم.
+
+
+
+ بازگشت به داشبورد
+
+
+
+
+
+
+
+
+
+
+
© ۲۰۲۵ TalimBot - سیستم گروهبندی هوشمند دانش آموزان
+
+
+
+
+
+
+
+
+
+
diff --git a/backend/static/pages/login.html b/backend/static/pages/login.html
new file mode 100644
index 0000000000000000000000000000000000000000..e867b513d3d27280945e601c69e38b76856fbd94
--- /dev/null
+++ b/backend/static/pages/login.html
@@ -0,0 +1,274 @@
+
+
+
+
+
+ ورود - سیستم گروهبندی دانش آموزان
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
سیستم گروهبندی هوشمند
+
مدیریت و گروهبندی دانش آموزان بر اساس شخصیت و سبک یادگیری
+
+
+
+ TalimBot
+
+
+
+
+
+
+
+
+
+
سیستم گروهبندی دانش آموزان
+
لطفاً نقش خود را انتخاب کنید
+
+
+
+
+
+
+
+ دانش آموز
+
+
+
+ معلم
+
+
+
+
+
+
+
+
+
+
+
+
نسخه 1.0.0 | آبان 1404
+
+
+
+
+
+
+
+
+
diff --git a/backend/static/pages/student-dashboard.html b/backend/static/pages/student-dashboard.html
new file mode 100644
index 0000000000000000000000000000000000000000..3065f30b58df9fbb8b7b0080fcec55a6a842623a
--- /dev/null
+++ b/backend/static/pages/student-dashboard.html
@@ -0,0 +1,580 @@
+
+
+
+
+
+
+
+
+
+ داشبورد دانش آموز - سیستم گروهبندی
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TalimBot
+
سیستم گروهبندی هوشمند
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
لطفاً تمام تستهای شخصیتی خود را تکمیل کنید و اطلاعات را ذخیره نمایید.
+
+
💡 چرا این اطلاعات مهم است؟ سیستم گروهبندی هوشمند از روشهای علمی مانند ZPD ، تکمیل شخصیتی MBTI، و تنوع سبک یادگیری VARK برای ساخت بهترین تیمها استفاده میکند. هر چه اطلاعات کاملتری وارد کنید، گروهبندی دقیقتری خواهید داشت!
+
+
+
+
+
+
+
+
+
+
+
تستهای تکمیل شده
+
0 / 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
MBTI - تیپ شخصیتی
+
شناخت تیپ شخصیتی برای ایجاد تعادل در گروه و درک نقاط قوت شما
+
+
+
+
+
+ نتیجه تست
+
+ انتخاب کنید...
+ INTJ
+ INTP
+ ENTJ
+ ENTP
+ INFJ
+ INFP
+ ENFJ
+ ENFP
+ ISTJ
+ ISFJ
+ ESTJ
+ ESFJ
+ ISTP
+ ISFP
+ ESTP
+ ESFP
+
+
+
+
+
+
+
+
+
+
+
VARK - سبک یادگیری
+
شناسایی سبک یادگیری شما (دیداری، شنیداری، خواندن/نوشتن، حرکتی)
+
+
+
+
+
+ نتیجه تست
+
+ انتخاب کنید...
+ Visual (دیداری)
+ Aural (شنیداری)
+ Read/Write (خواندن/نوشتن)
+ Kinesthetic (حرکتی/عملی)
+
+
+
+
+
+
+
+
+
+
+
AMS - انگیزش تحصیلی
+
سنجش انگیزه درونی و بیرونی برای یادگیری و پیشرفت تحصیلی
+
+
+
+
+
+ نمره کل (از 196)
+
+
+
+
+
+
+
+
+
+
+
توانایی همکاری
+
سنجش مهارتهای کار گروهی، تعامل و همکاری با دیگران
+
+
+
+
+
+ نمره کل (از 125)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ترجیحات همگروهی
+
+
میتوانید حداکثر 4 نفر از همکلاسیهای خود را که دوست دارید در یک گروه باشید انتخاب کنید (اختیاری)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ذخیره تمام اطلاعات
+
+
+
+
+
+ مشاهده گروه من
+
+
+
+
+
+
+
+
+
+
+
اطلاعات با موفقیت ذخیره شد!
+
+
+
+
+
+
+
+
نسخه 1.0.0 | آبان 1404
+
© ۲۰۲۵ TalimBot - سیستم گروهبندی هوشمند دانش آموزان
+
+
+
+
+
+
+
+
diff --git a/backend/static/pages/student-data.html b/backend/static/pages/student-data.html
new file mode 100644
index 0000000000000000000000000000000000000000..e69f90edf49e85ea49ab49029fc8645c3bf72245
--- /dev/null
+++ b/backend/static/pages/student-data.html
@@ -0,0 +1,388 @@
+
+
+
+
+
+ ورود اطلاعات دانشآموزان - TalimBot
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ورود اطلاعات دانشآموزان
+
+
اطلاعات دانشآموزان را وارد کنید تا در سیستم گروهبندی ثبت شود
+
+
+
+
+
+
+
+
+
+
راهنما
+
نام، شماره دانشآموزی و نمره را وارد کنید. پس از هر ورودی روی "ذخیره" کلیک کنید تا فرم خالی شود و آماده ورود دانشآموز بعدی باشد.
+
+
+
+
+
+
+
+
+
+
تعداد دانشآموزان ثبت شده
+
0
+
+
+
+
+
+
+
+
+
آخرین دانشآموز ثبت شده
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ افزودن دانشآموز
+
+
+
+
+
+
+
+
+
+
+
+
+
+ لیست دانشآموزان ذخیره شده
+
+
+
+
+
+
+
+ ردیف
+ شماره دانشآموز
+ نام دانشآموز
+ نمره (از 20)
+
+
+
+
+
+
+
+
+ هنوز دانشآموزی ثبت نشده است
+ از فرم بالا برای افزودن دانشآموز استفاده کنید
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
نسخه 1.0.0 | آبان 1404
+
© ۲۰۲۵ TalimBot - سیستم گروهبندی هوشمند دانش آموزان
+
+
+
+
+
+
+
+
+
+
+
diff --git a/backend/static/pages/teacher-dashboard.html b/backend/static/pages/teacher-dashboard.html
new file mode 100644
index 0000000000000000000000000000000000000000..4025d009e959b9a964cce03f3e3a9d41d373fbfc
--- /dev/null
+++ b/backend/static/pages/teacher-dashboard.html
@@ -0,0 +1,1017 @@
+
+
+
+
+
+
+
+
+
+ داشبورد معلم - سیستم گروهبندی
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ پنل مدیریت معلم
+
+
مدیریت گروهبندی دانش آموزان
+
+
+
+
+
+
+
+
+
+
تعداد کل دانش آموزان
+
30
+
+
+
+
+
+
+
+
+
پروفایلهای تکمیل شده
+
0
+
+
+
+
+
+
+
+
+
دانش آموزان گروهبندی شده
+
0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ اطلاعات درس
+
+
+
+
+
+
+
+
+
+
+ وضعیت گروهبندی
+
+
+
+
+
+
+
+
+
+
+ ⚙️
+ عملیات گروهبندی
+
+
+
+
+
+
+
+ آماده گروهبندی
+
+
+ 0
+ دانش آموز آماده گروهبندی هستند.
+
+
+
🎯 معیارهای گروهبندی علمی (سنین 15-16 سال، به ترتیب اولویت):
+
+
1. بهینهسازی ZPD ناحیه رشد نزدیک (30%): ترکیب نمرات بالا با متوسط برای یادگیری همیاری و آموزش همتا-به-همتا
+
2. تکمیل MBTI (25%): ترکیب شخصیتهای مکمل (نه مشابه) - مثال: ENFP+INTJ، ENTP+INFJ - تعادل درونگرا/برونگرا
+
3. تنوع VARK (20%): ترکیب سبکهای یادگیری دیداری، شنیداری، خواندن/نوشتن و حرکتی در هر گروه
+
4. انگیزش تحصیلی - AMS (15%): توزیع دانشآموزان با انگیزه بالا (>140) در گروهها برای الهامبخشی
+
5. مهارت همکاری (10%): دانشآموزان با مهارت همکاری بالا (>88) به عنوان تسهیلگر اجتماعی
+
6. ویژگیهای درس: تطبیق با نیازهای درس (ریاضی: تفکر منطقی، ادبیات: احساسی)
+
7. ترجیحات دانشآموزان (5%): فقط اگر با معیارهای بالا تضاد نداشته باشد - نوجوانان از کار با افراد جدید رشد میکنند
+
+
+
+
+ ⚡ نکته مهم: فقط دانشآموزانی که MBTI و سبک یادگیری خود را تکمیل کردهاند در گروهبندی شرکت میکنند.
+ اگر دانشآموزی دوستان خود را انتخاب کرده ولی آن دوستان فرم را تکمیل نکردهاند، این انتخاب در نظر گرفته نمیشود.
+
+
+
+
+
+
+
+
+
+ شروع فرآیند گروهبندی
+
+
+
+
+
+
+ بازنشانی گروهبندی
+
+
+
+
+
+
+ نمایش نتایج به دانشآموزان
+
+
+
+
+
+
در حال پردازش الگوریتم گروهبندی...
+
ممکن است چند لحظه طول بکشد
+
+
+
+
+
+
+
+ گروهبندی با موفقیت انجام شد!
+
+
+
+
+
+
+
+
+ 📋
+ لیست تمام دانش آموزان
+
+
+
+
+ نمایش لیست دانش آموزان
+
+
+ 📥 دانلود همه دادهها (JSON)
+
+
+
+
+
+
+
+ شماره دانش آموز
+ نام
+ MBTI
+ سبک یادگیری
+ AMS
+ Cooperative
+ معدل
+ گروه
+ عملیات
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
بازنشانی دادهها
+
+ این عملیات تمام اطلاعات سیستم را به حالت اولیه بازمیگرداند. همه 30 دانشآموز (S001 تا S030) بازگردانده میشوند،
+ تمام تغییرات و گروهبندیها حذف میشوند و سیستم به حالت پیشفرض برمیگردد.
+
+
+
+
+
+ بازنشانی دادهها
+
+
+
+
+
+
+
+
+
+
+
پر کردن دادههای تست
+
+ برای تست سیستم گروهبندی، 10 دانشآموز اول (S001 تا S010) را با دادههای کامل و تصادفی پر کنید.
+ این شامل MBTI، VARK، نمرات AMS و Cooperative و ترجیحات دانشآموزی میشود.
+
+
+
+
+
+
+ پر کردن دادههای تست
+
+
+
+
+
+
+
+
+
+
+
+
+
وارد کردن دادهها از JSON
+
+ یک فایل JSON حاوی اطلاعات دانشآموزان را انتخاب کنید. فایل باید شامل آرایهای از دانشآموزان با فیلدهای
+ mbti، learningStyle، ams، cooperative و preferredStudents باشد.
+
+
+
+
+
+
+
+ انتخاب فایل JSON
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ نتایج گروهبندی
+
+
+
+
+
+
+
+
+
+
+
نسخه 1.0.0 | آبان 1404
+
© ۲۰۲۵ TalimBot - سیستم گروهبندی هوشمند دانش آموزان
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/render.yaml b/render.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4cd0aa17f74410eb9103a646596855b085321737
--- /dev/null
+++ b/render.yaml
@@ -0,0 +1,7 @@
+# Render.com Deployment Configuration
+
+## Build Command:
+pip install -r backend/requirements.txt
+
+## Start Command:
+cd backend && uvicorn main:app --host 0.0.0.0 --port $PORT
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0549d5212e0b5d34cb0cd50a46451a3a4225070b
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,6 @@
+fastapi==0.104.1
+uvicorn==0.24.0
+pydantic==2.5.0
+requests==2.31.0
+python-multipart==0.0.6
+python-dotenv==1.0.0
diff --git a/resources_references/DEPLOYMENT_CHECKLIST.md b/resources_references/DEPLOYMENT_CHECKLIST.md
new file mode 100644
index 0000000000000000000000000000000000000000..beb2d3904ada7251206b2a4124d632927f395f98
--- /dev/null
+++ b/resources_references/DEPLOYMENT_CHECKLIST.md
@@ -0,0 +1,207 @@
+# ✅ Railway Deployment Checklist
+
+## Pre-Deployment Verification
+
+### ✅ Local Testing Complete
+- [x] Project restructured with `backend/static/` folder
+- [x] All frontend files copied to `backend/static/`
+- [x] `main.py` updated to serve static files
+- [x] `data.js` updated for Railway deployment
+- [x] Local server tested and working (`http://localhost:8000`)
+- [x] All pages accessible (index, login, dashboards, questionnaires)
+- [x] API endpoints working (grouping, data saving)
+
+### ✅ Git Repository Status
+- [x] `.env` file in `.gitignore` (API key NOT committed)
+- [x] All changes committed to Git
+- [x] Changes pushed to GitHub main branch
+- [x] Repository: `https://github.com/talimbot/talimbot`
+
+---
+
+## 🚂 Railway Deployment Steps
+
+### Step 1: Create Railway Account
+- [ ] Go to https://railway.app
+- [ ] Click "Start a New Project"
+- [ ] Sign in with GitHub account
+- [ ] Authorize Railway to access your repositories
+
+### Step 2: Deploy from GitHub
+- [ ] Click "Deploy from GitHub repo"
+- [ ] Select `talimbot/talimbot` repository
+- [ ] Railway auto-detects Python project
+- [ ] Deployment starts automatically
+
+### Step 3: Configure Environment Variables
+- [ ] Go to project dashboard
+- [ ] Click "Variables" tab
+- [ ] Click "+ New Variable"
+- [ ] Add variable:
+ - **Key**: `OPENROUTER_API_KEY`
+ - **Value**: `sk-or-v1-your-actual-key-here`
+- [ ] Click "Add"
+
+### Step 4: Generate Public URL
+- [ ] Go to "Settings" tab
+- [ ] Scroll to "Networking" section
+- [ ] Click "Generate Domain"
+- [ ] Copy your URL: `https://talimbot-production-xxxx.up.railway.app`
+
+### Step 5: Wait for Deployment
+- [ ] Monitor deployment in "Deployments" tab
+- [ ] Wait 2-3 minutes for build to complete
+- [ ] Look for "✅ Deployment successful" message
+
+---
+
+## 🧪 Post-Deployment Testing
+
+### Test All Features
+Visit your Railway URL and verify:
+
+#### Frontend Pages
+- [ ] Main page loads (`/`)
+- [ ] Login page works (`/pages/login.html`)
+- [ ] Student dashboard loads and functions
+- [ ] Teacher dashboard loads and functions
+- [ ] AMS questionnaire page works
+- [ ] Cooperative questionnaire page works
+- [ ] Group view page displays correctly
+
+#### Authentication & Navigation
+- [ ] Can login as student (use student number from data)
+- [ ] Can login as teacher (password: `teacher123`)
+- [ ] Navigation between pages works
+- [ ] Back buttons work correctly
+- [ ] Logout functionality works
+
+#### Student Features
+- [ ] MBTI test can be filled and saved
+- [ ] VARK test can be filled and saved
+- [ ] AMS questionnaire completes and auto-saves score
+- [ ] Cooperative questionnaire completes and auto-saves score
+- [ ] Preferred students selection works (max 4)
+- [ ] "Save All Data" button saves successfully
+- [ ] Data persists after page refresh
+- [ ] Can view assigned group
+
+#### Teacher Features
+- [ ] Can view all students in table
+- [ ] Can edit student information
+- [ ] Can add new students
+- [ ] Can delete students
+- [ ] Download data button works
+- [ ] Toggle visibility for students works
+- [ ] AI Grouping functionality works
+ - [ ] Can select course (Riazi, Faravari, etc.)
+ - [ ] Grouping completes successfully
+ - [ ] Groups are created and saved
+ - [ ] Students can see their groups
+- [ ] AMS and Cooperation columns display correctly
+
+#### API & Data Persistence
+- [ ] API calls complete without errors (check browser console)
+- [ ] Student data saves to backend
+- [ ] Data persists between sessions
+- [ ] Groups persist after creation
+- [ ] No 404 errors for API endpoints
+- [ ] No CORS errors in console
+
+---
+
+## 🔍 Troubleshooting Guide
+
+### If pages don't load:
+1. Check Railway deployment logs for errors
+2. Verify `backend/static/` folder contains all files
+3. Check browser console for 404 errors
+
+### If API calls fail:
+1. Verify environment variable `OPENROUTER_API_KEY` is set
+2. Check Railway logs for API errors
+3. Test API endpoints directly: `https://your-url.railway.app/api/students`
+
+### If grouping doesn't work:
+1. Verify OpenRouter API key is correct
+2. Check you have credits in OpenRouter account
+3. View Railway logs during grouping attempt
+4. Ensure request is reaching `/api/grouping` endpoint
+
+### If static files are missing:
+1. Verify files exist in `backend/static/` folder locally
+2. Ensure git committed and pushed all files
+3. Trigger manual redeploy in Railway
+4. Check file paths in HTML are correct (relative paths)
+
+---
+
+## 📊 Monitoring
+
+### Check Deployment Status
+- [ ] Railway dashboard shows "Active" status
+- [ ] Latest deployment timestamp is recent
+- [ ] No error messages in deployment logs
+
+### Monitor Usage
+- [ ] View usage in Railway "Usage" tab
+- [ ] Verify you're within free tier ($5/month)
+- [ ] Estimated usage: ~$2-3/month
+
+### View Logs
+- [ ] Real-time logs available in "Deployments" tab
+- [ ] Check logs for any errors or warnings
+- [ ] Monitor API request logs
+
+---
+
+## 🎯 Final Verification
+
+### Complete Success Criteria
+- [ ] Application is accessible from any device with internet
+- [ ] All features work identically to localhost version
+- [ ] No errors in browser console
+- [ ] No errors in Railway logs
+- [ ] Data persistence works correctly
+- [ ] AI grouping creates groups successfully
+- [ ] Teachers can manage students
+- [ ] Students can complete questionnaires
+
+### Share with Users
+- [ ] Copy Railway URL
+- [ ] Share URL with teacher
+- [ ] Provide login instructions:
+ - Teacher: Password is `teacher123`
+ - Students: Use their student number
+- [ ] Explain how to access from any device
+
+---
+
+## 🚀 You're Done!
+
+Once all checkboxes are checked, your TalimBot is:
+- ✅ **Fully deployed** on Railway
+- ✅ **Accessible from anywhere** via the internet
+- ✅ **Secure** (API key in environment variables)
+- ✅ **Free** (within Railway's $5/month credit)
+- ✅ **Professional** (real production website)
+
+**Your Live URL**: `https://your-project.up.railway.app`
+
+---
+
+## 📝 Next Steps
+
+1. **Bookmark your Railway dashboard** for monitoring
+2. **Keep your OpenRouter API key safe** (never share it)
+3. **Monitor Railway usage** to stay within free tier
+4. **Test from multiple devices** (phone, tablet, different computers)
+5. **Collect feedback** from teachers and students
+
+---
+
+## 🆘 Need Help?
+
+- **Railway Docs**: https://docs.railway.app
+- **Railway Discord**: https://discord.gg/railway
+- **Review**: `RAILWAY_SETUP_GUIDE.md` for detailed instructions
diff --git a/resources_references/Icons/Additional/teacherIcon.png b/resources_references/Icons/Additional/teacherIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..11ea63b048234b9661ca53b6dcd970607a768d2e
Binary files /dev/null and b/resources_references/Icons/Additional/teacherIcon.png differ
diff --git a/resources_references/Icons/Additional/teacherIcon2.jpg b/resources_references/Icons/Additional/teacherIcon2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..00ba55f45c28c016de9dd78f3a9b0c622fdb2c99
Binary files /dev/null and b/resources_references/Icons/Additional/teacherIcon2.jpg differ
diff --git a/resources_references/Icons/logo/Logo_blueBackground.jpg b/resources_references/Icons/logo/Logo_blueBackground.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e8c775a86dbb733ff780963bb10ea73e203966b6
Binary files /dev/null and b/resources_references/Icons/logo/Logo_blueBackground.jpg differ
diff --git a/resources_references/Icons/logo/Logo_noBackground.jpg b/resources_references/Icons/logo/Logo_noBackground.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..317d414f287b697d891103c98647a6c043f1c671
Binary files /dev/null and b/resources_references/Icons/logo/Logo_noBackground.jpg differ
diff --git a/resources_references/Icons/logo/logo.png b/resources_references/Icons/logo/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9dcbecafe8f1fa3138980865b9d392967f6940d
Binary files /dev/null and b/resources_references/Icons/logo/logo.png differ
diff --git a/resources_references/Icons/studentIcon.png b/resources_references/Icons/studentIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..1b3b4f96bca1bfada5b15c165a4469773a630aab
Binary files /dev/null and b/resources_references/Icons/studentIcon.png differ
diff --git a/resources_references/Icons/teacherIcon3.png b/resources_references/Icons/teacherIcon3.png
new file mode 100644
index 0000000000000000000000000000000000000000..d19f6da898b38cb3391cb2705d7c09fdfdf44bf3
Binary files /dev/null and b/resources_references/Icons/teacherIcon3.png differ
diff --git a/resources_references/RAILWAY_DEPLOYMENT.md b/resources_references/RAILWAY_DEPLOYMENT.md
new file mode 100644
index 0000000000000000000000000000000000000000..907f84e1f3eca544fded6bc6dcbe703d7a643dba
--- /dev/null
+++ b/resources_references/RAILWAY_DEPLOYMENT.md
@@ -0,0 +1,126 @@
+# 🚂 Railway Deployment Guide for TalimBot
+
+## Quick Deploy to Railway.app
+
+### Step 1: Create Railway Account
+1. Go to: **https://railway.app**
+2. Click **"Login"** → **"Login with GitHub"**
+3. Authorize Railway to access your repositories
+
+### Step 2: Deploy from GitHub
+1. Click **"New Project"**
+2. Select **"Deploy from GitHub repo"**
+3. Choose your **"talimbot"** repository
+4. Railway will automatically detect it's a Python project!
+
+### Step 3: Add Environment Variable (IMPORTANT!)
+1. In your Railway project, click on your service
+2. Go to **"Variables"** tab
+3. Click **"New Variable"**
+4. Add:
+ - **Name:** `OPENROUTER_API_KEY`
+ - **Value:** `sk-or-v1-your-actual-key-here` (get from https://openrouter.ai)
+5. Click **"Add"**
+
+### Step 4: Configure Build (if needed)
+Railway usually auto-detects, but if it doesn't:
+1. Go to **"Settings"** tab
+2. **Build Command:** `pip install -r backend/requirements.txt`
+3. **Start Command:** `cd backend && uvicorn main:app --host 0.0.0.0 --port $PORT`
+
+### Step 5: Deploy!
+1. Railway deploys automatically
+2. Wait 2-3 minutes for build to complete
+3. You'll see "Active" when ready
+
+### Step 6: Get Your URL
+1. Click **"Settings"** tab
+2. Scroll to **"Networking"**
+3. Click **"Generate Domain"**
+4. You'll get: `https://talimbot-production-xxxx.up.railway.app`
+5. **Copy this URL!**
+
+### Step 7: Update Frontend
+Edit `assets/js/data.js` line 11:
+```javascript
+return 'https://talimbot-production-xxxx.up.railway.app/api';
+```
+
+### Step 8: Push to GitHub
+```bash
+git add assets/js/data.js
+git commit -m "Configure Railway backend URL"
+git push origin main
+```
+
+### Step 9: Test!
+Visit: `https://talimbot.github.io/talimbot/`
+
+---
+
+## Environment Variables Explained
+
+### Local Development (.env file)
+```
+OPENROUTER_API_KEY=sk-or-v1-your-key-here
+```
+
+### Railway (Variables tab in dashboard)
+- **Variable Name:** OPENROUTER_API_KEY
+- **Variable Value:** sk-or-v1-your-key-here
+
+**Important:** NEVER commit your .env file to GitHub! It's already in .gitignore.
+
+---
+
+## Cost
+
+Railway offers:
+- **$5 free credit per month** (renews monthly)
+- **$0.000463 per GB-hour** of RAM
+- Usually enough for small projects like this
+- Can upgrade to Developer plan ($5/month) for more resources
+
+---
+
+## Advantages over Render
+
+✅ **No sleep** - stays online 24/7
+✅ **Faster deployments** - usually 1-2 minutes
+✅ **Better free tier** - $5 credit (vs Render's sleep after 15min)
+✅ **Auto-deploy** from GitHub on push
+✅ **Easy environment variables** - simple UI
+
+---
+
+## Troubleshooting
+
+### Build Fails
+- Check Logs tab for error messages
+- Verify `requirements.txt` has all dependencies
+- Make sure `python-dotenv` is included
+
+### "API key not configured" Error
+- Go to Variables tab
+- Verify OPENROUTER_API_KEY is set
+- Make sure there are no extra spaces
+- Redeploy after adding variable
+
+### Can't Access Backend
+- Check service is "Active" (not deploying/failed)
+- Verify you generated a domain in Settings → Networking
+- Try accessing: `https://your-url.up.railway.app/api/students`
+
+---
+
+## Next Steps
+
+After deployment:
+1. Test login from multiple devices
+2. Test grouping functionality
+3. Download JSON backup
+4. Share link with students!
+
+---
+
+**Your website is now live and independent!** 🎉
diff --git a/resources_references/RAILWAY_SETUP_GUIDE.md b/resources_references/RAILWAY_SETUP_GUIDE.md
new file mode 100644
index 0000000000000000000000000000000000000000..a9b8749df31da9d24bd80f17185ec70108a137f0
--- /dev/null
+++ b/resources_references/RAILWAY_SETUP_GUIDE.md
@@ -0,0 +1,300 @@
+# 🚂 Railway Deployment Guide for TalimBot
+
+## 📋 Overview
+This guide will help you deploy your complete TalimBot application (Frontend + Backend) to Railway for free, making it accessible from anywhere.
+
+## ✅ What We've Done (Preparation Complete!)
+
+### 1. **Restructured the Project**
+- ✅ Created `backend/static/` folder
+- ✅ Moved all frontend files (HTML, CSS, JS, Icons) to `backend/static/`
+- ✅ Updated `main.py` to serve static files
+- ✅ Updated `data.js` to use relative API paths for Railway
+
+### 2. **Updated FastAPI Configuration**
+Your `backend/main.py` now:
+- Serves static files from `backend/static/` folder
+- Uses environment variable for OpenRouter API key
+- Handles both frontend (HTML pages) and backend (API endpoints) from the same server
+- Works seamlessly on Railway's deployment platform
+
+### 3. **Project Structure**
+```
+talimbot/
+├── .env # LOCAL ONLY - Contains your API key (NEVER commit this!)
+├── .env.example # Template for environment variables
+├── .gitignore # Ensures .env is not committed
+├── Procfile # Tells Railway how to start the server
+├── runtime.txt # Specifies Python version
+├── README.md
+├── RAILWAY_DEPLOYMENT.md
+├── backend/
+│ ├── main.py # ✅ UPDATED - Serves static files + API endpoints
+│ ├── grouping_logic.py
+│ ├── requirements.txt
+│ ├── data/
+│ │ └── students.json
+│ └── static/ # ✅ NEW - All frontend files
+│ ├── index.html
+│ ├── assets/ # CSS and JS files
+│ │ ├── css/
+│ │ │ └── styles.css
+│ │ └── js/
+│ │ ├── data.js # ✅ UPDATED - Uses relative API paths
+│ │ └── grouping.js
+│ ├── pages/ # All HTML pages
+│ │ ├── login.html
+│ │ ├── student-dashboard.html
+│ │ ├── teacher-dashboard.html
+│ │ ├── ams-questionnaire.html
+│ │ ├── cooperative-questionnaire.html
+│ │ └── group-view.html
+│ └── Icons/ # Logo and icons
+```
+
+---
+
+## 🚀 Deployment Steps
+
+### **Step 1: Verify Local Setup**
+
+1. **Create `.env` file** (if you haven't already):
+ ```bash
+ # In the project root (talimbot/) folder
+ echo OPENROUTER_API_KEY=sk-or-v1-your-actual-key-here > .env
+ ```
+
+2. **Test locally**:
+ ```bash
+ cd backend
+ python main.py
+ ```
+
+3. **Open browser** to `http://localhost:8000`
+ - You should see the index.html page
+ - All pages should work (login, dashboards, questionnaires)
+ - API calls should work (grouping, data saving)
+
+---
+
+### **Step 2: Commit Changes to GitHub**
+
+⚠️ **IMPORTANT**: Make sure `.env` is in `.gitignore` (it already is!)
+
+```bash
+# From the talimbot/ directory
+git add .
+git status # Verify .env is NOT listed (should only see modified files)
+
+git commit -m "Restructure project for Railway deployment - serve frontend from backend"
+git push origin main
+```
+
+---
+
+### **Step 3: Deploy to Railway**
+
+#### A. **Sign Up / Log In**
+1. Go to [railway.app](https://railway.app)
+2. Click **"Start a New Project"**
+3. Sign in with your GitHub account
+
+#### B. **Create New Project**
+1. Click **"Deploy from GitHub repo"**
+2. Select your `talimbot` repository
+3. Railway will automatically detect it's a Python project
+
+#### C. **Configure Environment Variables**
+1. In the Railway dashboard, go to your project
+2. Click on the **"Variables"** tab
+3. Click **"+ New Variable"**
+4. Add:
+ - **Key**: `OPENROUTER_API_KEY`
+ - **Value**: `sk-or-v1-your-actual-openrouter-api-key`
+5. Click **"Add"**
+
+#### D. **Verify Deployment Settings**
+Railway auto-detects settings from your files:
+- ✅ **Build Command**: None needed (Python dependencies auto-installed)
+- ✅ **Start Command**: From `Procfile` → `cd backend && uvicorn main:app --host 0.0.0.0 --port $PORT`
+- ✅ **Python Version**: From `runtime.txt` → `python-3.11.0`
+
+#### E. **Deploy!**
+1. Click **"Deploy"**
+2. Wait 2-3 minutes for deployment
+3. Railway will show deployment logs
+4. When complete, you'll see: ✅ **"Deployment successful"**
+
+#### F. **Get Your URL**
+1. In Railway dashboard, click **"Settings"** tab
+2. Scroll to **"Networking"** section
+3. Click **"Generate Domain"**
+4. Copy your URL (e.g., `https://talimbot-production-abc123.up.railway.app`)
+
+---
+
+### **Step 4: Test Your Deployed Application**
+
+1. **Open your Railway URL** in a browser
+2. **Test all features**:
+ - ✅ Main page loads (`index.html`)
+ - ✅ Login page works (`/pages/login.html`)
+ - ✅ Student dashboard loads
+ - ✅ Teacher dashboard loads
+ - ✅ Questionnaires work (AMS, Cooperative)
+ - ✅ Grouping functionality works
+ - ✅ Data saves correctly
+
+---
+
+## 🔧 How It Works
+
+### **Single Server Architecture**
+Railway runs ONE server that handles BOTH:
+
+1. **Frontend (Static Files)**:
+ - `GET /` → Serves `index.html`
+ - `GET /pages/login.html` → Serves login page
+ - `GET /assets/css/styles.css` → Serves CSS
+ - `GET /assets/js/data.js` → Serves JavaScript
+
+2. **Backend (API Endpoints)**:
+ - `POST /api/grouping` → AI grouping logic
+ - `GET /api/students` → Get all students
+ - `PUT /api/students/{id}` → Update student
+ - All other API routes in `main.py`
+
+### **How Requests Are Routed**
+
+```
+User Browser → Railway URL
+ ↓
+ FastAPI Server (main.py)
+ ↓
+ ┌─────────┴─────────┐
+ ↓ ↓
+ /api/* Everything else
+(API Endpoints) (Static Files)
+ ↓ ↓
+grouping_logic.py backend/static/
+OpenRouter API (HTML/CSS/JS)
+```
+
+### **Environment Variable Flow**
+
+```
+Local Development:
+.env file → load_dotenv() → os.getenv("OPENROUTER_API_KEY")
+
+Railway Production:
+Railway Variables → os.getenv("OPENROUTER_API_KEY")
+```
+
+---
+
+## 📊 Monitoring & Management
+
+### **View Logs**
+1. Go to Railway dashboard
+2. Click on your project
+3. Click **"Deployments"** tab
+4. Click on the latest deployment
+5. View real-time logs
+
+### **Check Usage**
+- Railway free tier: **$5 credit/month**
+- Your app should use: **~$2-3/month**
+- Monitor usage in **"Usage"** tab
+
+### **Redeploy (After Code Changes)**
+1. Make changes locally
+2. Test locally (`python main.py`)
+3. Commit and push to GitHub:
+ ```bash
+ git add .
+ git commit -m "Your changes"
+ git push origin main
+ ```
+4. Railway **auto-deploys** within 1-2 minutes!
+
+---
+
+## 🆘 Troubleshooting
+
+### **Problem: API calls fail (404 errors)**
+**Solution**: API routes must start with `/api/`
+- ✅ Correct: `POST /api/grouping`
+- ❌ Wrong: `POST /grouping`
+
+### **Problem: Static files not loading (CSS/JS missing)**
+**Solution**:
+1. Verify files are in `backend/static/` folder
+2. Check browser console for 404 errors
+3. Ensure paths in HTML are relative (e.g., `/assets/css/styles.css`)
+
+### **Problem: OpenRouter API errors**
+**Solution**:
+1. Verify API key is correct in Railway Variables
+2. Check you have credits in your OpenRouter account
+3. View logs in Railway to see exact error message
+
+### **Problem: Server won't start**
+**Solution**:
+1. Check Railway logs for error messages
+2. Verify `requirements.txt` has all dependencies
+3. Ensure `Procfile` command is correct
+
+---
+
+## 🎯 Success Checklist
+
+After deployment, verify:
+
+- [ ] Railway URL loads the main page
+- [ ] All navigation links work
+- [ ] Login system works (student/teacher)
+- [ ] Student dashboard loads
+- [ ] Teacher dashboard loads
+- [ ] AMS questionnaire works and saves
+- [ ] Cooperative questionnaire works and saves
+- [ ] AI grouping creates groups successfully
+- [ ] Student data persists after refresh
+- [ ] API calls complete without errors
+- [ ] No console errors in browser DevTools
+
+---
+
+## 💡 Next Steps
+
+Once deployed successfully:
+
+1. **Share the Railway URL** with your teacher
+2. **Test from different devices** (phone, tablet)
+3. **Monitor Railway dashboard** for any errors
+4. **Keep your OpenRouter API key secure**
+5. **Consider upgrading Railway plan** if you exceed free tier
+
+---
+
+## 📞 Support Resources
+
+- **Railway Docs**: https://docs.railway.app
+- **OpenRouter Docs**: https://openrouter.ai/docs
+- **FastAPI Docs**: https://fastapi.tiangolo.com
+- **Your Deployment Guide**: `RAILWAY_DEPLOYMENT.md`
+
+---
+
+## 🎉 Congratulations!
+
+Your TalimBot is now a **real, independent website** accessible from anywhere! 🚀
+
+**Your app URL**: `https://your-project.up.railway.app`
+
+Teachers and students can access it from:
+- ✅ Home computers
+- ✅ School computers
+- ✅ Phones (any device with internet)
+- ✅ Tablets
+
+No need for localhost, no need for running Python locally - it's fully online! 🌐
diff --git a/resources_references/README.md b/resources_references/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..35b35181c2d2d1696288d6892360034594c4124d
--- /dev/null
+++ b/resources_references/README.md
@@ -0,0 +1,407 @@
+# TalimBot - سیستم گروهبندی هوشمند دانشآموزان
+
+A full-stack intelligent student grouping system using AI-powered analysis with FastAPI backend and GitHub Pages frontend.
+
+## 🎯 Overview
+
+TalimBot groups 30 real students based on MBTI personality types, learning styles, math grades, and peer preferences using AI (GPT-4o-mini via OpenRouter). Teachers control when students can view their group assignments.
+
+### Real Student Data
+- **30 Students** from class 1061 (دهم تجربی)
+- **Persian Names**: Full Persian names from actual class roster
+- **National Code Authentication**: Students login with their national ID
+- **Math Grades**: Real grades from student records
+
+---
+
+## 🚀 Quick Start (Local Development)
+
+### Prerequisites
+- Python 3.8+ installed
+- Modern web browser
+- Internet connection (for AI grouping)
+
+### Step 1: Start Backend (30 seconds)
+
+```powershell
+# Navigate to backend folder
+cd backend
+
+# Install dependencies (first time only)
+pip install -r requirements.txt
+
+# Start the server
+python main.py
+```
+
+**Server runs on:** `http://localhost:8000`
+
+**Keep this terminal running!**
+
+### Step 2: Open Frontend (10 seconds)
+
+**Option A - Direct Open (Easiest):**
+- Double-click `index.html` in File Explorer
+
+**Option B - Local Server (Recommended):**
+```powershell
+# In a NEW terminal window
+python -m http.server 3000
+```
+Then visit: `http://localhost:3000`
+
+---
+
+## 👥 Login Credentials
+
+### Students (30 students available)
+Login with:
+- **Student Number:** S001, S002, ..., S030
+- **National Code:** Each student's 10-digit national ID
+
+**Example:**
+- Student Number: `S001`
+- National Code: `929986644`
+- Name: آدینه پور - یاسمن
+
+### Teacher
+- **Password:** `teacher123`
+
+---
+
+## 📋 How It Works
+
+### For Students:
+
+1. **Login**
+ - Enter student number (S001-S030)
+ - Enter your 10-digit national code
+ - System displays your Persian name
+
+2. **Complete Profile**
+ - Take MBTI test (link provided)
+ - Take VARK learning style test (link provided)
+ - Fill out AMS and Cooperative preferences
+ - Select up to 4 preferred groupmates
+ - Save your information
+
+3. **View Group** (after teacher enables)
+ - See your group number
+ - View all group members
+ - Read AI reasoning in Persian
+
+### For Teachers:
+
+1. **Monitor Progress**
+ - View dashboard with statistics
+ - See which students completed profiles
+ - Check readiness for grouping
+
+2. **Perform Grouping**
+ - Enter course name
+ - Click "Start Grouping"
+ - AI analyzes all data (10-30 seconds)
+ - Review generated groups with Persian reasoning
+
+3. **Control Visibility**
+ - Groups are hidden by default
+ - Click "Show Results to Students"
+ - Toggle visibility on/off anytime
+
+4. **Manage Data**
+ - View all student information
+ - Edit student data if needed
+ - Reset grouping when necessary
+
+---
+
+## 🌐 Deployment to GitHub Pages
+
+### Part 1: Deploy Frontend to GitHub Pages
+
+1. **Create GitHub Repository**
+ ```bash
+ # Initialize git (if not already done)
+ git init
+ git add .
+ git commit -m "Initial commit with real student data"
+
+ # Create repo on GitHub and push
+ git remote add origin https://github.com/talimbot/talimbot.git
+ git branch -M main
+ git push -u origin main
+ ```
+
+2. **Enable GitHub Pages**
+ - Go to repository Settings → Pages
+ - Source: Deploy from branch `main`
+ - Folder: `/ (root)`
+ - Click Save
+
+3. **Your site will be live at:**
+ `https://talimbot.github.io/talimbot/`
+
+### Part 2: Deploy Backend to Render.com (Free)
+
+1. **Create Render Account**
+ - Visit [render.com](https://render.com)
+ - Sign up with GitHub
+
+2. **Create New Web Service**
+ - Click "New +" → "Web Service"
+ - Connect your GitHub repository
+ - Settings:
+ - **Name:** `talimbot-backend`
+ - **Environment:** `Python 3`
+ - **Build Command:** `pip install -r backend/requirements.txt`
+ - **Start Command:** `cd backend && uvicorn main:app --host 0.0.0.0 --port $PORT`
+ - **Plan:** Free
+
+3. **Add Environment Variable**
+ - In Render dashboard → Environment
+ - Add: `OPENROUTER_API_KEY` = `your-api-key`
+ - Optionally: `TEACHER_PASSWORD` = `your-password`
+
+4. **Get Your Backend URL**
+ - Copy the URL (e.g., `https://talimbot-backend.onrender.com`)
+
+### Part 3: Update Frontend to Use Deployed Backend
+
+Update `API_BASE_URL` in BOTH files:
+- `assets/js/data.js`
+- `assets/js/grouping.js`
+
+```javascript
+// Change from:
+const API_BASE_URL = 'http://localhost:8000/api';
+
+// To:
+const API_BASE_URL = 'https://talimbot-backend.onrender.com/api';
+```
+
+Commit and push changes:
+```bash
+git add .
+git commit -m "Update API URL for production"
+git push
+```
+
+GitHub Pages will auto-deploy in ~1 minute.
+
+---
+
+## 🔧 Configuration
+
+### API Key (OpenRouter)
+Located in `backend/grouping_logic.py`:
+```python
+OPENROUTER_API_KEY = 'sk-or-v1-...'
+```
+
+### Teacher Password
+Located in `backend/main.py` (SystemData model):
+```python
+teacherPassword: str = "teacher123"
+```
+
+Change as needed for security.
+
+### Student Data
+Students are initialized in `backend/main.py` in the `load_data()` function.
+All 30 real students with Persian names and national codes are pre-loaded.
+
+---
+
+## 📁 Project Structure
+
+```
+talimbot/
+├── backend/
+│ ├── main.py # FastAPI server with real student data
+│ ├── grouping_logic.py # AI grouping with OpenRouter
+│ ├── requirements.txt # Python dependencies
+│ ├── README.md # Backend documentation
+│ └── data/
+│ └── students.json # Auto-created data storage
+│
+├── assets/
+│ ├── css/
+│ │ └── styles.css
+│ └── js/
+│ ├── data.js # API client for student data
+│ └── grouping.js # API client for grouping
+│
+├── pages/
+│ ├── login.html # Login with national code
+│ ├── student-dashboard.html
+│ ├── student-data.html
+│ ├── teacher-dashboard.html
+│ └── group-view.html
+│
+├── Icons/ # UI icons
+├── index.html # Redirects to login
+├── README.md # This file
+├── .gitignore # Git ignore rules
+└── start-backend.ps1 # Windows startup script
+```
+
+---
+
+## 🎯 Features
+
+### ✅ Implemented
+- **Real Student Data**: 30 actual students with Persian names
+- **National Code Authentication**: Secure login using national IDs
+- **Persistent Storage**: JSON database on backend
+- **AI-Powered Grouping**: OpenRouter GPT-4o-mini integration
+- **Persian Language**: Full RTL support with Persian reasoning
+- **Teacher Controls**: Show/hide results, reset grouping
+- **Math Grades**: Real grades from class records
+- **MBTI & Learning Styles**: Comprehensive personality analysis
+- **Peer Preferences**: Students select preferred groupmates
+
+### 🎨 UI Features
+- Modern, responsive design with Tailwind CSS
+- Persian (RTL) interface
+- Real-time validation
+- Progress indicators
+
+---
+
+## 🐛 Troubleshooting
+
+### "Failed to fetch" errors
+**Problem:** Backend not running or wrong URL
+**Solution:**
+1. Check backend is running: Visit `http://localhost:8000`
+2. Should see: `{"message":"TalimBot API is running"}`
+3. Check `API_BASE_URL` in JS files matches backend
+
+### Students can't login
+**Problem:** Wrong national code
+**Solution:**
+- National code must be exactly 10 digits
+- Must match the code in backend database
+- Check `backend/main.py` for correct codes
+
+### Students can't see groups
+**Problem:** Teacher hasn't enabled visibility
+**Solution:**
+- Teacher must click "Show Results to Students"
+- Button appears after grouping is complete
+
+### Grouping fails
+**Problem:** API error or no internet
+**Solution:**
+1. Check internet connection
+2. Verify OpenRouter API key is valid
+3. Check backend logs for errors
+4. System has fallback random grouping if AI fails
+
+---
+
+## 📊 Student List (Sample)
+
+| # | Student Number | Name | National Code | Math Grade |
+|---|----------------|------|---------------|------------|
+| 1 | S001 | آدینه پور - یاسمن | 929986644 | 16.0 |
+| 2 | S002 | احمدزاده - پریا | 980085330 | 12.0 |
+| 3 | S003 | اکبرزاده - فاطمه | 970154550 | 11.0 |
+| 4 | S004 | الهی مهر - آناهیتا | 26425955 | 17.0 |
+| 5 | S005 | امیری - مریم | 980093341 | 18.0 |
+| ... | ... | ... | ... | ... |
+| 30 | S030 | وحدتی - باران | 929916913 | 12.0 |
+
+*Full list available in `backend/main.py`*
+
+---
+
+## 🔐 Security Notes
+
+### Current (Demo/Development):
+- ✅ Simple password authentication
+- ✅ CORS allows all origins
+- ✅ National codes as passwords
+
+### Recommended for Production:
+- 🔒 Use environment variables for secrets
+- 🔒 Implement JWT token authentication
+- 🔒 Enable HTTPS only
+- 🔒 Add rate limiting
+- 🔒 Use PostgreSQL instead of JSON
+- 🔒 Hash national codes
+- 🔒 Implement proper session management
+
+---
+
+## 📞 API Endpoints
+
+| Endpoint | Method | Description |
+|----------|--------|-------------|
+| `/` | GET | Health check |
+| `/api/students` | GET | Get all students |
+| `/api/student/{id}` | GET | Get one student |
+| `/api/student/{id}` | PUT | Update student |
+| `/api/auth/student` | POST | Authenticate student |
+| `/api/auth/teacher` | POST | Authenticate teacher |
+| `/api/grouping/perform` | POST | Run AI grouping |
+| `/api/grouping/status` | GET | Get stats |
+| `/api/grouping/toggle-visibility` | POST | Show/hide results |
+| `/api/grouping/reset` | POST | Clear grouping |
+| `/api/student/{id}/group` | GET | Get student's group |
+
+---
+
+## 🎓 Technologies Used
+
+### Backend
+- **FastAPI** - Modern Python web framework
+- **Uvicorn** - ASGI server
+- **Pydantic** - Data validation
+- **aiohttp** - Async HTTP client
+- **OpenRouter API** - AI integration
+
+### Frontend
+- **HTML5 / CSS3** - Structure and styling
+- **Tailwind CSS** - Utility-first CSS
+- **JavaScript (Async/Await)** - Modern JS
+- **Fetch API** - HTTP requests
+
+### Deployment
+- **GitHub Pages** - Frontend hosting (free)
+- **Render.com** - Backend hosting (free)
+
+---
+
+## 📝 License
+
+This project is for educational purposes.
+
+---
+
+## 🙏 Credits
+
+- Student data from class 1061 (دهم تجربی)
+- AI grouping powered by OpenRouter (GPT-4o-mini)
+
+---
+
+## ✅ Pre-Launch Checklist
+
+- [ ] Backend running locally
+- [ ] Students can login with national codes
+- [ ] Teacher can login with password
+- [ ] Grouping works with AI
+- [ ] Visibility toggle works
+- [ ] All 30 students load correctly
+- [ ] Persian names display properly
+- [ ] Math grades show correctly
+- [ ] Backend deployed to Render
+- [ ] Frontend deployed to GitHub Pages
+- [ ] API URLs updated for production
+
+---
+
+**Live URL:** `https://talimbot.github.io/talimbot/pages/login.html`
+
+**Last Updated:** December 2025
diff --git a/resources_references/TEST_RESULTS_AND_SOLUTION.md b/resources_references/TEST_RESULTS_AND_SOLUTION.md
new file mode 100644
index 0000000000000000000000000000000000000000..486637eb8f2d10c6d1273878203a293979ec2e78
--- /dev/null
+++ b/resources_references/TEST_RESULTS_AND_SOLUTION.md
@@ -0,0 +1,225 @@
+# ✅ SERVER ISSUE - FULLY DIAGNOSED & READY TO FIX
+
+## 🎯 Test Results (Just Ran)
+
+✅ **Server Status:** Running on port 8000
+✅ **API Response:** Returns data successfully
+✅ **Firewall Rules:** Properly configured for Python
+✅ **Local Network:** Server IS accessible from 192.168.114.1
+✅ **Deployment Files:** All created and ready
+
+---
+
+## 🔍 Problem Diagnosis
+
+**Why GitHub Pages doesn't work:**
+```
+https://talimbot.github.io/talimbot/
+ ↓ tries to connect to
+http://localhost:8000 ← This doesn't exist on the internet!
+```
+
+**Why phone doesn't work:**
+Your phone tries to connect to "localhost" which means "this phone" not "your laptop"
+
+---
+
+## 🎯 TWO SOLUTIONS - Choose One
+
+### 📱 Solution A: Test on Phone NOW (Temporary)
+
+Your server **IS** accessible from local network!
+
+**On Your Phone:**
+1. Connect to **same Wi-Fi** as laptop
+2. Open browser and visit:
+ ```
+ http://192.168.114.1:8000/index.html
+ ```
+ Or just test API:
+ ```
+ http://192.168.114.1:8000/api/students
+ ```
+
+3. Should work! ✅
+
+**To make GitHub Pages work with your laptop server:**
+1. Edit `assets/js/data.js`
+2. Change:
+ ```javascript
+ const API_BASE_URL = 'http://localhost:8000/api';
+ ```
+ To:
+ ```javascript
+ const API_BASE_URL = 'http://192.168.114.1:8000/api';
+ ```
+3. Push to GitHub
+4. Now GitHub Pages will try to connect to your laptop
+5. **Only works when laptop is on and server is running!**
+
+⚠️ **Limitations:**
+- Only works on your Wi-Fi network
+- Laptop must be on with server running
+- If laptop IP changes, you need to update code
+- Not suitable for real deployment
+
+---
+
+### 🌐 Solution B: Deploy to Cloud (PERMANENT) ⭐ RECOMMENDED
+
+Make your backend accessible from anywhere!
+
+**5-Minute Render.com Deployment:**
+
+1. **Sign up:** https://render.com (use GitHub login)
+
+2. **New Web Service:**
+ - Click "New +" → "Web Service"
+ - Connect your `talimbot` repository
+ - Select the repo
+
+3. **Configure:**
+ ```
+ Name: talimbot-api
+ Build Command: pip install -r backend/requirements.txt
+ Start Command: cd backend && uvicorn main:app --host 0.0.0.0 --port $PORT
+ Instance Type: Free
+ ```
+
+4. **Deploy:** Click "Create Web Service"
+
+5. **Get URL:** Copy your URL (e.g., `https://talimbot-api.onrender.com`)
+
+6. **Update Frontend:**
+ Edit `assets/js/data.js`:
+ ```javascript
+ const API_BASE_URL = 'https://talimbot-api.onrender.com/api';
+ ```
+
+7. **Push to GitHub:**
+ ```bash
+ git add .
+ git commit -m "Update API URL for production"
+ git push
+ ```
+
+8. **Done!** Your site works from anywhere! 🎉
+
+✅ **Benefits:**
+- Works from anywhere in the world
+- Works on any device
+- No laptop needed
+- Professional setup
+- FREE tier available
+
+---
+
+## 📋 Files I Created for You
+
+| File | Purpose |
+|------|---------|
+| `DEPLOYMENT_GUIDE.md` | Complete deployment tutorial (Render/Railway/PythonAnywhere) |
+| `FIXING_SERVER_ERROR.md` | Troubleshooting guide |
+| `Procfile` | Tells Render how to start server |
+| `runtime.txt` | Specifies Python version |
+| `render.yaml` | Render configuration |
+| `setup-firewall.ps1` | Windows firewall setup (if needed) |
+| `THIS FILE` | Summary of everything |
+
+---
+
+## 🚀 WHAT TO DO NOW
+
+### For Quick Test (Next 5 Minutes):
+1. **On phone**, visit: `http://192.168.114.1:8000/api/students`
+2. Should see JSON data ✅
+3. This proves your server works!
+
+### For Real Deployment (Next 15 Minutes):
+1. **Go to:** https://render.com
+2. **Follow steps** in Solution B above
+3. **Read full guide:** `DEPLOYMENT_GUIDE.md`
+4. **Update code** with Render URL
+5. **Push to GitHub**
+6. **Your app works worldwide!** 🌍
+
+---
+
+## 📊 Current vs After Deployment
+
+**Current (localhost):**
+```
+✅ Laptop browser → Works
+❌ Phone → Doesn't work
+❌ GitHub Pages → Doesn't work
+❌ Other people → Can't access
+```
+
+**After Deployment:**
+```
+✅ Laptop browser → Works
+✅ Phone → Works
+✅ GitHub Pages → Works
+✅ Other people → Can access
+✅ From anywhere → Works
+```
+
+---
+
+## 💡 Quick Comparison
+
+| Method | Time | Cost | Works Everywhere | Reliable |
+|--------|------|------|------------------|----------|
+| **Localhost** | 0 min | Free | ❌ No | - |
+| **Local IP (192.168.x.x)** | 0 min | Free | ❌ Wi-Fi only | ❌ |
+| **Render.com** | 5 min | Free | ✅ Yes | ✅ |
+| **Railway.app** | 5 min | $5 credit | ✅ Yes | ✅ |
+| **PythonAnywhere** | 15 min | Free | ✅ Yes | ✅ |
+
+**Recommendation:** Render.com (easiest, fastest, free)
+
+---
+
+## 🎓 What You Learned
+
+1. **localhost = your computer only** (not accessible from internet)
+2. **192.168.x.x = local network only** (same Wi-Fi)
+3. **https://your-app.onrender.com = anywhere** (real internet URL)
+4. **GitHub Pages = frontend only** (needs backend somewhere else)
+5. **Backend must be deployed separately** from frontend
+
+---
+
+## ❓ Common Questions
+
+**Q: Can't I just use localhost?**
+A: No, localhost doesn't exist on the internet.
+
+**Q: Why does it work on my laptop?**
+A: Your laptop's browser can reach localhost because the server is running ON your laptop.
+
+**Q: Will phone work if I deploy?**
+A: Yes! After deployment, phone/laptop/anyone can access it.
+
+**Q: Is Render really free?**
+A: Yes, free tier available. Service sleeps after 15 min inactivity (wakes up in 30s on first request).
+
+**Q: What if Render is too slow?**
+A: Try Railway ($5 free credit) or upgrade Render later.
+
+---
+
+## 🎯 Bottom Line
+
+**Your server works perfectly!** ✅
+It's just not on the internet yet.
+
+**Two choices:**
+1. Quick test on phone: Use `http://192.168.114.1:8000` (same Wi-Fi)
+2. Real deployment: Deploy to Render (5 minutes, works everywhere)
+
+**I recommend:** Deploy to Render - then your project is truly online! 🚀
+
+---
+
+**All files are ready. All tests passed. Ready to deploy!** ✅
diff --git a/resources_references/angizesh_tahsili.txt b/resources_references/angizesh_tahsili.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cb97f9b7b3f92510e5fc5537c8198ddafcb66817
--- /dev/null
+++ b/resources_references/angizesh_tahsili.txt
@@ -0,0 +1,67 @@
+پرسشنامه انگیزش تحصیلی (نسخه محققساخته همساخت با AMS – مناسب دانشآموزان)
+۲۸ گویه – ۷ زیرمقیاس – مقیاس ۷ گزینهای
+راهنمای پاسخدهی
+لطفاً مشخص کنید هر جمله تا چه حد درباره شما درست است:
+1. اصلاً درست نیست
+2. خیلی کم درست است
+3. کمی درست است
+4. تا حدی درست است
+5. نسبتاً درست است
+6. خیلی درست است
+7. کاملاً درست است
+________________________________________
+A) بیانگیزشی (Amotivation)
+1. گاهی نمیدانم چرا باید برای درس خواندن تلاش کنم.
+2. احساس میکنم درس خواندن برایم فایدهای ندارد.
+3. بعضی وقتها فکر میکنم ادامه دادن درس هیچ هدف مشخصی برایم ندارد.
+4. وقتی درس میخوانم، نمیدانم برای چه چیزی زحمت میکشم.
+________________________________________
+B) انگیزش بیرونی – تنظیم بیرونی (External Regulation)
+5. برای اینکه والدین یا معلمانم از من ناراحت نشوند، درس میخوانم.
+6. بیشتر برای گرفتن نمره خوب تلاش میکنم، نه چیز دیگر.
+7. درس میخوانم چون از پیامدهای منفی نمره پایین میترسم.
+8. پیشرفت تحصیلیام برایم مهم است چون دیگران از من انتظار دارند.
+________________________________________
+C) انگیزش بیرونی – درونفکنیشده (Introjected Regulation)
+9. وقتی درس نمیخوانم احساس گناه میکنم.
+10. درس خواندن باعث میشود حس بهتری نسبت به خودم داشته باشم.
+11. اگر برای امتحان آماده نباشم، از خودم ناراحت میشوم.
+12. بعضی وقتها برای اینکه احساس ارزشمندی کنم، بیشتر درس میخوانم.
+________________________________________
+D) انگیزش بیرونی – همانندسازیشده (Identified Regulation)
+13. درس خواندن برایم مهم است چون میدانم در آینده به من کمک میکند.
+14. یادگیری مطالب مدرسه را ارزشمند میدانم.
+15. موفقیت در درس را بخشی از پیشرفت شخصی خودم میدانم.
+16. برای این درس میخوانم که به هدفهای آیندهام نزدیکتر شوم.
+________________________________________
+E) انگیزش درونی برای کسب دانش (Intrinsic – To Know)
+17. از یادگرفتن مطالب جدید لذت میبرم.
+18. وقتی چیزی را واقعاً یاد میگیرم، احساس رضایت میکنم.
+19. فهمیدن موضوعات سخت برایم هیجانانگیز است.
+20. دوست دارم درباره درسها بیشتر بدانم، حتی خارج از کلاس.
+________________________________________
+F) انگیزش درونی برای کسب موفقیت (Intrinsic – Toward Accomplishment)
+21. حل کردن یک مسئله سخت به من حس موفقیت میدهد.
+22. وقتی یک تکلیف را عالی انجام میدهم، احساس افتخار میکنم.
+23. دوست دارم در درسها عملکردی بالاتر از حد معمول داشته باشم.
+24. تلاش میکنم چون میخواهم تواناییهایم را نشان بدهم.
+________________________________________
+G) انگیزش درونی برای تجربه تحریک/هیجان (Intrinsic – Stimulation)
+25. بعضی درسها برایم هیجانانگیز و جذاب هستند.
+26. یادگیری برایم لذتبخش است، حتی وقتی سخت باشد.
+27. وقتی در فعالیتهای آموزشی مشارکت میکنم، احساس انرژی و شادی میکنم.
+28. تجربه کردن روشهای جدید یادگیری برایم جالب و هیجانآور است.
+________________________________________
+نمرهگذاری
+• هر سؤال از ۱ تا ۷ نمره دارد.
+• نمره هر زیرمقیاس = مجموع ۴ گویه آن (دامنه: ۴ تا ۲۸).
+• نمرهگذاری
+• هر یک از ۷ زیرمقیاس شامل ۴ سؤال است.
+• • بیانگیزشی = میانگین/جمع سؤالات 1–4
+• • تنظیم بیرونی = سؤالات 5–8
+• • درونفکنی شده = 9–12
+• • همانندسازی شده = 13–16
+• • انگیزش درونی برای دانستن = 17–20
+• • انگیزش درونی برای موفقیت = 21–24
+• • انگیزش درونی برای تحریک/هیجان = 25–28
+
diff --git a/resources_references/cooperative.txt b/resources_references/cooperative.txt
new file mode 100644
index 0000000000000000000000000000000000000000..27b15365feea47e8999b4baad9e74f05dd5a6054
--- /dev/null
+++ b/resources_references/cooperative.txt
@@ -0,0 +1,64 @@
+پرسشنامه یادگیری مشارکتی (بر اساس مدل جانسون و جانسون، ۱۹۹۴)
+مناسب برای دانشجویان / دانشآموزان / معلمان
+نسخه فارسی – محققساخته مبتنی بر مدل پنجعنصری
+مقیاس پاسخدهی
+لطفاً میزان موافقت خود را با هر جمله مشخص کنید:
+1. کاملاً مخالفم
+2. مخالفم
+3. نظری ندارم
+4. موافقم
+5. کاملاً موافقم
+________________________________________
+بخش اول: وابستگی متقابل مثبت
+(Positive Interdependence)
+1. موفقیت من در فعالیتهای این درس به همکاری اعضای گروه بستگی دارد.
+2. اگر یکی از اعضای گروه کار خود را انجام ندهد، عملکرد کل گروه تحت تأثیر قرار میگیرد.
+3. اعضای گروه برای رسیدن به هدف مشترک احساس مسئولیت مشترک دارند.
+4. در فعالیتهای گروهی، پیشرفت هر عضو به پیشرفت گروه کمک میکند.
+5. هدفهای گروه طوری طراحی شدهاند که بدون همکاری، دستیابی به آنها دشوار است.
+________________________________________
+بخش دوم: پاسخگویی فردی
+(Individual Accountability)
+6. هر عضو گروه مسئول بخش مشخصی از کار است.
+7. عملکرد من در گروه بهطور جداگانه نیز مورد ارزیابی قرار میگیرد.
+8. من باید وظیفه خودم را بهخوبی انجام دهم تا گروه موفق شود.
+9. همه اعضا میدانند که سهم هر فرد چه تأثیری بر نتیجه نهایی دارد.
+10. هر فرد در گروه باید بتواند بخش مربوط به خود را توضیح دهد.
+________________________________________
+بخش سوم: تعامل چهرهبهچهره / ارتقای متقابل
+(Face-to-Face Promotive Interaction)
+11. اعضای گروه در کلاس بهطور مستقیم با یکدیگر گفتوگو میکنند.
+12. هنگام انجام فعالیتهای گروهی، اعضا به یکدیگر کمک میکنند تا بهتر یاد بگیرند.
+13. در گروه، توضیح دادن مطالب به یکدیگر امری معمول است.
+14. اعضای گروه به یکدیگر بازخورد سازنده میدهند.
+15. در فعالیتهای گروهی، فرصت کافی برای تبادل نظر وجود دارد.
+________________________________________
+بخش چهارم: مهارتهای اجتماعی
+(Social Skills)
+16. اعضای گروه با احترام به نوبت یکدیگر صحبت میکنند.
+17. اعضا برای حل اختلافها از گفتوگو و مذاکره استفاده میکنند.
+18. اعضای گروه به یکدیگر گوش میدهند و صحبتهای همگروهیها را قطع نمیکنند.
+19. مدیریت زمان و تقسیم وظایف به شکل مؤثر انجام میشود.
+20. اعضای گروه در تعاملات خود ادب و احترام را رعایت میکنند.
+________________________________________
+بخش پنجم: پردازش گروهی / بازاندیشی در عملکرد گروه
+(Group Processing)
+21. در پایان فعالیتها، گروه درباره نقاط قوت خود بحث میکند.
+22. گروه بهطور منظم درباره اینکه چگونه میتوانند همکاری بهتری داشته باشند، بازاندیشی میکند.
+23. اعضا درباره مشکلات گروه و راهحلهای ممکن با هم صحبت میکنند.
+24. گروه پس از هر فعالیت، ارزیابی کوتاهی از نحوه عملکرد خود انجام میدهد.
+25. اعضای گروه در مورد بهبود عملکرد آینده تصمیمگیری مشترک میکنند.
+________________________________________
+نحوه نمرهگذاری
+• مقیاس: 1 تا 5(نمره بالاتر = سطح بالاتر یادگیری مشارکتی)
+نمره هر زیرمقیاس
+• هر مؤلفه = مجموع نمرات ۵ گویه
+• دامنه نمره هر زیرمقیاس: ۵ تا ۲۵
+نمره کل یادگیری مشارکتی
+• مجموع گویهها
+• دامنه: ۲۵ تا ۱۲۵
+تفسیر پیشنهادی نمره کل
+• ۲۵–۵۰: یادگیری مشارکتی کم
+• ۵۱–۸۸: یادگیری مشارکتی متوسط
+• ۸۹–۱۲۵: یادگیری مشارکتی زیاد
+
diff --git a/resources_references/sample-student-data.json b/resources_references/sample-student-data.json
new file mode 100644
index 0000000000000000000000000000000000000000..9a49c4c57d6c45981c0d216cee3789342c2136d8
--- /dev/null
+++ b/resources_references/sample-student-data.json
@@ -0,0 +1,26 @@
+[
+ {
+ "studentNumber": "S001",
+ "mbti": "INTJ",
+ "learningStyle": "Visual",
+ "ams": "150",
+ "cooperative": "95",
+ "preferredStudents": ["S002", "S003"]
+ },
+ {
+ "studentNumber": "S002",
+ "mbti": "ENFP",
+ "learningStyle": "Aural",
+ "ams": "130",
+ "cooperative": "110",
+ "preferredStudents": ["S001", "S004", "S005"]
+ },
+ {
+ "studentNumber": "S003",
+ "mbti": "ISFJ",
+ "learningStyle": "Read/Write",
+ "ams": "165",
+ "cooperative": "88",
+ "preferredStudents": ["S001", "S002"]
+ }
+]
diff --git a/resources_references/setup-firewall.ps1 b/resources_references/setup-firewall.ps1
new file mode 100644
index 0000000000000000000000000000000000000000..d49c209f936797d74d4c12c562d2b1b0a4b4e956
--- /dev/null
+++ b/resources_references/setup-firewall.ps1
@@ -0,0 +1,43 @@
+# 🔥 Allow Backend Server Through Firewall (Windows)
+
+# This script allows Python to accept connections from your local network
+# Run this in PowerShell as Administrator
+
+Write-Host "Checking firewall rules for Python..." -ForegroundColor Cyan
+
+# Find Python executable
+$pythonPath = (Get-Command python).Source
+
+Write-Host "Python location: $pythonPath" -ForegroundColor Yellow
+
+# Create firewall rule
+$ruleName = "TalimBot Backend Server"
+
+# Check if rule already exists
+$existingRule = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
+
+if ($existingRule) {
+ Write-Host "Firewall rule already exists. Removing old rule..." -ForegroundColor Yellow
+ Remove-NetFirewallRule -DisplayName $ruleName
+}
+
+# Create new rule
+Write-Host "Creating firewall rule to allow Python server..." -ForegroundColor Cyan
+
+New-NetFirewallRule -DisplayName $ruleName `
+ -Direction Inbound `
+ -Program $pythonPath `
+ -Action Allow `
+ -Protocol TCP `
+ -LocalPort 8000 `
+ -Profile Any `
+ -Description "Allows TalimBot backend server to accept connections on port 8000"
+
+Write-Host "✅ Firewall rule created successfully!" -ForegroundColor Green
+Write-Host ""
+Write-Host "Now your server at http://192.168.114.1:8000 should be accessible from your phone!" -ForegroundColor Green
+Write-Host ""
+Write-Host "Next steps:" -ForegroundColor Cyan
+Write-Host "1. Make sure your laptop and phone are on the same Wi-Fi"
+Write-Host "2. Server must be running: python main.py"
+Write-Host "3. On phone, visit: http://192.168.114.1:8000/api/students"
diff --git a/resources_references/start-backend.ps1 b/resources_references/start-backend.ps1
new file mode 100644
index 0000000000000000000000000000000000000000..b4ba3c51a7978a6bf79f154ad52c88a747291013
--- /dev/null
+++ b/resources_references/start-backend.ps1
@@ -0,0 +1,30 @@
+# Start Backend Server
+Write-Host "Starting TalimBot Backend..." -ForegroundColor Green
+
+# Check if Python is installed
+try {
+ $pythonVersion = python --version 2>&1
+ Write-Host "Python found: $pythonVersion" -ForegroundColor Cyan
+} catch {
+ Write-Host "ERROR: Python not found. Please install Python 3.8 or higher." -ForegroundColor Red
+ exit 1
+}
+
+# Navigate to backend directory
+$backendPath = Join-Path $PSScriptRoot "backend"
+Set-Location $backendPath
+
+# Check if requirements are installed
+Write-Host "Checking dependencies..." -ForegroundColor Yellow
+$requirementsExist = Test-Path "requirements.txt"
+
+if ($requirementsExist) {
+ Write-Host "Installing/updating dependencies..." -ForegroundColor Yellow
+ pip install -r requirements.txt
+}
+
+# Start the server
+Write-Host "`nStarting FastAPI server on http://localhost:8000" -ForegroundColor Green
+Write-Host "Press Ctrl+C to stop the server`n" -ForegroundColor Yellow
+
+python main.py
diff --git a/resources_references/students_class_notebook.txt b/resources_references/students_class_notebook.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c47b686f3fda90b7c0994497983030edaccb18c3
--- /dev/null
+++ b/resources_references/students_class_notebook.txt
@@ -0,0 +1,35 @@
+کارنامه مستمر پاییز,,,,,,,,,,,,,,,,,,,,
+پایه: دهم تجربی,,,کلاس: 1061,,,,,,,,,,,,,,سال تحصیلی: 1405-1404,,,
+رديف,نام خانوادگی - نام,کد ملی,کلاس,معــدل,اختصاصی,رتبه,,تعلیمات دینی (دینی، اخلاق و قرآن) 1 ,عربی، زبان قرآن1 ,فارسی 1 ,نگارش 1 ,زبان خارجی1 ,جغرافیای عمومی و استان شناسی ,تفکر و سواد رسانهای ,آمادگی دفاعی ,ریاضی1 ,فیزیک1 ,زیست شناسی 1 ,شیمی 1 ,انضباط
+,,,,,,کلاس,پایه,,,,,,,,,,,,,
+-,میانگین,-,-,18.25,17.2,-,-,19.38,17.52,18.47,20,17.43,19.5,20,20,15.7,17.18,18.23,18.2,19.88
+1,آدینه پور - یاسمن,929986644,1061,18.77,18.19,15,24,20,18,18,20,18.5,19,20,20,16,19.5,19,19,20
+2,احمدزاده - پریا,980085330,1061,17.28,15.58,24,48,19.5,13.5,18,20,17.75,19,20,20,12,16.5,16.5,18.5,20
+3,اکبرزاده - فاطمه,970154550,1061,16.71,14.92,27,52,19.25,16,18,20,13.5,18.5,20,20,11,18.5,14.5,17,20
+4,الهی مهر - آناهیتا,26425955,1061,19.05,18.73,11,18,19,19,20,20,17,20,20,20,17,19,20,19.5,20
+5,امیری - مریم,980093341,1061,18.87,17.94,12,21,20,18.5,20,20,18.25,20,20,20,18,16.75,19.5,17.5,20
+6,برادران رحیمی - باران,960043985,1061,19.07,18.4,9,16,18.25,19,20,20,19.5,19.5,20,20,18,18.75,17,20,20
+7,بصیری امین - مایسا,960089446,1061,19.33,19.48,5,9,18.25,18,19,20,18.5,20,20,20,20,18.75,20,19,20
+8,ثابت عهد - دلارام,960125620,1061,19.55,19.54,1,3,20,19,20,20,18,20,20,20,18.5,20,20,20,20
+9,جان محمدی - شاینا,960068041,1061,19.47,19.23,3,5,20,18.5,19,20,19.5,20,20,20,19,19.5,19,19.5,19.5
+10,جوان - آیدا,95112313,1061,16.77,15.06,26,51,18.5,16.75,18,20,13.5,18.5,20,20,9,16.75,18,18.5,20
+11,حاجی آبادی - سارینا,999216751,1061,16.08,12.69,28,55,19.5,18.5,16,20,16.5,18,20,20,12,7,15,17,20
+12,حسن پور جوان - هستی,960074198,1061,19.55,19.15,1,3,20,20,20,20,19,20,20,20,18,20,19.5,19.5,20
+13,حسینی - فاطمه,2400410259,1061,19.07,18.4,9,16,20,19,20,20,18,20,20,20,18,17.75,18,20,20
+14,خسروی - غزل,929995767,1061,15.05,10.69,29,56,20,19.75,14,20,14,19,20,20,7,9,17,11,20
+15,ذباح - غزل,960110186,1061,19.25,19.1,8,13,20,18.5,18,20,18.5,20,20,20,19.5,18.75,18,20,19.5
+16,راشکی - نازنین زهرا,3661516087,1061,17.02,15.71,25,50,20,13,18,20,15.5,17.5,20,20,13,16.25,18,16.5,20
+17,روح نواز - ویونا,314458344,1061,18.7,17.6,16,25,18,19,20,20,19,20,20,20,16.5,18.75,17.5,18,20
+18,سعادتی - روژینا,960051023,1061,18.2,17.52,20,35,18,16,17,20,19.5,18,20,20,15.5,18.25,18.5,18.5,20
+19,شعبانی - ترنم,950083100,1061,19.37,19.35,4,8,20,19.5,18,20,18,20,20,20,19,20,20,18.5,20
+20,شفابخش - ستایش,960126899,1061,18.36,17.73,19,30,20,15.5,15,20,19.25,20,20,20,17.5,16,17.5,20,20
+21,شیرزادخان - فاطمه,980120756,1061,19.33,19.23,5,9,19.5,18.5,17,20,19.75,20,20,20,19,19,19,20,20
+22,علی جوی - آرزو,960054316,1061,17.98,15.65,21,40,20,18.5,20,20,19,20,20,20,13,16,17,17.5,20
+23,قنادزاده - آناهیتا,960089836,1061,18.84,17.58,13,22,20,18.5,20,20,19.5,20,20,20,14,20,19,18.5,19.5
+24,کارگر - نیایش,929956052,1061,17.74,16.45,22,44,18.5,15,19,20,17,20,20,20,12,18.8,19,17.5,19.5
+25,کبریایی نسب - باران,980119588,1061,18.82,17.83,14,23,20,19.5,20,20,17.5,20,20,20,16.5,18.75,19.5,17,20
+26,کیانوش - زینب,970072678,1061,18.58,17.54,17,27,18.25,19,19,20,18.5,20,20,20,16.5,16,20,18,19.5
+27,محمودی - ستایش,929904656,1061,19.33,19.38,5,9,19.75,17,18,20,19.25,20,20,20,19.5,19.5,20,18.5,20
+28,مشتاقی - ستایش,361282217,1061,17.67,17.02,23,46,18.5,15.25,17,20,16,18.5,20,20,16.5,15.75,18,18,20
+29,معلمی - مهتاب,960070265,1061,18.56,17.79,18,29,20,18,20,20,16,20,20,20,17.5,17.75,18,18,20
+30,وحدتی - باران,929916913,1061,15.02,12.58,30,57,18.5,11.5,18,20,9,19.5,20,20,12,8,15,15.5,19
diff --git a/runtime.txt b/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f2dbea3000ec972d40ca1afea09300a86fdb5ee1
--- /dev/null
+++ b/runtime.txt
@@ -0,0 +1 @@
+python-3.11.0