# Project export: SquadPulse

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: TreeHacks 2025
- Tagline: Squad health monitoring using PPG waves & fitness metadata. Detect trends, assess readiness, and get real-time alerts for cardiac risks - enhancing team safety & performance.
- Devpost: https://devpost.com/software/squadpulse
- GitHub: https://github.com/jathinsn27/Squad_pulse
- Video: https://www.youtube.com/embed/KDLdjrOo854?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 3 GitHub contributor(s) — anantasingh (19 commits), jathin sn (3 commits), Shivankthakur (2 commits)

## Devpost submission (written by the team)

### Inspiration

In high-stake environments like military operations, emergency response teams, and extreme sports, health monitoring is not just a luxury it’s a necessity. SquadPulse aims to empower teams with real-time medical insights using PPG waveforms and metadata, ensuring mission readiness and proactive health management. By extracting key biomarkers like heart rate (HR), heart rate variability (HRV), and SpO₂ levels, SquadPulse can detect early signs of fatigue, stress, dehydration, and cardiovascular risks. AI-powered trend analysis enhances decision-making, allowing squads to respond before minor issues become critical. With SquadPulse, we’re not just tracking health; we’re building a resilient, high-performance future where every heartbeat counts.

### What it does

In today’s world, preventive healthcare is more important than ever. Fitness tracking has evolved beyond counting steps and it’s about understanding the body’s signals and making informed health decisions. By integrating PPG-based biometrics, AI-driven insights, and personalized health analytics, modern fitness tracking can go beyond generic recommendations to adaptive wellness solutions. Whether it’s detecting early arrhythmias, monitoring recovery patterns, or personalizing training regimens, the future of fitness is precision-driven and data-backed. From elite athletes to everyday users, real-time health tracking bridges the gap between fitness and medicine, ensuring that everyone can train smarter, recover better, and live healthier. 🚀 The future of health tracking isn’t just about numbers. It’s about unlocking human potential.

### How we built it

We started by diving deep into the healthcare and fitness monitoring space, making sure we could truly understand the data we were working with. Using the Terra API, we gained access to critical biometric data, like PPG waveforms, and explored advanced techniques to extract meaningful insights. This allowed us to focus on important biomarkers such as heart rate, heart rate variability, and SpO₂. By training AI models to recognize patterns in the data, we were able to catch signs of fatigue, stress, or potential cardiovascular issues early, helping keep squad members healthy and ready. We also made sure to track trends over time, so we could make proactive decisions about fitness and well-being. For the real-time analysis, we built an intuitive front-end dashboard with React.js to ensure that both squad members and healthcare professionals could easily interact with the system. On the back end, Python Flask helped us process the data quickly and efficiently, so the flow of information was seamless. We optimized our algorithms to handle large datasets without delays, ensuring that actionable insights were delivered in real time during training or missions. We also designed the system to be scalable, so it could be used in various environments, from field operations to high-performance sports. By combining cutting-edge AI, real-time processing, and a user-friendly interface, SquadPulse became a versatile tool to help teams stay healthy, safe, and mission-ready.

### Challenges we ran into

One of the biggest challenges we faced was ensuring the accuracy of the biometric data, especially from the PPG waveforms. These signals can be noisy and prone to fluctuations, which made extracting reliable heart rate (HR), heart rate variability (HRV), and SpO₂ measurements difficult. To address this, we had to develop and fine-tune advanced filtering algorithms to ensure that we could accurately detect the key biomarkers. Additionally, synchronizing data streams from different sources like PPG signals, accelerometer data, and metadata was complex. Aligning these signals in real-time was crucial for providing accurate insights, and this required robust data integration techniques to ensure a seamless and synchronized experience. Another significant challenge was adapting our AI models to handle the wide variety of physiological states in high-performance environments. The factors affecting health can vary greatly, such as fatigue, stress, or environmental conditions like temperature or altitude. This made it difficult to create machine learning models that could reliably detect early signs of health issues across different conditions. Real-time data analysis was another hurdle, as we needed to ensure that the system could provide fast insights without compromising accuracy. This required optimizing our algorithms for speed, streamlining data processing pipelines, and refining the system to handle large volumes of data efficiently. Gaining domain knowledge in health monitoring was also a learning curve, as we had to consult with healthcare professionals and experts to ensure that the insights we provided were both actionable and medically sound.

