# Project export: Braillience

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 12.0
- Tagline: Braillience makes studying accessible for blind students with voice-controlled flashcards, screen reader support, and AI-generated study materials for inclusive, hands-free learning.
- Devpost: https://devpost.com/software/braillience
- GitHub: https://github.com/Pavanmahaveer7/Braillience
- Video: https://www.youtube.com/embed/1WcWxWYDlo8?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 4 GitHub contributor(s) — Slytherin-dev (4 commits), bhasan26 (3 commits), bhasan26 (1 commits), Ragavan Arivazhagan (1 commits)

## Devpost submission (written by the team)

### Overview

About Braillience 🧠 What It Does Braillience is an accessible flashcard learning platform for blind and visually impaired college students. It enables fully voice-driven studying with AI-generated flashcards, speech navigation, and screen reader support. Users can upload PDFs, generate flashcards, and learn hands-free through spoken commands. 🛠️ How We Built It The frontend is built with React and TypeScript, and the backend uses Node.js + Express. We integrated VAPI for seamless voice processing and Letta File + Agent to manage intelligent flashcard generation and conversational learning. Accessibility was designed in from the start — with ARIA markup, keyboard-only navigation, and high-contrast visual themes. 🚧 Challenges We Ran Into Integrating Letta agents with dynamic voice feedback loops. Handling speech-to-text accuracy in noisy environments. Achieving full screen reader and browser compatibility (NVDA, VoiceOver). 🏆 Accomplishments Built a voice-first learning experience end-to-end. Successfully linked Letta AI agents with VAPI voice pipelines. Created a fully accessible workflow from upload → generate → learn → test. 💡 What We Learned We explored the intersection of AI agents, voice UX, and accessibility engineering. We learned to design for inclusivity and discovered the complexity behind combining speech systems with real-time learning interfaces. 🚀 What’s Next Expand Gemini AI integration for deeper content understanding. Add multi-language voice support. Launch a mobile PWA for offline study. Partner with universities to pilot Braillience in accessibility programs.

## README (from the GitHub repository)

