Build with patient care in mind, SymptomSync is a web application designed to help users manage their health and wellness. It provides a comprehensive dashboard for tracking medications, appointments, and health logs, all while ensuring real-time synchronization across devices. With features like medication reminders, appointment tracking, and an AI-powered chatbot, SymptomSync empowers users to take smarter control of their health journey and live healthier lives πͺ.
Note
Developed by David Nguyen and Erica Ocbu at UNCβChapel Hill. Β© SymptomSync Team, 2025.
[!IMPORTANT] > Live Web App: https://symptomsync.vercel.app π
- SymptomSync UI
- Features
- Tech Stack
- Architecture Overview
- Installation
- Configuration
- Supabase Schema
- Usage
- Agentic AI
- Video Demo
- High-Fidelity Prototype
- AWS & Ansible Deployment
- GitHub Actions CI/CD
- Testing
- Contributing
- Authors
- License
- Acknowledgements
The UI of the app was designed with Figma and Tailwind CSS. The design is responsive and mobile-first, ensuring a seamless experience across devices. Below are some screenshots of the app in action:
... and so many more! Explore our app to see the full range of features and functionality.
Important
Link to Figma prototype: SymptomSync Figma Prototype
SymptomSync offers a range of features to help users manage their health effectively:
- Medication Reminders: Schedule, edit, and delete recurring or oneβoff med alerts.
- QR/Barcode Scanning: Scan medication QR codes to auto-fill details. This can save time and reduce errors when entering medication information!
- Appointment Tracking: Log upcoming appointments with date/time and manage them.
- Health Logs: Record symptoms, mood, vitals, and notes; visualize trends over time.
- Dashboard Visualizations: Interactive charts for severity trends, symptom & mood distribution, and more.
- RealβTime Updates: Broadcast channel notifications and Supabase Realtime keep all devices in sync instantly.
- Pagination: Efficient paginated fetching for large datasets (meds, appts, logs).
- Notifications: In-app reminders for due medications and appointments.
- ICS Export/Import: Export all events as an ICS calendar file or import from external calendars.
- Calendar View: Month/week/day/agenda views for all events, with drag-and-drop support.
- Documents Page: Upload/export and manage documents related to health records, prescriptions, etc.
- Chatbot: AI-powered chatbot for symptom analysis and health insights.
- Chatbot Actions: The chatbot can now perform actions like fetching user data, scheduling reminders, and providing health tips based on user input on the user's behalf.
- User Profiles: Create and manage user profiles with personalized settings.
- Medication Schedules: Set up complex medication schedules with reminders.
- Login/Signup: Secure authentication via Supabase Auth.
- Reset Password: Password reset functionality for user accounts.
- Dark Mode: Toggle between light and dark themes for better accessibility.
- Responsive Design: Mobile-first design with a focus on usability across devices.
- Front-End
- Next.js & React (TypeScript)
- Tailwind CSS & Shadcn/ui components
- Framer Motion for animations
- react-chartjs-2 & Chart.js for charts
- react-query for data fetching & caching
- react-calendar for calendar view
- lucide-icons for icons
- Back-End / Data
- Supabase (Auth, Postgres, Realtime, Storage, Cron)
- Notifications & Sync
- Supabase Postgres Triggers for real-time updates
- Supabase Cron Jobs for scheduled reminders
- Supabase Broadcast Channels &
postgres_changesfor live updates & notifications
The diagrams below summarize how SymptomSync is assembled across the client, data services, and deployment workflows. A much deeper dive (with additional sequence and ER diagrams) lives in ARCHITECTURE.md.
flowchart TD
subgraph Client["Next.js Frontend"]
UI["UI Layer\nReact + Tailwind + shadcn/ui"]
Data["State & Data Layer\nReact Query + Supabase SDK"]
end
subgraph Supabase["Supabase Platform"]
Auth["Auth"]
DB["Postgres + RLS"]
Storage["Storage Buckets"]
Realtime["Realtime Channels"]
Cron["pg_cron Jobs"]
Functions["Stored Procedures"]
end
subgraph Integrations["External Services"]
GoogleAI["Google AI\n(Generative API)"]
end
UI -->|"Forms, Charts, Calendar"| Data
Data -->|"Auth, REST & RPC"| Auth
Data -->|"CRUD & analytics"| DB
Data -->|"File uploads"| Storage
DB -->|"Broadcast changes"| Realtime
Cron -->|"invoke notify_due_reminders()"| DB
Data -->|"Live subscription"| Realtime
Data -->|"Symptom prompts"| GoogleAI
flowchart LR
Dev["Developer"] -->|"push / PR"| GitHub["GitHub Repository"]
GitHub -->|"CI trigger"| Actions["GitHub Actions Pipeline"]
Actions -->|"lint & test"| Quality["Quality Gates"]
Actions -->|"next build"| Artifact["Next.js Build Artifacts"]
Actions -->|"docker build"| GHCR["GitHub Container Registry"]
Actions -->|"Ansible + CDK"| AWS["AWS Deployment (optional)"]
Actions -->|"Deploy"| Vercel["Vercel Hosting"]
AWS -->|"REST + Cron"| ClientStack["Serverless API & Reminders"]
SupabaseSvc["Supabase Cloud"] -->|"Auth, DB, Realtime"| ClientStack
Vercel -->|"serve UI"| Users["End Users"]
- Supabase: The backend is powered by Supabase, which provides a Postgres database, authentication, and real-time capabilities.
- Each table is protected by Row Level Security (RLS) policies to ensure user data isolation, so that users can only access/update/delete their own data.
- Realtime Broadcast: Any create/update/delete triggers both a
postgres_changessubscription and a broadcast message so all open clients show a toast notification. - Cron Jobs: Scheduled jobs (via Supabase Cron) that scan upcoming reminders and dispatch notifications every second.
[!CAUTION] If the window loses focus, or when you have a slow connection, the reminder notifications may not show up. Also, the cron jobs are not guaranteed to run at the exact time specified, but they will run within a few seconds of the scheduled time.
- Postgres Triggers: Database triggers that listen for changes in the
medication_reminders,appointment_reminders, andhealth_logstables, and send messages to the broadcast channel.- There is also a trigger on the
auth.userstable to create a correspondinguser_profilesentry when a new user signs up.
- There is also a trigger on the
- AI Chatbot: The chatbot uses the Google AI API to analyze user symptoms and provide health insights.
-
Clone the repo
git clone https://github.com/hoangsonww/SymptomSync-Health-App.git cd SymptomSync-Health-App -
Open the project in your favorite code editor (e.g., VSCode). When prompted by your IDE, select "Open in Container" to open the project in a Docker container. Alternatively, if using VSCode, you can use the Remote - Containers extension to open the project in a container.
[!CAUTION] This is very important as the project uses Docker to run the database and other services. If you don't have Docker installed, please install it first.
-
Install dependencies (Remember to use
--legacy-peer-depsif you encounter issues with React versions being incompatible with Shadcn/ui)npm install --legacy-peer-deps
-
Copy
.env.exampleβ.env.localand fill in your Supabase credentialsNEXT_PUBLIC_SUPABASE_URL=β¦ NEXT_PUBLIC_SUPABASE_ANON_KEY=β¦ NEXT_PUBLIC_GOOGLE_AI_API_KEY=β¦
-
Run the dev server
npm run dev
-
Supabase
- Configure Auth settings in the Supabase dashboard
- Enable email/password signups
- Uncheck the confirmation email option for now
- Create tables:
user_profiles,medication_reminders,appointment_reminders,health_logs,files, anduser_notificationsand enable Realtime for all of them.- Set relationships between tables using Foreign Keys.
- Add RLS policies for user isolation to the tables. All tables should have the following policies or similar:
select:auth.uid() = user_profile_idinsert:auth.uid() = user_profile_idupdate:auth.uid() = user_profile_iddelete:auth.uid() = user_profile_id
- Set up Cron jobs to run
send_reminders()stored procedure daily/hourly or even every second.- To do so, you might need to enable the
pg_cronextension in your Supabase project.
- To do so, you might need to enable the
- Create Postgres Functions to handle the logic for sending notifications and reminders
send_reminders(): Check for upcoming reminders and send notificationscreate_user_profile(): Create a new user profile when a user signs up
- Define Database Triggers to write to broadcast channels on insert/update/delete and to create a new user profile on signup
- Set up Storage for file uploads. Create 2 buckets:
avatarsanddocuments
- Configure Auth settings in the Supabase dashboard
-
Environment
.env.localholds all keys (refer to.env.example)- Default port:
3000
SymptomSync uses the following tables in Supabase:
user_profilesmedication_remindersappointment_remindershealth_logsfilesuser_notificationsauth.users(Supabase Auth table)auth.refresh_tokens(Supabase Auth table)auth.user_attributes(Supabase Auth table)auth.user_mfa(Supabase Auth table)- and more...
These tables are used to store user profiles, medication reminders, appointment reminders, health logs, uploaded files, and user notifications. The schema is designed to ensure data integrity and security through Row Level Security (RLS) policies.
Below is a diagram of the Supabase schema used in SymptomSync:
- Sign up / log in via Supabase Auth.
- On the Home dashboard, add new medications, appointments, or health logs.
- View interactive charts - severity trends, symptom distribution, appointment patterns.
- Navigate to Calendar to see a month/week/day/agenda view of all events, add events, or even import/export ICS.
- All changes sync in realβtime across open tabs/devices; cronβdriven reminders notify you via in-app notifications.
- Use the Documents page to upload/export health records, prescriptions, etc.
- Chat with the AI Chatbot for symptom analysis and health insights.
- Toggle between light and dark mode for better accessibility.
- View and manage your profile. You can also view other users' profiles.
- Visit the Medication Schedules page to view/edit a complete list of your medications and their schedules.
SymptomSync incorporates Agentic AI to enhance user experience and provide personalized health insights. The AI analyzes user data, identifies patterns, and offers tailored recommendations for medication management, appointment scheduling, and health tracking.
- Symptom Analysis: The AI chatbot can analyze user-reported symptoms and provide insights based on medical knowledge.
- Personalized Reminders: The AI can suggest optimal times for medication reminders based on user routines and habits.
- Health Trend Predictions: By analyzing health logs, the AI can predict potential health trends and alert users to take preventive actions.
- Natural Language Processing: The AI chatbot uses NLP to understand user queries and provide relevant responses in a conversational manner.
For more details on how Agentic AI is integrated into SymptomSync, refer to the AI Integration Documentation.
Check out our demo video showcasing the app's features and functionality: Link to Demo Video
Tip
This video might not be comprehensive and cover all features of our app - so please feel free to give our live app at symptomsync.vercel.app a try to test out all the features!
Link to Figma prototype: SymptomSync Figma Prototype
Our high-fidelity prototype showcases the app's design and user experience. You can interact with the prototype to get a feel for how the app works.
SymptomSync now fully supports Amazon Web Services (AWS) deployment alongside Vercel if you choose to host your own instance on AWS! Its deployment infra is defined in the aws/ folder (AWS CDK in JavaScript) and can be deployed via the Ansible playbooks in ansible/. This setup provisions Cognito, DynamoDB, S3, Lambdas, API Gateway, a scheduled EventBridge rule, and now includes CodeDeploy canaries plus blue/green stages for safe rollouts and canary deployments for dual-instance traffic shifting.
Tip
Blue/green deployments: This strategy uses two identical environments (blue and green). One environment (e.g., blue) serves all production traffic while the other (green) is idle. When deploying a new version, it is first deployed to the idle environment (green). After testing, traffic is switched from blue to green. This allows for quick rollbacks by switching back to the previous environment if issues arise.
Canary deployments: This strategy gradually shifts traffic to the new version in small increments (e.g., 10% every 5 minutes) while monitoring for errors. If no issues are detected, the deployment continues until all traffic is on the new version. If problems occur, the deployment can be automatically rolled back to the previous stable version.
.
βββ aws/ # CDK v2 stack (JavaScript)
β βββ bin/
β βββ lib/
β βββ lambda/
β βββ package.json
β βββ cdk.json
β βββ .gitignore
βββ ansible/ # Ansible deployment playbook
βββ ansible.cfg
βββ inventory.ini
βββ deploy-infrastructure.yml
- Bootstrap & Deploy
cd aws
npm install
cdk bootstrap
cdk deploy --require-approval never-
Whatβs created
- Cognito User Pool & App Client
- DynamoDB tables for profiles, meds, appts, logs, notifications
- S3 buckets (
avatars,documents) with encryption, no public access, retained by default - Lambda functions: REST API, reminder processor, chatbot, presigned-URL, each fronted by a
livealias with CodeDeployCANARY_10PERCENT_5MINUTESrollback - API Gateway (REST) + Cognito authorizer + explicit
blue/greenstages exported as stack outputs,/healthendpoint for smoke checks - WAF + Alarms managed rules and rate limit on API Gateway; per-stage CloudWatch alarms for 5XX and p95 latency
- SSM Parameter
/symptomsync/active_stageto flip traffic between blue/green (via DNS/base-path) - EventBridge rule to run reminders every minute pinned to the
livealias
-
Run the playbook
cd ansible ansible-playbook deploy-infrastructure.yml -
What it does
- Installs Node.js, AWS CLI, AWS CDK on the host
- Verifies your
GOOGLE_AI_API_KEYenv var - Bootstraps CDK in your AWS account
- Deploys the entire SymptomSync stack non-interactively
- (Optional) Run
ansible/blue-green-rollout.ymlto smoke test the inactive stage and update/symptomsync/active_stageafter a deploy
Ensure your AWS credentials (via AWS_PROFILE or AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY) and GOOGLE_AI_API_KEY are set in your environment before running.
We have set up GitHub Actions for continuous integration and deployment. The workflow runs on every push to the main branch and performs the following steps:
- Installs dependencies
- Runs tests
- Builds the application
- Deploys to Vercel
- Deploys the AWS stack using the Ansible playbook
- Notifies the team on success/failure
For more details, check out the .github/workflows/ci.yml file in the repository.
We have implemented unit tests using Jest to ensure the reliability of our application. The tests cover various components and functionalities, including:
- User authentication
- Data fetching and state management
- API integration
- UI components
To run the tests, use the following command in the web directory:
npm run test- Fork & branch:
git checkout -b feature/awesome - Develop something awesome
- Install & format:
npm install && npm run format - Commit & PR with description
- Wait for review and merge
A big thank you to our team members for their hard work and dedication:
MIT License - Feel free to use, modify, and distribute this code as you wish. Contributions are welcome!
Please ensure to follow the Contributing Guidelines if you wish to contribute to this project.
We would like to acknowledge the following resources and libraries that made this project possible:
- Next.js for the React framework
- Supabase for the backend services
- Tailwind CSS for the styling framework
- Shadcn/ui for the UI components
- Framer Motion for the animations
- Chart.js for the data visualizations
- Google AI for the AI-powered chatbot
- Docker for containerization
- Ansible for deployment automation
- AWS CDK for infrastructure as code
- Figma for the design and prototyping
- Postman for API testing
- Jest for testing
- ESLint for code linting
- Prettier for code formatting
- and many more!
For any questions, feedback, or contributions, feel free to open an issue here or reach out to us via GitHub Discussions. We appreciate your interest in SymptomSync and look forward to hearing from you!
Thank you for checking out SymptomSync! We hope it helps you manage your health and wellness effectively. If you have any questions or feedback, feel free to reach out! π