### Accomplishments we're proud of

We’re incredibly proud of the proof-of-concept we’ve developed with SquadPulse, successfully integrating cutting-edge technology with real-time health monitoring for high-performance environments. Our system can detect key biomarkers such as heart rate (HR), heart rate variability (HRV), and SpO₂ from PPG waveforms, providing actionable insights that help individuals proactively manage health risks. The AI-powered trend analysis we implemented effectively identifies early signs of fatigue, stress, and cardiovascular issues, enabling smarter decision-making. We’ve also built a seamless, scalable system by combining AI models, a responsive React.js front-end, and a Python Flask back-end, ensuring real-time data analysis and intuitive visualization. This accomplishment reflects not only technical innovation but also our commitment to addressing real-world health challenges, making SquadPulse a valuable tool for squads, athletes, and healthcare professionals.

### What we learned

Building SquadPulse taught us the importance of data preprocessing and synchronization, particularly with noisy PPG signals and aligning multiple data streams like accelerometer and metadata. We gained technical expertise in developing efficient algorithms for real-time health monitoring and learned the crucial role of context in interpreting health data. Understanding variables like fatigue, environmental conditions, and stress response was key to enhancing our AI models. Additionally, collaborating with healthcare professionals and fitness experts broadened our knowledge of health monitoring in high-stakes environments. This experience helped us refine our system to provide medically relevant insights, ensuring our technology is not only accurate but also practical for real-world health management in demanding situations.

### What's next

Our next steps focus on enhancing the accuracy and adaptability of our AI models, particularly in detecting early-stage health issues like arrhythmias, dehydration, or stress, while providing more personalized insights based on individual health profiles. We plan to refine our algorithms and leverage additional data to improve the system’s ability to respond to complex, real-world health scenarios. Additionally, we aim to incorporate real-time alerts to notify users and teams of critical health conditions as soon as they arise. Looking further ahead, we aim to integrate SquadPulse with additional features like personalized nutrition plans and adaptive fitness regimens, as well as develop early-warning systems for cardiovascular health. By expanding the system’s capabilities and minimizing latency, we plan to integrate SquadPulse with wearable devices and other health tracking platforms to create a seamless, all-in-one solution. Ultimately, we aim to empower individuals and teams to proactively manage their health and performance, making SquadPulse an indispensable tool for high-performance environments.

## README (from the GitHub repository)

# SquadPulse - Military Health Monitoring System

## Overview

SquadPulse is a comprehensive health monitoring system designed specifically for military personnel. It provides real-time health analytics and squad performance monitoring to ensure optimal readiness and well-being of military units.

## Features

### For Squad Commanders (Admin)
- **Squad Overview Dashboard**
  - Real-time health metrics visualization
  - Squad performance analytics
  - Alert system for health anomalies
  - Interactive data graphs

### For Individual Soldiers (Users)
- **Personal Health Dashboard**
  - Heart rate monitoring
  - Sleep quality tracking
  - Activity level measurement
  - Health status indicators

### Key Functionalities
- Real-time health monitoring
- Squad-wide analytics
- Early warning system for health risks
- Performance tracking
- Sleep pattern analysis
- Activity level monitoring

## Technology Stack

- **Frontend**
  - React.js
  - Redux for state management
  - Chart.js for data visualization
  - CSS3 for styling

- **Dependencies**
  ```json
  {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.x",
    "react-chartjs-2": "^5.x",
    "redux": "^4.x",
    "react-redux": "^8.x"
  }
  ```

## Installation

1. Clone the repository
   ```bash
   git clone https://github.com/yourusername/squadpulse.git
   ```

