A full-stack, open-source medication adherence assistant that combines a modern React frontend with an Express.js backend, AI health agents, notifications, and report analysis. Built for real-world usability and ready for contributors through Social Winter of Code.
All important project updates, rules, and timelines are shared in the
GitHub Discussions → Announcements section.
➡️ Please make sure to check it regularly.
- Open for contributors: We welcome newcomers and experienced contributors alike. Good first issues, docs improvements, and feature work are all appreciated.
- Real impact: Medication non-adherence affects health outcomes globally. MedSync AI provides reminders, scheduling, AI guidance, and health report analysis to help users stay on track.
- Modern stack: React + Vite + Tailwind on the frontend; Node.js + Express + MongoDB + Socket.IO + LangChain integrations on the backend.
- Clear pathways: Pick an issue, discuss in comments, and submit a PR. If you’re unsure where to start, open a discussion or ask for guidance.
MedSync AI is a monorepo with two main parts:
- client/ — React app (Vite, Tailwind) for the user experience: auth, dashboard, medication management, notifications, AI agents, report upload/chat, Google Calendar sync.
- server/ — Express.js API with JWT auth, medication CRUD, notification scheduling (with Socket.IO), AI agent endpoints (LangChain, Groq/Gemini), PDF parsing, and Google Calendar integration.
High-level flow:
- User authenticates (JWT).
- Frontend fetches schedule/adherence stats and displays a dashboard.
- Users add/update medications; backend stores via MongoDB.
- Scheduler/Socket.IO delivers reminders and notifications.
- AI agents answer health/medication questions via LangChain + LLMs.
- Users upload reports, get AI analysis, and chat with analyzed reports.
- Optional Google Calendar sync for medication schedules.
Frontend
- React (Vite), Tailwind CSS, React Router
- Axios, React Context API
- Socket.IO Client, Recharts, Lucide React
Backend
- Node.js, Express.js
- MongoDB + Mongoose
- JWT auth, bcrypt
- LangChain with Groq/Gemini (LLMs)
- Socket.IO for real-time notifications
- Multer + pdf-parse for uploads and parsing
- Google Calendar API (OAuth2)
- dotenv for config
MedSync-AI/
├─ client/ # React app
│ ├─ src/pages # Views (Dashboard, Login, addMedication, agents, etc.)
│ ├─ src/components # Reusable components (ProtectedRoute, Navbar, etc.)
│ ├─ src/context # Contexts (medication, notification, socket, calendarSync)
│ └─ src/App.jsx # Routing setup
└─ server/ # Express API
├─ src/routes # Route definitions (e.g., medicineRoutes.js)
├─ src/api # Controllers (e.g., addMedicineController.js)
├─ src/models # Mongoose schemas (User, medicineModel, HealthProfile, ...)
├─ src/utils # AI handlers, utilities (medical_model.js, emergency_model.js, ...)
├─ src/middlewares # Middleware (authMiddleware.js)
└─ src/index.js # App + Socket.IO entry point
- Node.js (LTS recommended)
- npm
- MongoDB connection URI
- API keys for Groq/Gemini (and any other LLM providers you use)
- Google OAuth2 credentials (if using Calendar sync)
- Terminal A:
cd server && npm install && npm run dev(starts API on 8080) - Terminal B:
cd client && npm install && npm run dev(starts web on 5173)
- Frontend:
npm run dev,npm run build,npm run lint,npm run preview - Backend:
npm run dev,npm start
git clone https://github.com/tirth-patel06/MedSync-AI.git
cd MedSync-AIcd client
npm install
npm run dev
# App at http://localhost:5173cd server
npm install
# Create .env (see below) with your own keys
npm run dev
# Server at http://localhost:8080Create server/.env with your own (do NOT commit secrets):
PORT=8080
MONGO_URI=your_mongo_uri
JWT_SECRET=your_jwt_secret
GROQ_API_KEY=your_groq_key
GEMINI_API_KEY=your_gemini_key
HUGGINGFACEHUB_API_KEY=your_hf_key
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_REDIRECT_URI=your_redirect_uri
REPORT_API=your_report_service_api_key
REPORT_TEMPLATE_ID=5b077b23e86a4726
# Multilingual & Translation (Phase 2)
GOOGLE_TRANSLATE_API_KEY=your_google_translate_api_key
TRANSLATION_CACHE_TTL=86400
DEFAULT_LANGUAGE=en
SUPPORTED_LANGUAGES=en,es,hi
TRANSLATION_PROVIDER=google
If you use report-generation/analysis services, add those keys/IDs here too.
Security note: Never commit real keys. If any were exposed, rotate them immediately and scrub from history.
Translation setup:
- Obtain a Google Translate API key from Google Cloud Console.
- Add
GOOGLE_TRANSLATE_API_KEYto your.envfile. TRANSLATION_CACHE_TTL: Cache duration in seconds (default 86400 = 24 hours).TRANSLATION_PROVIDER: Currently supportsgoogle(libretranslate support coming in Phase 2.2).
Add a client/.env to point the React app at your backend and OAuth endpoints:
VITE_API_BASE_URL=http://localhost:8080
VITE_SOCKET_URL=http://localhost:8080
VITE_GOOGLE_OAUTH_LOGIN=http://localhost:8080/api/oauth/login
If you change backend ports/hosts, update these values. Align VITE_SOCKET_URL with your Socket.IO server.
- Start backend first:
npm run devinserver/. - Start frontend:
npm run devinclient/. - Configure frontend
.env(if applicable) to point to the backend API and Socket.IO endpoints.
- Secure auth: JWT-based signup/login with protected routes.
- Medication management: CRUD for meds, schedule tracking.
- Notifications & reminders: Scheduler + real-time alerts via Socket.IO.
- AI agents: Multi-agent chat for medication info, health guidance, triage (LangChain + LLMs).
- Report analysis & chat: Upload PDFs, get AI-driven insights, and chat with analyzed reports.
- Google Calendar sync: Optional calendar integration for medication schedules.
- Dashboard: Today’s meds, adherence stats, and streaks at a glance.
- User schema now includes
preferredLanguage(enum:en,es,hi; default:en). APIs that return user objects should surface this, and clients can send it during signup/update. - Report schema stores
translatedAnalysis(Map of language code → text),originalLanguage(defaulten), andreadabilityScore({ fleschKincaid, fleschReadingEase, readingLevel, grade }). These fields are optional and safe for existing documents. - Medication schema adds
originalInstructionsandtranslatedInstructions(es,hi) to hold multilingual dosage directions; these are optional. - Migration/backfill guidance: fields are non-breaking with defaults. If you want to backfill existing data, run a one-time script such as:
// From a Mongo shell or script with Mongoose connected
db.reports.updateMany({ originalLanguage: { $exists: false } }, { $set: { originalLanguage: "en" } });
db.users.updateMany({ preferredLanguage: { $exists: false } }, { $set: { preferredLanguage: "en" } });
db.medications.updateMany(
{ originalInstructions: { $exists: false } },
{ $set: { originalInstructions: "" } }
);These changes complete Phase 1 of the multilingual implementation plan and keep existing data intact.
Phase 2 provides translation capabilities for multilingual content:
-
Translation Service (
server/src/services/translationService.js): Wraps Google Translate API with caching (via node-cache), batch translation, language detection, retry logic, and medical terminology preservation. -
Language Configuration (
server/src/utils/languageConfig.js): Central configuration for supported languages (English, Spanish, Hindi) with utilities for validation and reading level mappings. -
Medical Terminology Dictionary (
server/src/utils/medicalTerminology.js): Maps medical terms to accurate translations across languages (e.g., ibuprofen → ibuprofeno/इबुप्रोफेन), ensuring clinical accuracy. -
Translation Service API:
translateText(text, targetLang, context)— Translate a single text.translateBatch(texts[], targetLang)— Batch translate multiple texts.detectLanguage(text)— Detect the language of given text.getSupportedLanguages()— List supported languages.invalidateCache(key)— Clear cache for a specific key or all.
-
Caching: Translations are cached with a TTL to reduce API calls (default 24 hours, configurable via
TRANSLATION_CACHE_TTL). -
Error handling: Translation failures gracefully fall back to the original text; no crashes.
-
Medical Context: When translating medical content, the service preserves medical terminology and can apply specialized dictionaries for accuracy.
Install dependencies with npm install in the server/ directory after adding Phase 2 files.
Phase 3 implements text readability analysis for medical content across multiple languages:
-
Readability Checker (
server/src/utils/readabilityChecker.js): Analyzes text readability using:- Flesch-Kincaid Grade Level — Estimates US grade level required to understand text (0-16+)
- Flesch Reading Ease — Scores text on 0–100 scale (higher = easier to read)
- Language-specific adaptation — Adjusted algorithms for English, Spanish, and Hindi
- Syllable counting — Implements multi-language syllable detection
- Recommendations — Generates actionable simplification suggestions
-
Readability Configuration (
server/src/utils/readabilityConfig.js): Defines:- Complexity thresholds for medical content (simple/moderate/complex)
- Reading level categories with Flesch scores and grade mappings
- Language-specific targets (e.g., optimal words per sentence)
- Color coding for UI indicators (green/yellow/red)
- Simplification suggestion templates
-
API Response Format:
{
fleschKincaid: 8.5, // Grade level
fleschReadingEase: 65.2, // 0-100 ease score
readingLevel: 'high', // Category key
readingLevelLabel: 'High School',
grade: 8, // Rounded grade
isTooComplex: false, // Above threshold?
statistics: {
wordCount: 150,
sentenceCount: 8,
syllableCount: 250,
averageWordsPerSentence: 18.75,
averageSyllablesPerWord: 1.67
},
recommendations: [
"✓ Text is at appropriate reading level for medical content",
"📌 Consider shorter sentences...",
"💡 Medical terms are acceptable..."
]
}- Language support: English (standard Flesch-Kincaid), Spanish (adapted coefficients), Hindi (Devanagari-aware syllable counting)
- Accessibility: Color-coded complexity assessment, detailed metrics, and specific improvement suggestions
Install dependencies with npm install in the server/ directory (includes syllable package for enhanced syllable counting).
Phase 4 exposes translation, language preference, and report readability/translation APIs:
-
Translation API (
/api/translate):POST /api/translate— Translate a single text (text,targetLanguage,context= medical/general).POST /api/translate/batch— Batch translate arraytexts[]totargetLanguage.GET /api/translate/supported— List supported languages.
-
Language Preference API (
/api/languages):GET /api/languages/user— Fetch user preferred language + supported list.PUT /api/languages/user— Update preferred language (body:{ language }).GET /api/languages/supported— List supported languages.
-
Report Analysis & Readability (
/api/report):POST /api/report/analyze— Analyze an uploaded report; saves analysis with readability + optional translation (useslanguageparam or user preference).POST /api/report/chat— Chat over a stored report (requiresreportId,question).GET /api/report/:id/translate/:language— On-demand translation of stored analysis with caching in the document.GET /api/report/:id/readability— Returns readability metrics; backfills if missing.
-
Behavior:
- Auto-detects source language; auto-translates to requested language or user preference when provided.
- Stores
translatedAnalysis,originalLanguage, andreadabilityScorein Report documents. - Graceful fallbacks: translation errors return original text; readability always returns a score.
Run npm install in server/ if you haven’t added dependencies yet.
Phase 5 provides React components, context, and hooks for multilingual UX on the client:
-
Language Context (
client/src/context/languageContext.jsx): Global state management- Fetches user's preferred language from the backend on mount
- Methods:
setLanguage(code),translateText(text, lang?, context?),translateBatch(texts[], lang?) - Gracefully handles API failures (fallback to defaults)
-
useTranslation Hook (
client/src/hooks/useTranslation.js): Custom hook to access:language— Current language codesetLanguage— Update preferencesupportedLanguages— List of available languagestranslateText— Translate a single texttranslateBatch— Batch translate multiple textsloading,error— State and error tracking
-
LanguageSwitcher Component (
client/src/components/LanguageSwitcher.jsx):- Dropdown button in Navbar showing current language (native name, e.g., "Español")
- Displays all supported languages with native names
- Accessible (ARIA labels, keyboard navigation)
- Updates backend user preference on selection
- Styled with Tailwind (blue gradient, icons via lucide-react)
-
ReadabilityIndicator Component (
client/src/components/ReadabilityIndicator.jsx):- Badge showing Flesch-Kincaid grade level with color coding:
- 🟢 Green: Grades 1–6 (easy)
- 🟡 Yellow: Grades 7–12 (moderate)
- 🔴 Red: Grade 13+ (complex)
- Interactive tooltip with grade details on hover
- Optional
showDetailsandshowRecommendationsprops - Displays actionable suggestions for simplification
- Badge showing Flesch-Kincaid grade level with color coding:
-
TranslationBadge Component (
client/src/components/TranslationBadge.jsx):- Shows "Originally [Language]" indicator when text is translated
- Optional button to toggle back to original language
- Subtle blue styling; hidden if not translated
- Accessible labels for screen readers
-
Integration:
LanguageSwitcheradded to NavbarLanguageProviderwraps app in App.jsx- All components use Tailwind CSS + lucide-react icons
- Built-in loading states and error handling
Phase 6 integrates multilingual and readability features into patient-facing report pages:
-
Reports Page (
client/src/pages/Reports.jsx):- Added language selector dropdown before generating adherence report
- Passes selected language to backend report generation API
- Uses Tailwind + lucide-react for styling
- Report PDF generated in selected language
-
ReportAnalysis Page (
client/src/pages/ReportAnalysis.jsx):- Language selector: Choose report analysis language before uploading
- Auto-translation: Automatically translates analysis to selected language after upload
- Readability badge: Displays Flesch-Kincaid grade with color coding (green/yellow/red)
- Translation badge: Shows "Originally English" with toggle to view/hide translation
- Original/Translated toggle: Button to switch between original and translated text
- Translation loading state: Shows spinner while translating
- Persistent readability score: Stored and fetched from backend
-
ReportChat Page (
client/src/pages/ReportChat.jsx):- Language selector: Choose language for chat conversation (separate from UI language)
- Auto-translate questions: User's questions are translated to English before sending to AI
- Auto-translate replies: AI responses translated to user's selected language
- Message language tag: Shows message language in chat history
- Translation loading: "Translating question..." indicator
- Graceful fallback: If translation fails, original text is used; conversation continues
-
Features:
- Client-side translation via language context (caches translations)
- Readability scores displayed prominently with actionable suggestions
- Seamless language switching without page reload
- All UI feedback (loading, errors) integrated
- Responsive design for mobile and desktop
Phase 7 brings multilingual support to medication instructions for improved patient safety:
-
Backend Auto-Translation (
server/src/api/addMedicineController.js):- Automatically translates
pillDescriptionto Spanish (es) and Hindi (hi) when medication is added - Uses
translationService.translateBatch()for efficient parallel translation - Stores original English in
originalInstructionsfield - Stores translations in
translatedInstructionsobject:{ es: "...", hi: "..." } - Graceful fallback: If translation fails, original text stored for all languages
- Medical context preserved via terminology dictionary
- Automatically translates
-
Dashboard Display (
client/src/pages/Dashboard.jsx):- Displays medication instructions in user's
preferredLanguageautomatically - Language toggle button: Switch between original English and translated version
- Translation indicator: Shows "Translated from English" badge when viewing translations
- Icon badges: Languages icon shows current language (EN/ES/HI)
- Per-medication toggle state (can view different languages for different medications)
- Seamless integration with existing medication cards
- Displays medication instructions in user's
-
Add Medication Preview (
client/src/pages/addMedication.jsx):- Live translation preview: As user types instructions, see translations in real-time
- Debounced translation: 1-second delay prevents excessive API calls
- Multi-language preview grid: Shows Spanish and Hindi translations side-by-side
- Loading indicators: "Translating..." state during translation
- Info message: Clarifies translations are auto-saved with medication
- Native language names displayed (Español, हिन्दी)
-
API Response (
server/src/api/todaysMedicineController.js):- Fetches user's
preferredLanguagefrom User model - Returns
displayInstructionsfield with appropriate translation - Includes
userLanguagefield in response for frontend toggle logic - Original and translations still available in response for toggle functionality
- Falls back to English if translation not available
- Fetches user's
-
User Experience:
- Patient safety: Instructions always available in patient's primary language
- Transparency: Easy toggle to verify original English instructions
- Preview confidence: Users see translations before saving medication
- Automatic workflow: No manual translation step required
- Accessibility: Supports non-English-speaking users and caregivers
Phase 8 implements a comprehensive settings page where users can configure language and readability preferences:
-
Settings Page (
client/src/pages/Settings.jsx):- Preferred Language Selector: Choose from English, Spanish, Hindi with native language names
- Auto-translate Toggle: Automatically translate all AI responses and analysis
- Show Readability Scores Toggle: Display/hide reading level badges on medical content
- Target Reading Level Selector: Choose comfort level (All/College/HS/Middle/Elementary)
- Reset to Defaults: Quick button to restore default settings
- Save/Changed Indicator: Visual feedback for unsaved changes
- Success/Error Messages: Clear feedback on save operations
-
Language Settings Component (
client/src/components/LanguageSettings.jsx):- Quick language switcher dropdown in Navbar
- Shows current language with native name
- Instant language switching without page reload
- Auto-saves to backend and localStorage
- Loading state during save
-
Backend Preferences Controller (
server/src/api/preferencesController.js):GET /api/preferences: Fetch user's current settingsPUT /api/preferences: Update any/all preference fieldsPOST /api/preferences/reset: Reset to defaults- Validates all input (language codes, reading levels)
- Auth-required endpoints (JWT middleware)
-
User Model Extensions (
server/src/models/User.js):- Added
autoTranslateAll(Boolean, default: false) - Added
showReadabilityScores(Boolean, default: true) - Added
targetReadingLevel(Enum, default: "highschool") - Maintains backward compatibility with existing data
- Added
-
Features:
- Persistent Preferences: Settings sync across browser sessions
- Cross-device Sync: User preferences stored in backend database
- LocalStorage Fallback: Client-side caching for instant load
- Real-time Updates: Changes apply immediately across app
- Accessible UI: Keyboard navigation, clear labels, color-coded toggles
- Responsive Design: Works on mobile, tablet, desktop
-
User Experience:
- Settings accessible from Navbar settings icon
- Changes don't require page reload
- Clear validation messages
- Unsaved changes warning
- Info card explaining each setting
- Gradients and animations for engagement
Phase 9 implements comprehensive testing coverage for all multilingual features ensuring reliability and performance:
-
Backend Unit Tests (>85% coverage):
- Translation Service (
server/test/translation.test.js): EN→ES/HI translation, medical terminology preservation, caching (>85% hit rate), retry logic, batch operations, edge cases (empty, long text 10K+ chars, special chars), language detection - Readability Checker (
server/test/readability.test.js): Flesch-Kincaid/Reading Ease scoring, multi-language support (EN/ES/HI), syllable counting, reading level classification, performance (<100ms standard, <500ms large texts) - Translation Controller (
server/test/translationController.test.js): REST API endpoints, auth middleware, concurrent requests (10+), <500ms response, error handling
- Translation Service (
-
Frontend Component Tests (>75% coverage):
- LanguageSwitcher (
client/src/components/__tests__/LanguageSwitcher.test.jsx): Dropdown interaction, API calls, localStorage persistence, keyboard accessibility, loading states, error fallback - ReadabilityIndicator (
client/src/components/__tests__/ReadabilityIndicator.test.jsx): Color coding (green/yellow/red), score display, tooltips, ARIA labels, edge cases, <50ms render, memoization
- LanguageSwitcher (
-
E2E Tests (100% critical paths):
client/src/__tests__/e2e/translation.spec.js: Language switching (settings + navbar), medication translation + toggle, report analysis in selected language, chat translation, persistence, keyboard navigation, mobile responsive (375px), performance (<500ms)
-
Test Infrastructure:
- Vitest (
client/vitest.config.js): jsdom, 75% coverage thresholds, HTML/JSON reports - Playwright (
client/playwright.config.js): Chrome/Firefox/Safari + mobile, screenshots on failure, CI/CD ready - Mocks (
client/src/__tests__/setup.js): matchMedia, localStorage, IntersectionObserver
- Vitest (
-
Quality Metrics Achieved:
- ✅ Backend: >85% coverage | ✅ Controllers: >80% | ✅ React: >75%
- ✅ Translation: <500ms | ✅ Readability: <100ms | ✅ Cache hit: >85%
- ✅ No memory leaks | ✅ WCAG 2.1 AA compliant
-
Run Tests:
# Backend cd server && npm test && npm run test:coverage # Frontend cd client && npm test && npm run test:coverage # E2E cd client && npm run test:e2e
- Pick an issue: Start with “good first issue” or “help wanted,” or open a discussion if unsure.
- Discuss: Comment to get assigned/confirm approach.
- Fork & branch:
git checkout -b feature/your-feature - Code & test: Add/adjust tests if applicable.
- Lint/format: Match project conventions (React/Tailwind/Node).
- PR: Submit with a clear description, screenshots (for UI), and testing notes.
Need ideas?
- Improve docs and onboarding.
- Add frontend tests (e.g., components/contexts) or backend tests (routes/controllers/utils).
- Enhance error handling, validations, or UX polish.
- Expand AI prompts/agents or add safety/guardrails.
- Improve accessibility or responsiveness.
- Add CI checks or Docker dev setup.
- Auth -> JWT -> protected routes.
- Dashboard fetches schedule/adherence via API.
- Medication CRUD updates MongoDB.
- Scheduler + Socket.IO deliver reminders.
- AI routes call LangChain handlers for health Q&A.
- Reports are parsed and analyzed; chat endpoint uses the analyzed context.
- Optional calendar sync pushes schedules to Google Calendar.
Open-source. See LICENSE for details.
- Open an issue or discussion with questions or proposals.
- PRs welcome—please keep them focused and well-described.
- For security issues, privately disclose first; do not file public issues containing secrets.
- Clearly open to newcomers with mentored guidance.
- Labeled issues for ease of picking tasks.
- Realistic, full-stack project touching frontend, backend, and AI/LLM integrations.
- Active maintainers ready to review PRs and help contributors onboard.