# 🧠 Braillience  
![React](https://img.shields.io/badge/Frontend-React_18-61DAFB?logo=react&logoColor=white)
![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white)
![Node.js](https://img.shields.io/badge/Backend-Node.js-339933?logo=node.js&logoColor=white)
![Express](https://img.shields.io/badge/API-Express-000000?logo=express&logoColor=white)
![Web Speech API](https://img.shields.io/badge/Voice-Web_Speech_API-purple)
![Letta](https://img.shields.io/badge/AI-Letta-1E90FF?logo=openai&logoColor=white)
![Gemini](https://img.shields.io/badge/AI-Google_Gemini-4285F4?logo=google&logoColor=white)
![Claude](https://img.shields.io/badge/AI-Claude_Sonnet_3.5-FFD700?logo=anthropic&logoColor=black)
![Accessibility](https://img.shields.io/badge/Focus-Accessibility-FF69B4?logo=accessible-icon&logoColor=white)
![License: MIT](https://img.shields.io/badge/License-MIT-green)

🎥 **Demo Video:** https://youtu.be/1WcWxWYDlo8?si=g8aWwUHi0QJ5CZUg


---
## 🎯 Problem Statement

Blind and visually impaired college students face significant barriers when using traditional learning platforms — most study apps are **not screen reader compatible**, rely on **visual cues**, and **don’t support voice-only control**.  
Existing accessibility tools are fragmented, forcing students to switch between multiple apps to study effectively.  

**The challenge:**  
How can we create a fully voice-driven, accessible learning experience that allows blind students to **study hands-free**, generate flashcards automatically, and **navigate entirely through speech**?


---

## 💡 Our Solution

**Braillience** is an **accessible learning platform** designed specifically for blind and visually impaired learners.  
It enables teachers to upload PDFs, automatically generate flashcards using AI, and study completely via voice commands — no mouse or screen required. Students start an in-browser voice session and converse with an AI tutor using their microphone and speakers.

**Key Innovations:**

- 🎙️ **Voice-First Learning Interface:** Fully voice-controlled navigation for flashcards, tests, and progress tracking.  
- 🧠 **AI-Generated Flashcards:** Letta Agents analyze uploaded PDFs to create structured study sets automatically.  
- 🗣️ **Seamless Voice Processing:** The browser's built-in Web Speech API handles speech recognition and synthesis for real-time, natural voice interactions, at no per-minute cost.  

Result: A **hands-free, inclusive learning experience** that empowers blind students to study independently.

## 🎯 Project Structure

```
Braillience/
├── backend/                 # Node.js API server
│   ├── src/
│   │   ├── routes/         # API endpoints
│   │   │   ├── auth.js     # Authentication
│   │   │   ├── upload.js   # PDF upload & processing
│   │   │   ├── flashcards.js # Flashcard management
│   │   │   └── voice-learning.js # Browser-based voice tutoring sessions
│   │   ├── services/       # Business logic
│   │   │   ├── aiService.js # AI flashcard generation
│   │   │   └── voiceSessionService.js # Voice session logic & answer grading
│   │   └── server.js       # Express server
│   ├── package.json
│   └── env.example
├── frontend/               # React frontend application
│   ├── src/
│   │   ├── components/    # React components
│   │   │   ├── Dashboard.js/css    # Main dashboard
│   │   │   ├── VoiceTutor.js/css   # In-browser AI voice tutoring session
│   │   │   ├── Login.js/css        # Authentication
│   │   │   ├── Header.js/css       # Navigation header
│   │   │   └── Footer.js/css       # Footer
│   │   ├── contexts/      # React contexts
│   │   │   └── AuthContext.js
│   │   ├── hooks/         # Custom hooks
│   │   │   └── useVoiceCommands.js # Web Speech API recognition hook
│   │   ├── App.js/css     # Main app component
│   │   └── index.js/css   # App entry point
│   ├── public/            # Static assets
│   │   ├── index.html
│   │   └── manifest.json
│   └── package.json
├── docs/                  # Documentation
├── tasks/                 # Project requirements
│   └── prd-braillience-flashcard-app.md
├── start-demo.sh         # Demo startup script
└── README.md
```

---

## 🛠️ Tech Stack

### Frontend
- **React 18 + TypeScript** — Modern and accessible UI  
- **React Router** — App navigation  
- **Framer Motion** — Subtle motion for transitions  

### Backend
- **Node.js + Express** — API and logic layer  
- **Multer** — PDF uploads  
- **JWT** — Authentication  
- **Letta Agents** — AI content generation  

### Voice & AI
- **Web Speech API** — In-browser speech recognition and synthesis, free  
- **Letta File + Agent** — Stateful learning assistance  
- **Gemini AI** — Enhanced semantic understanding  
- **Claude Sonnet 3.5** - AI automation and structured calling

---

## 🚀 Getting Started

### Prerequisites
- Node.js 18+
- npm or yarn

### Installation & Running

1. **Start Backend:**
   ```bash
   cd backend
   npm install
   npm start
   ```

2. **Start Frontend:**
   ```bash
   cd frontend
   npm install
   npm start
   ```

3. **Or use the demo script:**
   ```bash
   ./start-demo.sh
   ```

### Access Points
- **Frontend:** http://localhost:3000
- **Backend API:** http://localhost:3001

## 🎤 Voice Features

### Voice Commands
- **Navigation:** "Start Learning", "Take Test", "Go Back"
- **Learning:** "Show Answer", "Next Card", "Previous Card", "Repeat"
- **Testing:** "Select A", "Select B", "Select C", "Select D"

### Voice Integration
- Speech-to-text for commands
- Text-to-speech for content
- Voice navigation throughout the app
- Screen reader compatibility

## 📱 Features

### Core Functionality
- **PDF Upload:** Upload documents to generate flashcards
- **AI Generation:** Automatic flashcard creation from content
- **Learning Modes:** Flashcards, multiple choice, typing
- **Testing:** Timed tests with scoring
- **Progress Tracking:** Learning analytics and statistics

### User Experience
- **Voice Navigation:** Complete control via voice in call
- **Responsive Design:** Works on all phones
- **Offline Support:** Continue learning without internet
- **Multi-language:** Support for various languages

## 🎯 Demo Flow

1. **Login** → Use demo credentials
2. **Dashboard** → View progress and quick actions
3. **Learn** → Practice with flashcards using voice commands
4. **Test** → Take timed quizzes with voice selection
5. **Progress** → Track learning statistics

## 🔧 Development

### Project Structure
- **Clean separation** between frontend and backend
- **Modular components** for easy maintenance
- **Voice-first architecture** throughout
- **Accessibility-first design** principles

### Key Files
- `frontend/src/App.js` - Main React application
- `frontend/src/components/Dashboard.js` - Main dashboard with voice
- `backend/src/server.js` - Express server setup
- `backend/src/services/aiService.js` - AI integration

## 📚 Documentation

- **PRD:** `tasks/prd-braillience-flashcard-app.md`
- **Accessibility:** `docs/ACCESSIBILITY_GUIDELINES.md`
- **Contributing:** `CONTRIBUTING.md`

## 📝 License
This project is licensed under the MIT License.

**Built with ❤️ by the Braillience Team at Cal Hacks 2025 for accessibility and inclusion**


## Detected evidence (automated analysis)

Indexed codebase: 97 recognized source files, 417 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- OpenAI (technology) — detected in the code
- React (technology) — detected in the code
- Google Gemini (technology) — claimed on Devpost, not found in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- TypeScript (language) — claimed on Devpost, not found in the code
- AI coding agent: Claude Code — evidence: commit authorship or trailers
- AI coding agent: Cursor — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (120 of 166)

```
.cursor/rules/001-Core-Security.mdc
.cursor/rules/002-Accessibility-First.mdc
.cursor/rules/003-Code-Quality.mdc
.cursor/rules/004-Documentation.mdc
.cursor/rules/005-Tech-Stack.mdc
.cursor/rules/100-PRD-Generation.mdc
.cursor/rules/101-Task-Generation.mdc
.cursor/rules/102-Task-Management.mdc
.github/ISSUE_TEMPLATE/accessibility_issue.yml
.github/ISSUE_TEMPLATE/bug_report.yml
.github/ISSUE_TEMPLATE/feature_request.yml
.github/pull_request_template.md
.github/workflows/accessibility.yml
.github/workflows/ci.yml
.gitignore
.nixpacks.toml
backend/.env.backup
backend/clear-all-data.js
backend/clear-letta-memory.js
backend/data/conversations/conv_1761428967760_mdf2j4m7q.json
backend/data/conversations/conv_1761428967761_bdurpcwve.json
backend/data/conversations/conv_1761432369214_ems1i900a.json
backend/data/conversations/conv_1761432405437_dw6ypsykc.json
backend/data/conversations/conv_1761432591346_r1eket72v.json
backend/data/conversations/conv_1761432983331_uz889ddxr.json
backend/data/conversations/conv_1761432984747_u88autjx8.json
backend/data/conversations/conv_1761433201002_fh5vp7egg.json
backend/data/conversations/conv_1761433216753_8kn7not00.json
backend/data/conversations/conv_1761433532097_g2odxq9f4.json
backend/data/conversations/conv_1761433536125_05lfynt3o.json
backend/data/conversations/conv_1761433562139_wsyyz9vzj.json
backend/data/conversations/conv_1761433610671_m6zbdv1s6.json
backend/data/conversations/conv_1761433818722_f5rfsx7ug.json
backend/data/conversations/conv_1761433819410_n1eknnid2.json
backend/data/conversations/conv_1761433894641_c3x7c059x.json
backend/data/conversations/conv_1761433894641_ohex9mrxl.json
backend/data/conversations/conv_1761433994026_ia0dq7kjl.json
backend/data/conversations/conv_1761434045356_jhbqlldr7.json
backend/data/conversations/conv_1761434381101_0nfa23kah.json
backend/data/conversations/conv_1761434381102_8jchhzrkk.json
backend/data/conversations/conv_1761435081028_kv30fbipe.json
backend/data/conversations/conv_1761435374312_mf5kcurvl.json
backend/data/conversations/conv_1761435383769_tt3oh5ghr.json
backend/data/conversations/conv_1761435437835_ryatuh30z.json
backend/data/conversations/conv_1761435438560_pes7hoqoo.json
backend/data/conversations/conv_1761435715666_eo1727wav.json
backend/data/conversations/conv_1761436050996_ffv16lwra.json
backend/data/conversations/conv_1761436114293_kndrip9iu.json
backend/data/conversations/conv_1761436815479_rn6f4kjup.json
backend/data/conversations/conv_1761437197404_2dwimg263.json
backend/data/conversations/conv_1761437281085_jkzwk1gqu.json
backend/data/conversations/conv_1761437424026_bo6iqxcdc.json
backend/data/conversations/conv_1761437811628_cxfypxg6e.json
backend/data/conversations/conv_1761437991555_ks1jywmdt.json
backend/data/conversations/conv_1761438426272_9sw353so9.json
backend/data/conversations/conv_1761438555513_7hossa4mh.json
backend/data/conversations/conv_1761438667845_d3yzleec5.json
backend/data/conversations/conv_1761439075290_1534gy52q.json
backend/data/conversations/conv_1761440532236_k6v61ud8t.json
backend/data/conversations/conv_1761440606046_36c3n3ppk.json
backend/data/conversations/conv_1761440836048_c6x1c9l5n.json
backend/data/conversations/conv_1761441515082_dfzvwa4st.json
backend/data/conversations/conv_1761453018428_s2pxhos04.json
backend/data/conversations/user_blind-student-001_agent.json
backend/data/conversations/user_demo-user_agent.json
backend/data/conversations/user_quick-test-user_agent.json
backend/data/conversations/user_test-complete-letta-fix_agent.json
backend/data/conversations/user_test-letta-agent-user_agent.json
backend/data/conversations/user_test-student-now_agent.json
backend/data/conversations/user_test-user-local_agent.json
backend/env.example
backend/input-real-conversation.js
backend/input-your-conversation.js
backend/package.json
backend/quick-test.js
backend/setup-webhook-alternatives.sh
backend/setup-webhook.sh
backend/src/config/database.js
backend/src/models/Document.js
backend/src/models/Flashcard.js
backend/src/models/User.js
backend/src/routes/auth.js
backend/src/routes/conversations.js
backend/src/routes/flashcards.js
backend/src/routes/test-ai.js
backend/src/routes/upload.js
backend/src/routes/voice-learning.js
backend/src/server.js
backend/src/services/aiService.js
backend/src/services/conversationService.js
backend/src/services/databaseService.js
backend/src/services/lettaService.js
backend/src/services/voiceService.js
backend/src/services/voiceSessionService.js
backend/test-basic-letta-upload.js
backend/test-complete-letta-fix.js
backend/test-complete-pdf-letta-flow.js
backend/test-filename-fix.js
backend/test-final-letta-verification.js
backend/test-folder-creation.js
backend/test-full-letta-integration.js
backend/test-letta-agent-creation.js
backend/test-letta-filesystem.js
backend/test-letta-integration.js
backend/test-letta-sdk.js
backend/test-letta-without-env.js
backend/test-local-letta.js
backend/test-local-setup.js
backend/test-pdf-letta-integration.js
backend/test-pdf-upload.js
backend/test-phone-transcript.js
backend/test-shared-letta-agent.js
backend/test-simple-filesystem.js
backend/test-stateful-response.js
backend/test-upload-to-existing-folder.js
backend/test-verify-letta-folders.js
backend/test-webhook-locally.js
backend/update-letta-agent.js
build.sh
CONTRIBUTING.md
[46 more files omitted for size]
```

### Dependencies

- backend/package.json: @letta-ai/letta-client@^0.0.68665, @types/jest@^29.5.8, axios@^1.6.2, bcryptjs@^2.4.3, better-sqlite3@^12.4.1, compression@^1.7.4, cors@^2.8.5, dotenv@^16.3.1, express@^4.18.2, express-rate-limit@^7.1.5, helmet@^7.1.0, jest@^29.7.0, jsonwebtoken@^9.0.2, letta@^0.5.2, multer@^1.4.5-lts.1, node-cron@^3.0.3, nodemon@^3.0.2, openai@^4.20.1, pdf-parse@^1.1.1, sqlite3@^5.1.7, supertest@^6.3.3
- frontend/package.json: @types/react@^18.0.28, @types/react-dom@^18.0.11, axios@^1.3.0, eslint@^8.38.0, eslint-plugin-jsx-a11y@^6.7.1, eslint-plugin-react@^7.32.2, eslint-plugin-react-hooks@^4.6.0, framer-motion@^10.0.0, react@^18.2.0, react-dom@^18.2.0, react-dropzone@^14.2.3, react-hot-toast@^2.4.0, react-icons@^4.7.0, react-router-dom@^6.8.0, react-scripts@^5.0.1, web-vitals@^3.1.0

### Recent commits (newest first)

- Replace VAPI phone calls with free in-browser Web Speech API voice sessions
- Fix broken production build: gitignore was excluding frontend/public
- Update README.md
- Update CONTRIBUTING.md
- Fix Railway deployment configuration - add root package.json and nixpacks config
- Ready for deployment with custom domain
- added some stuff to make the letta smoother
- letta + vapi integration
- voice agent
- added vapi and fixed demo login
- -vapi everything is good to go
- fixed the bugs in the backend code
- added backend
- Merge remote changes with voice logic preserved
- Save current voice logic and backend implementation
- Delete h.exe
- Merge branch 'master' of https://github.com/Pavanmahaveer7/Braillience
- frontend files in frontend folder
- Shared types
- .

## Key source files (fetched from GitHub, selected and truncated for size)

### QUICK_DEPLOY.md

```markdown
# 🚀 Quick Deploy Guide

## Option 1: Vercel (Frontend) + Railway (Backend) - RECOMMENDED

### Step 1: Deploy Frontend to Vercel

```bash
# Install Vercel CLI
npm install -g vercel

# Deploy frontend
cd frontend
vercel

# Follow prompts:
# - Link to existing project? N
# - Project name: braillience-frontend
# - Directory: ./
# - Override settings? N
```

### Step 2: Deploy Backend to Railway

1. Go to [railway.app](https://railway.app)
2. Sign up with GitHub
3. Click "New Project" → "Deploy from GitHub repo"
4. Select your Braillience repository
5. Add environment variables:
   ```
   LETTA_API_KEY=your_letta_key
   VAPI_API_KEY=your_vapi_key
   VAPI_ASSISTANT_ID=your_assistant_id
   VAPI_PHONE_NUMBER_ID=your_phone_id
   USE_REAL_VAPI=true
   ```

### Step 3: Connect Frontend to Backend

1. Get your Railway backend URL (e.g., `https://braillience-backend.railway.app`)
2. In Vercel dashboard, go to your project settings
3. Add environment variable:
   ```
   REACT_APP_API_URL=https://your-railway-backend-url.railway.app
   ```
4. Redeploy frontend

## Option 2: One-Click Deploy (Railway Full Stack)

1. Go to [railway.app](https://railway.app)
2. Click "Deploy from GitHub"
3. Select your repository
4. Add environment variables
5. Deploy!

## Option 3: Render (Full Stack)

1. Go to [render.com](https://render.com)
2. Connect GitHub repository
3. Create new Web Service
4. Set:
   - Build Command: `cd frontend && npm run build`
   - Start Command: `cd backend && node src/server.js`
   - Publish Directory: `frontend/build`
5. Add environment variables
6. Deploy!

## Environment Variables Needed

### Backend
```
LETTA_API_KEY=your_letta_api_key
VAPI_API_KEY=your_vapi_api_key
VAPI_ASSISTANT_ID=your_vapi_assistant_id
VAPI_PHONE_NUMBER_ID=your_vapi_phone_number_id
USE_REAL_VAPI=true
```

### Frontend
```
REACT_APP_API_URL=https://your-backend-url.com
```

## Quick Test

```bash
# Test locally first
cd frontend
npm run build
npx serve -s build -l 3000

# In another terminal
cd backend
npm start
```

## Cost

- **Vercel**: Free tier (100GB bandwidth)
- **Railway**: Free tier ($5 credit)
- **Render**: Free tier (750 hours/month)

## Need Help?

1. Check `DEPLOYMENT_GUIDE.md` for detailed instructions
2. Check platform documentation
3. Test locally first with `npm run build`

---

**Ready to deploy?** Choose an option above and follow the steps! 🚀

```

### DEPLOY_NOW.md

```markdown
# 🚀 Deploy Braillience NOW!

## Method 1: Railway (Easiest - Full Stack)

### Step 1: Prepare Your Repository
```bash
# Make sure all changes are committed
git add .
git commit -m "Ready for deployment"
git push origin main
```

### Step 2: Deploy to Railway
1. Go to [railway.app](https://railway.app)
2. Sign up with GitHub
3. Click "New Project" → "Deploy from GitHub repo"
4. Select your Braillience repository
5. Railway will automatically detect it's a Node.js app

### Step 3: Add Environment Variables
In Railway dashboard, go to your project → Variables tab:

```
LETTA_API_KEY=your_letta_api_key_here
VAPI_API_KEY=your_vapi_api_key_here
VAPI_ASSISTANT_ID=your_vapi_assistant_id_here
VAPI_PHONE_NUMBER_ID=your_vapi_phone_number_id_here
USE_REAL_VAPI=true
NODE_ENV=production
```

### Step 4: Deploy!
Railway will automatically:
- Install dependencies
- Run the build script
- Start the server
- Give you a live URL!

---

## Method 2: Render (Alternative)

### Step 1: Deploy to Render
1. Go to [render.com](https://render.com)
2. Sign up with GitHub
3. Click "New" → "Web Service"
4. Connect your repository

### Step 2: Configure Settings
- **Build Command**: `./build.sh`
- **Start Command**: `cd backend && node src/server.js`
- **Environment**: Node

### Step 3: Add Environment Variables
Same as Railway above.

---

## Method 3: Vercel + Railway (Separate)

### Frontend (Vercel)
```bash
# Install Vercel CLI
npm install -g vercel

# Deploy frontend
cd frontend
vercel

# Add environment variable in Vercel dashboard:
# REACT_APP_API_URL=https://your-railway-backend-url.railway.app
```

### Backend (Railway)
Follow Method 1 steps 2-4 above.

---

## Quick Deploy Commands

### Test Locally First
```bash
# Build and test locally
./build.sh

# Start the server
cd backend && node src/server.js

# Visit http://localhost:3001
```

### Deploy to Railway
```bash
# Install Railway CLI
npm install -g @railway/cli

# Login and deploy
railway login
railway init
railway up
```

---

## Environment Variables You Need

### Get Your API Keys:

**Letta API Key:**
1. Go to [app.letta.com](https://app.letta.com)
2. Sign up/login
3. Go to Settings → API Keys
4. Copy your API key

**VAPI API Key:**
1. Go to [vapi.ai](https://vapi.ai)
2. Sign up/login
3. Go to Dashboard → API Keys
4. Copy your API key

**VAPI Assistant ID:**
1. In VAPI dashboard, create an assistant
2. Copy the assistant ID

**VAPI Phone Number ID:**
1. In VAPI dashboard, go to Phone Numbers
2. Add a phone number
3. Copy the phone number ID

---

## After Deployment

### Test Your App
1. Visit your deployed URL
2. Try uploading a PDF
3. Test the AI Teacher call feature
4. Check if everything works

### Custom Domain (Optional)
1. Buy a domain from Namecheap/GoDaddy
2. In Railway/Render, add custom domain
3. Update DNS records
4. SSL certificate will be auto-generated

---

## Troubleshooting

### Common Issues:
1. **Build fails**: Check Node.js version (use 18+)
2. **API errors**: Verify environment variables

[truncated — 656 more characters]
```

### package.json

```
{
  "name": "braillience",
  "version": "1.0.0",
  "description": "Braillience - AI-powered flashcard app for blind users",
  "main": "backend/src/server.js",
  "scripts": {
    "start": "cd backend && node src/server.js",
    "dev": "cd backend && npm run dev",
    "build": "cd frontend && npm run build",
    "install-all": "cd backend && npm install && cd ../frontend && npm install",
    "test": "cd backend && npm test"
  },
  "engines": {
    "node": ">=18.0.0",
    "npm": ">=8.0.0"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/yourusername/braillience.git"
  },
  "keywords": [
    "accessibility",
    "flashcards",
    "ai",
    "blind",
    "learning"
  ],
  "author": "Your Name",
  "license": "MIT"
}

```

### backend/package.json

```
{
  "name": "braillience-backend",
  "version": "1.0.0",
  "description": "Backend API for Braillience flashcard app",
  "main": "src/server.js",
  "scripts": {
    "dev": "nodemon src/server.js",
    "start": "node src/server.js",
    "test": "jest",
    "test:watch": "jest --watch"
  },
  "dependencies": {
    "@letta-ai/letta-client": "^0.0.68665",
    "axios": "^1.6.2",
    "bcryptjs": "^2.4.3",
    "better-sqlite3": "^12.4.1",
    "compression": "^1.7.4",
    "cors": "^2.8.5",
    "dotenv": "^16.3.1",
    "express": "^4.18.2",
    "express-rate-limit": "^7.1.5",
    "helmet": "^7.1.0",
    "jsonwebtoken": "^9.0.2",
    "letta": "^0.5.2",
    "multer": "^1.4.5-lts.1",
    "node-cron": "^3.0.3",
    "openai": "^4.20.1",
    "pdf-parse": "^1.1.1",
    "sqlite3": "^5.1.7"
  },
  "devDependencies": {
    "@types/jest": "^29.5.8",
    "jest": "^29.7.0",
    "nodemon": "^3.0.2",
    "supertest": "^6.3.3"
  }
}

```

### frontend/package.json

```
{
  "name": "braillience-frontend",
  "version": "1.0.0",
  "description": "Accessible Quizlet for Blind Users - Frontend",
  "main": "index.js",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "dev": "react-scripts start",
    "lint": "eslint src/",
    "lint:fix": "eslint src/ --fix"
  },
  "dependencies": {
    "axios": "^1.3.0",
    "framer-motion": "^10.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-hot-toast": "^2.4.0",
    "react-icons": "^4.7.0",
    "react-router-dom": "^6.8.0",
    "react-scripts": "^5.0.1",
    "web-vitals": "^3.1.0",
    "react-dropzone": "^14.2.3"
  },
  "devDependencies": {
    "@types/react": "^18.0.28",
    "@types/react-dom": "^18.0.11",
    "eslint": "^8.38.0",
    "eslint-plugin-jsx-a11y": "^6.7.1",
    "eslint-plugin-react": "^7.32.2",
    "eslint-plugin-react-hooks": "^4.6.0"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "keywords": [
    "accessibility",
    "blind",
    "quizlet",
    "language-learning",
    "screen-reader",
    "inclusive-design"
  ],
  "author": "Cal-Hack Team",
  "license": "MIT"
}

```

### frontend/src/index.js

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
import './index.css';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

```

### frontend/src/App.js

```javascript
import React, { useState, useEffect } from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import { Toaster } from 'react-hot-toast';
import Login from './components/Login';
import Register from './components/Register';
import Home from './components/Home';
import Dashboard from './components/Dashboard';
import About from './components/About';
import Upload from './components/Upload';
import VoiceTutor from './components/VoiceTutor';
import Header from './components/Header';
import Footer from './components/Footer';
import { AuthProvider, useAuth } from './contexts/AuthContext';
import './App.css';

function AppContent() {
  const { user, loading } = useAuth();

  if (loading) {
    return (
      <div className="loading-container" role="status" aria-live="polite">
        <div className="loading-spinner"></div>
        <p className="loading-text">Loading Braillience...</p>
      </div>
    );
  }

  return (
    <div className="app">
      <Header />
      <main className="main-content">
        <Routes>
          <Route path="/" element={user ? <Dashboard /> : <Home />} />
          <Route path="/login" element={!user ? <Login /> : <Navigate to="/dashboard" />} />
          <Route path="/register" element={!user ? <Register /> : <Navigate to="/dashboard" />} />
          <Route path="/dashboard" element={user ? <Dashboard /> : <Navigate to="/login" />} />
          <Route path="/about" element={<About />} />
          <Route path="/upload" element={user ? <Upload /> : <Navigate to="/login" />} />
          <Route path="/voice" element={user ? <VoiceTutor /> : <Navigate to="/login" />} />
        </Routes>
      </main>
      <Footer />
      <Toaster 
        position="top-right"
        toastOptions={{
          duration: 4000,
          style: {
            background: '#363636',
            color: '#fff',
          },
        }}
      />
    </div>
  );
}

function App() {
  return (
    <AuthProvider>
      <AppContent />
    </AuthProvider>
  );
}

export default App;

```

### backend/src/server.js

```javascript
const express = require('express')
const cors = require('cors')
const helmet = require('helmet')
const compression = require('compression')
const rateLimit = require('express-rate-limit')
const path = require('path')
const database = require('./config/database')
require('dotenv').config()

const app = express()
const PORT = process.env.PORT || 3001

// Middleware
app.use(helmet())
app.use(compression())
app.use(cors({
  origin: process.env.FRONTEND_URL || 'http://localhost:3000',
  credentials: true
}))

// Serve static files from React build
app.use(express.static(path.join(__dirname, '../public')))

// Rate limiting
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // limit each IP to 100 requests per windowMs
})
app.use('/api/', limiter)

app.use(express.json({ limit: '50mb' }))
app.use(express.urlencoded({ extended: true, limit: '50mb' }))

// Routes
app.use('/api/auth', require('./routes/auth'))
app.use('/api/upload', require('./routes/upload'))
app.use('/api/flashcards', require('./routes/flashcards'))
app.use('/api/voice-learning', require('./routes/voice-learning')) // Browser-based voice tutoring
app.use('/api/conversations', require('./routes/conversations')) // Conversation storage with Letta
app.use('/api/test-ai', require('./routes/test-ai'))

// Health check
app.get('/api/health', (req, res) => {
  res.json({ 
    status: 'OK', 
    timestamp: new Date().toISOString(),
    service: 'Braillience API'
  })
})

// Error handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack)
  res.status(500).json({ 
    error: 'Something went wrong!',
    message: process.env.NODE_ENV === 'development' ? err.message : 'Internal server error'
  })
})

// Catch-all handler: send back React's index.html file for any non-API routes
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, '../public/index.html'))
})

// Start server with database connection
async function startServer() {
  try {
    // Connect to database
    await database.connect()
    
    // Start the server
    app.listen(PORT, () => {
      console.log(`🚀 Braillience API server running on port ${PORT}`)
      console.log(`📚 Environment: ${process.env.NODE_ENV || 'development'}`)
      console.log(`🗄️ Database: ${database.getConnectionStatus().isConnected ? 'Connected' : 'Disconnected'}`)
    })
  } catch (error) {
    console.error('❌ Failed to start server:', error)
    process.exit(1)
  }
}

// Handle graceful shutdown
process.on('SIGINT', async () => {
  console.log('\n🛑 Shutting down server...')
  await database.disconnect()
  process.exit(0)
})

process.on('SIGTERM', async () => {
  console.log('\n🛑 Shutting down server...')
  await database.disconnect()
  process.exit(0)
})

// Start the server
startServer()

module.exports = app

```

### build.sh

```shell
#!/bin/bash

# Build script for Railway deployment
echo "🚀 Building Braillience for production..."

# Install dependencies
echo "📦 Installing dependencies..."
npm install

# Build frontend
echo "🏗️ Building frontend..."
cd frontend
npm install
npm run build
cd ..

# Copy frontend build to backend public directory
echo "📁 Copying frontend build to backend..."
mkdir -p backend/public
cp -r frontend/build/* backend/public/

echo "✅ Build complete!"
echo "🎯 Frontend built and served from backend at /public"

```

### start-demo.sh

```shell
#!/bin/bash

echo "🚀 Starting Braillience Demo..."
echo ""

# Check if node_modules exist
if [ ! -d "node_modules" ]; then
    echo "📦 Installing root dependencies..."
    npm install
fi

if [ ! -d "frontend/node_modules" ]; then
    echo "📦 Installing frontend dependencies..."
    cd frontend && npm install && cd ..
fi

if [ ! -d "backend/node_modules" ]; then
    echo "📦 Installing backend dependencies..."
    cd backend && npm install && cd ..
fi

echo ""
echo "🎯 Starting development servers..."
echo "Frontend: http://localhost:3000"
echo "Backend: http://localhost:3001"
echo ""
echo "Press Ctrl+C to stop both servers"
echo ""

# Start both servers concurrently
npm run dev

```

[89 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]