2. Install dependencies
   ```bash
   cd squadpulse
   npm install
   ```

3. Start the development server
   ```bash
   npm start
   ```

## Project Structure

squadpulse/
├── src/
│ ├── components/
│ │ ├── admin/
│ │ │ └── graphs/
│ │ ├── user/
│ │ │ └── dashboard/
│ │ └── sidebar/
│ ├── store/
│ │ └── actions/
│ ├── assets/
│ └── App.js
├── public/
└── package.json

## Usage

### Admin Dashboard
1. Access the admin panel through `/admin/graphs`
2. View squad-wide health metrics
3. Monitor individual soldier performance
4. Receive alerts for health anomalies

### User Dashboard
1. Access personal dashboard through `/dashboard`
2. View personal health metrics
3. Track daily activity
4. Monitor sleep patterns

## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

## Acknowledgments

- Chart.js for data visualization
- React team for the amazing framework
- Military health monitoring standards and guidelines


## Future Enhancements

- Enhanced alert system


## Detected evidence (automated analysis)

Indexed codebase: 31 recognized source files, 59 KB.
- CSS (language) — detected in the code
- Flask (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code

## Codebase structure (from repository index)

### Files (39 of 39)

```
.gitignore
EDA/soldier_health.ipynb
EDA/Terra_PPG1.ipynb
package.json
public/index.html
public/manifest.json
public/robots.txt
README.md
server/chroma_db/chroma.sqlite3
server/main.py
server/requirements.txt
src/App.css
src/App.js
src/components/admin/graphs/Graph.css
src/components/admin/graphs/Graphs.js
src/components/admin/graphs/SleepDetails.css
src/components/admin/graphs/SleepDetails.js
src/components/admin/graphs/SquadDetails.css
src/components/admin/graphs/SquadDetails.js
src/components/common/Header.css
src/components/common/Header.js
src/components/Dashboard.css
src/components/Dashboard.js
src/components/layout/Layout.css
src/components/layout/Layout.js
src/components/layout/UserLayout.js
src/components/sidebar/Sidebar.css
src/components/sidebar/Sidebar.js
src/components/sidebar/UserSidebar.js
src/components/user/dashboard/Dashboard.css
src/components/user/dashboard/Dashboard.js
src/index.css
src/index.js
src/store/actions/squadActions.js
src/store/index.js
src/store/reducers/squadReducer.js
src/store/sagas/squadSaga.js
src/store/transformData.js
src/styles/global.css
```

### Dependencies

- package.json: @testing-library/dom@^10.4.0, @testing-library/jest-dom@^6.6.3, @testing-library/react@^16.2.0, @testing-library/user-event@^13.5.0, axios@^1.7.9, chart.js@^4.4.7, react@^19.0.0, react-chartjs-2@^5.3.0, react-dom@^19.0.0, react-icons@^5.4.0, react-redux@^9.2.0, react-router-dom@^7.1.5, react-scripts@5.0.1, redux@^5.0.1, redux-saga@^1.3.0, web-vitals@^2.1.4
- server/requirements.txt: chromadb, flask, flask-cors, terra-python

### Recent commits (newest first)

- Add Google Colab Notebook
- ngrok url
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Header
- side bars updated
- user dashbaord
- added data from terra
- Merge pull request #1 from jathinsn27/backend
- add db
- add files
- added draft profile icon
- added user dashboard
- Added api code not working completely
- Added the average healthy headings and corrected scroll
- Step Count Added
- One Component Only
- Added Sleep Details

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

### package.json

```
{
  "name": "dashboard",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/dom": "^10.4.0",
    "@testing-library/jest-dom": "^6.6.3",
    "@testing-library/react": "^16.2.0",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^1.7.9",
    "chart.js": "^4.4.7",
    "react": "^19.0.0",
    "react-chartjs-2": "^5.3.0",
    "react-dom": "^19.0.0",
    "react-icons": "^5.4.0",
    "react-redux": "^9.2.0",
    "react-router-dom": "^7.1.5",
    "react-scripts": "5.0.1",
    "redux": "^5.0.1",
    "redux-saga": "^1.3.0",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

```

### server/requirements.txt

```
flask
terra-python
chromadb
flask-cors
```

### src/index.js

```javascript
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';

const root = createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);
```

### src/App.js

```javascript
import React from 'react';
import './App.css';
import './styles/global.css';
// import Sidebar from './components/sidebar/Sidebar';
// import Dashboard from './components/Dashboard';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Layout from './components/layout/Layout';
import Graphs from './components/admin/graphs/Graphs';
import Dashboard from './components/user/dashboard/Dashboard';
import UserLayout from './components/layout/UserLayout';

// function App() {
//    return (
//      <Router>
//       <Layout>
//        <Routes>
//          <Route path="/admin/graphs" element={<Graphs />} />
//          <Route path="/user/dashboard" element={<Dashboard />} /> 
//        </Routes>
//        </Layout>
//      </Router> 
//    );
//  }

 function App() {
  return (
    <Router>
      <Routes>
        {/* Admin routes with Admin Layout */}
        <Route element={<Layout />}>
          <Route path="/admin/graphs" element={<Graphs />} />
        </Route>

        {/* User routes with User Layout */}
        <Route element={<UserLayout />}>
          <Route path="/user/dashboard" element={<Dashboard />} />
        </Route>
      </Routes>
    </Router>
  );
}

export default App; 
```

### server/main.py

```python
import logging
from flask import Flask, request, jsonify
from flask_cors import CORS
import chromadb
import json
from datetime import datetime
from typing import Dict, Any

# Initialize Flask app
app = Flask(__name__)
CORS(app)  # Enable CORS for all routes

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Initialize ChromaDB
chroma_client = chromadb.PersistentClient(path="db")

# Create or get collection
collection = chroma_client.get_or_create_collection(
    name="health_data"
)

def load_json_file(filename: str) -> Dict[str, Any]:
    with open(filename, 'r') as f:
        return json.load(f)

@app.route("/process_health_data", methods=["POST"])
def process_health_data():
    try:
        # Load the filtered JSON file
        data = load_json_file('filtered_health_data.json')
        user_id = data.get('user_id', 'unknown')
        
        # Check if user data already exists
        existing_data = collection.get(
            ids=[user_id],
            include=['metadatas']
        )
        
        if existing_data and existing_data['metadatas']:
            logger.error(f"Data already exists for user_id={user_id}")
            return jsonify({
                "error": f"User {user_id} already exists in the database. Cannot add duplicate data."
            }), 409  # 409 Conflict status code
        
        # Prepare metadata with default values
        metadata = {
            "user_id": user_id,
            "timestamp": data.get('timestamp', datetime.utcnow().isoformat()),
            "avg_heart_rate": data.get('heart_rate', {}).get('avg_bpm', 0.0),
            "max_heart_rate": data.get('heart_rate', {}).get('max_bpm', 0.0),
            "min_heart_rate": data.get('heart_rate', {}).get('min_bpm', 0.0),
            "avg_oxygen_saturation": data.get('oxygen', {}).get('avg_saturation', 0.0),
            "total_steps": data.get('steps', {}).get('total_steps', 0),
            "distance_meters": data.get('steps', {}).get('distance_meters', 0.0),
            "sleep_efficiency": data.get('sleep', {}).get('efficiency', 0.0),
            "total_sleep_seconds": data.get('sleep', {}).get('total_sleep_seconds', 0.0),
            "deep_sleep_seconds": data.get('sleep', {}).get('deep_sleep_seconds', 0.0),
            "light_sleep_seconds": data.get('sleep', {}).get('light_sleep_seconds', 0.0),
            "rem_sleep_seconds": data.get('sleep', {}).get('rem_sleep_seconds', 0.0)
        }
        
        # Add new data only if user doesn't exist
        collection.add(
            ids=[user_id],
            metadatas=[metadata],
            documents=[json.dumps(data)]
        )
        
        logger.info(f"Stored new health data for user_id={user_id}")
        return jsonify({
            "message": "Health data stored successfully",
            "data": metadata
        })
        
    except Exception as e:
        logger.error(f"Error processing health data: {str(e)}")
        return jsonify({"error": str(e)}), 500

@app.route("/health_data/<user_id>", methods=["GET"])
def get_health_data(user_id: str):
    try:
        results = collection.get(
            ids=[user_id],
            include=['metadatas']
        )
        
        if results and results['metadatas']:
            return jsonify(results['metadatas'][0])
        else:
            return jsonify({"error": "No health data found for this user"}), 404
            
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route("/health_data/batch", methods=["GET"])
def get_batch_health_data():
    try:
        limit = request.args.get('limit', default=20, type=int)
        
        results = collection.get(
            include=['metadatas'],
            limit=limit
        )
        
        if results and results['metadatas']:
            return jsonify({
                "count": len(results['metadatas']),
                "data": results['metadatas']
            })
        else:
            return jsonify({"error": "No health data found"}), 404
            
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route("/health_data/clear", methods=["POST"])
def clear_health_data():
    try:
        # Delete the existing collection
        chroma_client.delete_collection(name="health_data")
        
        # Recreate the collection
        global collection
        collection = chroma_client.create_collection(name="health_data")
        
        logger.info("Successfully cleared all health data")
        return jsonify({"message": "All health data cleared successfully"})
            
    except Exception as e:
        logger.error(f"Error clearing health data: {str(e)}")
        return jsonify({"error": str(e)}), 500

@app.route("/health_data/latest", methods=["GET"])
def get_latest_health_data():
    try:
        # Get the limit from query params, default to 20
        limit = int(request.args.get('limit', 20))
        
        # Query the collection with limit
        result = collection.get(
            limit=limit,
            include=['documents', 'metadatas']
        )
        
        if not result['ids']:
            return jsonify({"message": "No records found"}), 404
            
        # Create list of results with timestamps for sorting
        results = []
        for i in range(len(result['ids'])):
            results.append({
                "user_id": result['ids'][i],
                "metadata": result['metadatas'][i],
                "data": json.loads(result['documents'][i]),
                "timestamp": result['metadatas'][i].get('timestamp', '')
            })
        
        # Sort results by timestamp in descending order
        results.sort(key=lambda x: x['timestamp'], reverse=True)
            
        # Return all matching results
        return jsonify({
            "count": len(results),
            "results": results
        })
        
    except Exception as e:
        logger.error(f"Error retrievi
[truncated — 2442 more characters]
```

### src/store/index.js

```javascript
import { createStore, applyMiddleware, combineReducers } from 'redux';
import createSagaMiddleware from 'redux-saga';
import { all } from 'redux-saga/effects';
import squadReducer from './reducers/squadReducer';
import { watchFetchSquads } from './sagas/squadSaga';

const rootReducer = combineReducers({
  squads: squadReducer
});

function* rootSaga() {
  yield all([
    watchFetchSquads()
  ]);
}

const sagaMiddleware = createSagaMiddleware();

const store = createStore(
  rootReducer,
  applyMiddleware(sagaMiddleware)
);

sagaMiddleware.run(rootSaga);

export default store;
```

### src/App.css

```css
.app {
  display: flex;
  min-height: 100vh;
  background-color: #f5f6fa;
}

.main-content {
  flex: 1;
  min-height: 100vh;
} 
```

### src/index.css

```css
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
} 
```

### public/index.html

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

```

### src/styles/global.css

```css
.layout {
  display: flex;
  min-height: 100vh;
}

.main-content {
  flex: 1;
  margin-left: 80px; /* Reduced from 250px to 80px - adjust based on your sidebar width */
  padding: 20px;
  width: calc(100% - 80px); /* Ensures content takes up remaining space */
}
```

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