A multi-platform language learning application that uses AI-driven conversations to help users practice and improve their language skills. This monorepo contains a React Native mobile app, Next.js web application, and standalone WebSocket server for real-time communication.
Thrivify is an AI-powered language learning platform where users practice conversations with AI tutors that adapt to their learning level (CEFR framework). The platform emphasizes natural dialogue practice with real-time feedback and corrections.
Core Features:
- AI Conversation Partners: Two specialized OpenAI assistants ("Thrivify" and "Language Expert") provide conversational practice
- CEFR Level Adaptation: AI adjusts difficulty based on user's language proficiency (A1-C2)
- Structured Lessons: Progressive language lessons with training data storage
- Real-time Communication: WebSocket-based chat across mobile and web platforms
- Language Analysis: Syntax parsing, vocabulary filtering, and correction tracking
- Multi-platform: Native mobile apps (iOS/Android via Expo) and responsive web interface
- Offline-First Mobile: Realm database enables offline functionality with eventual sync
- Framework: Expo 49 / React Native 0.72.6
- State Management: Jotai atoms + React Query (TanStack Query)
- Local Database: Realm for offline-first data storage
- Navigation: React Navigation 6.x (Native Stack, Bottom Tabs)
- UI Components: React Native Paper, Styled Components, Flash List
- Chat Interface: React Native Gifted Chat
- Speech: Expo Speech (TTS), React Native Voice (STT)
- Animations: React Native Reanimated, Lottie
- Storage: React Native MMKV (fast key-value storage)
- Notifications: Expo Notifications
- Language: TypeScript
- Framework: Next.js 14 (Pages Router)
- Database: Azure Cosmos DB
- AI Integration: OpenAI GPT with Assistants API
- Styling: Tailwind CSS
- WebSocket Client: Custom integration
- Authentication: Custom header-based auth (x-install-id)
- Deployment: Docker container to Azure App Service
- Language: TypeScript
- Runtime: Node.js 20.x
- Framework: Express.js + ws library
- Database: Azure Cosmos DB (shared with web-app)
- Real-time: WebSocket server for both mobile and web clients
- Deployment: Docker container to Azure App Service
- Language: TypeScript
- Purpose: DynamoDB table definitions (legacy infrastructure)
- Framework: Serverless Framework
- Cloud: AWS (DynamoDB tables only)
- Status: Infrastructure-only, no active Lambda functions
- Note: DynamoDB tables appear unused; all services use Azure Cosmos DB
┌─────────────────┐ ┌─────────────────┐
│ Mobile App │ │ Web App │
│ (React Native) │ │ (Next.js) │
└────────┬────────┘ └────────┬────────┘
│ │
│ REST API │ (Internal)
│ WebSocket │ WebSocket
│ │
├───────────────────────────┤
│ │
┌────────▼────────┐ ┌────────▼────────┐
│ Next.js App │◄────────┤ WebSocket Server│
│ (API Routes) │ Query │ (Express + ws) │
└────────┬────────┘ └────────┬────────┘
│ │
│ │
└─────────┬─────────────────┘
│
┌────────▼────────┐
│ Azure Cosmos DB │
│ (thrivify) │
└─────────────────┘
-
Next.js Web App (
packages/web-app)- Serves the web interface at add-secret-here
- Provides REST API endpoints at
/api/*that BOTH mobile and web clients use - Integrates with OpenAI Assistants API for AI conversations
- Stores all data in Azure Cosmos DB
- API endpoints include: user, conversations, thread, message, lesson, language, etc.
-
WebSocket Server (
packages/websocket-server)- Standalone WebSocket server at add-secret-here
- Handles real-time messaging for both mobile and web clients
- Shares Azure Cosmos DB with web-app
- Validates challenges and manages connection lifecycle
-
Mobile App (
packages/mobile-app)- Makes HTTP requests to Next.js API routes (not AWS Lambda)
- Connects to WebSocket server for real-time updates
- Uses Realm for offline-first local storage
- Syncs data when connection is available
-
Backend Package (
packages/backend)- Important: This is NOT an API server
- Only contains DynamoDB table definitions via Serverless Framework
- Tables appear to be legacy/unused (all services use Cosmos DB)
- Has one WebSocket handler file that may be deprecated
- ✅ AI-powered conversation practice with 2 specialized assistants
- ✅ CEFR-level adaptive difficulty (A1-C2)
- ✅ Real-time language corrections and feedback
- ✅ Vocabulary filtering and syntax analysis
- ✅ Structured progressive lessons
- ✅ Lesson training data collection
- ✅ Translation practice with training storage
- ✅ Speech-to-text input (mobile)
- ✅ Text-to-speech feedback (mobile)
- ✅ Multi-platform (iOS, Android via Expo, Web via Next.js)
- ✅ Offline-first mobile app (Realm database with sync)
- ✅ Real-time WebSocket communication
- ✅ Azure Cosmos DB for all active services
- ✅ OpenAI GPT Assistants API integration
- ✅ Docker containerization for web services
- ✅ TypeScript throughout (mobile, web, websocket-server)
- ✅ Header-based authentication (x-install-id)
- ✅ Custom language syntax parsing
- ✅ JSON repair utilities for robust AI response handling
- Node.js 18.x or later (20.x for websocket-server)
- Yarn package manager
- Expo CLI (
npm install -g expo-cli) - Azure account (for Cosmos DB)
- OpenAI API key
- Docker (for web service deployment)
cd packages/mobile-app
# Install dependencies
yarn install
# iOS specific - install pods
cd ios && pod install && cd ..
# Configure environment
# Edit app.config.ts to point to your API and WebSocket URLs
# Default production URLs:
# - API: add-secret-here/api
# - WebSocket: add-secret-here
# Start Expo development server
yarn start
# Run on iOS
yarn ios
# Run on Android
yarn android
# Type checking
yarn ts:check
# Linting
yarn lintcd packages/web-app
# Install dependencies
yarn install
# Configure environment variables
cp .env.example .env.local
# Edit .env.local with:
# - COSMOS_ENDPOINT (Azure Cosmos DB endpoint)
# - COSMOS_KEY (Azure Cosmos DB key)
# - DEFAULT_ASSISTANT_ID (OpenAI Assistant ID for main tutor)
# - LANGUAGE_EXPERT_ASSISTANT_ID (OpenAI Assistant ID for language expert)
# - OPENAI_API_KEY
# Run development server
yarn dev # starts on http://localhost:3000
# Build for production
yarn build
# Run production server
yarn start
# Build Docker image
docker build -t klyveress .cd packages/websocket-server
# Install dependencies
yarn install
# Build TypeScript
yarn build
# Configure environment variables
cp .env.example .env
# Edit .env with:
# - COSMOS_ENDPOINT
# - COSMOS_KEY
# - PORT (default: 5738)
# Run development (with watch mode)
yarn dev
# Run production
yarn start # runs compiled JS from dist/
# Build Docker image
docker build -t klyveress-ws .cd packages/backend
# Install dependencies
yarn install
# Note: This package only defines DynamoDB tables
# No API server exists here
# Deploy infrastructure to AWS (if needed)
serverless deploy --stage prod
# The defined tables are:
# - users, conversations, conversation-participants
# - conversation-actions, websocket-connections
# - lessons, lessons-trainingthrivify-monorepo/
├── packages/
│ ├── mobile-app/ # Expo/React Native mobile application
│ │ ├── api/ # API client and REST endpoint wrappers
│ │ │ ├── rest/ # REST API functions (action, lesson, message, etc.)
│ │ │ ├── database/ # Realm database schemas and queries
│ │ │ ├── hooks/ # React Query hooks
│ │ │ └── language/ # Language detection and processing
│ │ ├── app/ # App entry point
│ │ ├── components/ # Reusable UI components
│ │ ├── state/ # Jotai atoms for global state
│ │ ├── assets/ # Images, fonts
│ │ ├── lottie/ # Lottie animations
│ │ ├── localization/ # i18n translations
│ │ ├── android/ # Android native code
│ │ └── ios/ # iOS native code
│ │
│ ├── web-app/ # Next.js web application + API server
│ │ ├── src/
│ │ │ ├── pages/ # Next.js pages
│ │ │ │ ├── api/ # REST API endpoints (shared by mobile & web)
│ │ │ │ │ ├── conversation.ts
│ │ │ │ │ ├── conversations.ts
│ │ │ │ │ ├── message.ts
│ │ │ │ │ ├── thread.ts
│ │ │ │ │ ├── threadMessages.ts
│ │ │ │ │ ├── threadActions.ts
│ │ │ │ │ ├── user.ts
│ │ │ │ │ ├── lesson.ts
│ │ │ │ │ ├── lessons.ts
│ │ │ │ │ ├── language.ts
│ │ │ │ │ └── health/readiness/startup.ts
│ │ │ │ └── index.tsx # Web app home page
│ │ │ ├── lib/ # Business logic
│ │ │ │ ├── azure.ts # Cosmos DB client & containers
│ │ │ │ ├── assistants.ts# OpenAI Assistant configurations
│ │ │ │ ├── authenticate.ts # Auth middleware
│ │ │ │ ├── conversation.ts # Conversation logic
│ │ │ │ ├── message.ts # Message processing
│ │ │ │ ├── action.ts # User actions
│ │ │ │ ├── aiResponse/ # AI response processing
│ │ │ │ ├── language/ # Language syntax & analysis
│ │ │ │ ├── openai.ts # OpenAI client
│ │ │ │ └── websocket.ts # WebSocket utilities
│ │ │ └── styles/ # Global CSS
│ │ ├── Dockerfile # Docker containerization
│ │ └── cosmos-db-deployment.json
│ │
│ ├── websocket-server/ # Standalone WebSocket server
│ │ ├── src/
│ │ │ ├── server.ts # Express HTTP server
│ │ │ ├── wss.ts # WebSocket server (ws library)
│ │ │ ├── endpoints.ts # HTTP endpoints
│ │ │ ├── azure.ts # Cosmos DB client
│ │ │ ├── config.ts # Configuration
│ │ │ └── validateChallenge.ts
│ │ ├── dist/ # Compiled JavaScript output
│ │ └── Dockerfile # Docker containerization
│ │
│ └── backend/ # Infrastructure definitions only
│ ├── src/
│ │ └── websockets/ # (Legacy) WebSocket handler
│ │ └── connection.js
│ ├── serverless.yml # DynamoDB table definitions
│ └── buildspec.yml # AWS CodeBuild config
│
└── README.md # This file
Database: thrivify
Containers:
- Users: User profiles, install IDs, learning preferences, CEFR levels
- Conversations: Conversation threads with AI assistants
- ConversationParticipants: Maps users to conversations
- ConversationActions: User actions within conversations (typing, messages, etc.)
- WebsocketConnections: Active WebSocket connection tracking
- Lessons: Language lessons content and metadata
- LessonsTraining: Training data collected from lesson interactions
- TranslationsTraining: Translation practice training data
The packages/backend/serverless.yml defines these tables, but they appear unused:
users,conversations,conversation-participantsconversation-actions,websocket-connectionslessons,lessons-training
Note: All active services (web-app, websocket-server, mobile-app) use Azure Cosmos DB exclusively.
Two specialized AI assistants configured in packages/web-app/src/lib/assistants.ts:
- Purpose: General conversation practice in the target language
- Input Parameters:
learningLanguage,nativeLanguage,CEFRLevel - Response Processing: Extracts
messageandmessageLanguagefrom JSON response - Use Case: Natural dialogue practice
- Purpose: Topic-based conversation with corrections
- Input Parameters:
learningLanguage,CEFRLevel,topic(e.g., "Travel") - Response Processing: Extracts
messageAboutTopicandcorrectionsMade - Use Case: Focused practice with explicit feedback
All sensitive credentials managed through environment variables:
Never commit:
.env,.env.localfiles- Azure Cosmos DB connection strings
- OpenAI API keys
- Docker registry credentials
Configuration Requirements:
Web App (packages/web-app):
COSMOS_ENDPOINT- Azure Cosmos DB endpoint URLCOSMOS_KEY- Azure Cosmos DB primary keyDEFAULT_ASSISTANT_ID- OpenAI Assistant ID for main tutorLANGUAGE_EXPERT_ASSISTANT_ID- OpenAI Assistant ID for language expertOPENAI_API_KEY- OpenAI API key
WebSocket Server (packages/websocket-server):
COSMOS_ENDPOINT- Azure Cosmos DB endpoint URLCOSMOS_KEY- Azure Cosmos DB primary keyPORT- Server port (default: 5738)
Mobile App (packages/mobile-app):
- Configure
apiUrlandwebSocketUrlinapp.config.ts - Production defaults:
- API:
add-secret-here/api - WebSocket:
add-secret-here
- API:
cd packages/web-app
# Build Docker image
docker build -t klyveress .
# Tag for Azure Container Registry
docker tag klyveress add-secret-here/klyveress:latest
# Push to registry
az acr login --name add-secret-here
docker push add-secret-here/klyveress:latest
# Azure App Service automatically deploys from container registrycd packages/websocket-server
# Build Docker image
docker build -t klyveress-ws .
# Tag and push to Azure Container Registry
docker tag klyveress-ws add-secret-here/klyveress-ws:latest
docker push add-secret-here/klyveress-ws:latestiOS:
- Update version in
app.json - Build with EAS:
eas build --platform ios - Submit to App Store Connect
Android:
- Update version in
app.json - Build with EAS:
eas build --platform android - Submit to Google Play Console
Expo Development:
cd packages/mobile-app
yarn start # Opens Expo Dev ToolsThe Next.js web app provides REST API endpoints at /api/* used by BOTH mobile and web clients:
POST /api/user- Create/update user profileGET /api/user- Get user profile
GET /api/conversations- List user's conversationsPOST /api/conversation- Create new conversationDELETE /api/conversation- Delete conversationPATCH /api/conversation- Update conversation settings
POST /api/thread- Create OpenAI threadGET /api/threadMessages- Get messages in a threadPOST /api/message- Send message to AI assistantPATCH /api/message- Analyze message for vocabularyGET /api/threadActions- Get thread actions
GET /api/lessons- List available lessonsGET /api/lesson- Get specific lessonPOST /api/lesson- Create/update lessonPATCH /api/lesson- Update lesson progress
POST /api/language- Analyze language syntax and vocabulary
GET /api/health- Health checkGET /api/readiness- Readiness probeGET /api/startup- Startup probe
# Mobile app
cd packages/mobile-app
# (No tests configured yet)
# Web app
cd packages/web-app
# (No tests configured yet)
# Backend
cd packages/backend
yarn test# Mobile app
cd packages/mobile-app
yarn ts:check
# Web app (automatically checked during build)
cd packages/web-app
yarn build
# Backend
cd packages/backend
yarn type-check# Any package
yarn format # Prettier
yarn lint # ESLint# Mobile app
cd packages/mobile-app
yarn find-deadcode # ts-prune- Unified API Layer: Next.js API routes serve both mobile and web clients, avoiding duplication
- Separate WebSocket Server: Dedicated Express+ws server optimized for real-time messaging
- Azure-First: All active services use Azure Cosmos DB (DynamoDB tables are legacy)
- Offline-First Mobile: Realm database enables mobile app to work without connectivity
- AI Assistants Pattern: OpenAI Assistants API maintains conversation context across sessions
- Header-Based Auth: Simple
x-install-idheader authentication for cross-platform compatibility - JSON Repair: Uses
jsonrepairlibrary to handle malformed AI responses gracefully - CEFR Framework: Standardized language proficiency levels (A1-C2) for adaptive difficulty
❌ "AWS Lambda Backend API" - The backend package only defines infrastructure, no Lambda functions exist ✅ Reality: Next.js API routes serve as the REST API
❌ "Dual Database Architecture (DynamoDB + Cosmos)" - DynamoDB tables are defined but unused ✅ Reality: Only Azure Cosmos DB is actively used by all services
❌ "Mobile connects to AWS services" - Mobile app doesn't use AWS at all ✅ Reality: Mobile connects to Next.js (Azure) and WebSocket server (Azure)
Private - All rights reserved
Note: This is a portfolio project showcasing multi-platform language learning technology, AI integration via OpenAI Assistants API, real-time WebSocket communication, and full-stack TypeScript development. Production credentials have been sanitized for security.