https://github.com/opesam42/sicklecare
Predictive health-tech platform for Sickle Cell crisis detection. Built with FastAPI & SQLModel. Features a data-driven Stability Index & Offline QR Triage. 4th Place @ HSIL 2026 Lagos.
https://github.com/opesam42/sicklecare
fastapi hackathon-project healthcare-application
Last synced: 30 days ago
JSON representation
Predictive health-tech platform for Sickle Cell crisis detection. Built with FastAPI & SQLModel. Features a data-driven Stability Index & Offline QR Triage. 4th Place @ HSIL 2026 Lagos.
- Host: GitHub
- URL: https://github.com/opesam42/sicklecare
- Owner: opesam42
- License: other
- Created: 2026-04-04T12:17:45.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-05-11T10:34:33.000Z (about 2 months ago)
- Last Synced: 2026-05-11T12:38:57.993Z (about 2 months ago)
- Topics: fastapi, hackathon-project, healthcare-application
- Language: Python
- Homepage:
- Size: 663 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Roadmap: ROADMAP.md
Awesome Lists containing this project
README
# π‘οΈ SickleShield (SickleCare)
> **Real-time Physiological Monitoring & Crisis Prediction for Sickle Cell Management.**
> *Awarded 4th Place β HSIL Hackathon 2026, Lagos Hub*
SickleShield is a proactive health-tech system designed to close the gap between daily biometric monitoring and emergency clinical intervention for Sickle Cell patients. By continuously analysing Heart Rate Variability (HRV), ambient temperature, hydration levels, and urine colour, the system computes a **Stability Index** to detect the *prodromal phase* of a Vaso-Occlusive Crisis (VOC) β up to 72 hours before collapse.
---
## π Table of Contents
- [The Mission](#-the-mission)
- [How It Works](#-how-it-works)
- [System Architecture](#-system-architecture)
- [Key Features](#-key-features)
- [Demo Patients](#-demo-patients)
- [Tech Stack](#-tech-stack)
- [Project Structure](#-project-structure)
- [Installation & Setup](#-installation--setup)
- [API Reference](#-api-reference)
- [Data Models](#-data-models)
- [ML Model](#-ml-model--isolation-forest)
- [Frontend Architecture](#-frontend-architecture)
- [Technical Debt & Hackathon Bypasses](#-technical-debt--hackathon-bypasses)
- [Future Roadmap](#-future-roadmap)
- [Team](#-team)
- [Legal Disclaimer](#-legal-disclaimer)
---
## π The Mission
In the Nigerian healthcare context, Sickle Cell patients (HbSS, HbSC genotypes) frequently arrive at hospitals already in full-blown Vaso-Occlusive Crisis. Emergency rooms have no prior context about the patient's baseline physiology, genotype, or recent biometric trajectory.
**SickleShield** addresses three failure points:
| Problem | Our Response |
|---|---|
| Crisis detected too late | Isolation Forest anomaly detection on continuous wearable data |
| Clinic has no context at ER | Offline-first QR triage page β works in airplane mode |
| Patient can't self-assess | 4-category pain scale + urine colour wheel with heuristic override |
**The 72-hour window** is the core thesis: physiological signals (HRV decline, dehydration, environmental cold fronts) consistently precede crisis onset. SickleShield monitors these signals daily and fires SMS alerts the moment the Stability Index crosses a critical threshold β before the patient knows they are in crisis.
---
## βοΈ How It Works
```
Patient logs daily Wearable auto-populates
(urine, hydration, pain) (HRV, HR, steps, RMSSD)
β β
ββββββββββββββββ¬ββββββββββββββββββββββ
βΌ
POST /api/submit-log/
β
βΌ
βββββββββββββββββββββββββββββββ
β Heuristic Rule Engine β
β dark_amber_urine β bypass β
β pain β₯ 6 β exclude baselineβ
ββββββββββββββ¬βββββββββββββββββ
β
βββββββββββββ΄βββββββββββββββ
β Heuristic trigger? β
YES NO
β β
βΌ βΌ
CRITICAL (instant) Isolation Forest model
risk_level = CRITICAL anomaly_score β risk_level
β β
βββββββββββββ¬βββββββββββββββ
βΌ
Stability Index (0.00β1.00)
0.00 = CRITICAL 1.00 = STABLE
β
βββββββββββββ΄βββββββββββββββ
β Is crisis? β
YES NO
β β
βΌ βΌ
Twilio SMS (patient Dashboard updates
+ clinic phone) 5-second polling
```
---
## ποΈ System Architecture
The system follows a **Backend-First Architecture**, prioritising data integrity and high-concurrency biometric polling.
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend (PWA) β
β Alpine.js Β· Tailwind CSS Β· IBM Plex Sans/Mono β
β Pages: /log /dashboard /qr /triage/{id} β
β All data fetched client-side via API.getPatient() + polling β
ββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββ
β HTTP/REST
ββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββ
β FastAPI (Python 3.12+) β
β Routers: β
β /api/auth β login, get-patient β
β /api/submit-log β log ingestion + ML inference β
β /apistatus β stitched patient status (5s polling) β
β /api/dashboard β sparkline, SMS status β
β /api/qr β QR generation, wallet card β
β /demo/{state} β demo state machine β
β Template routes β thin Jinja2 shell renderers β
ββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββ
β SQLModel ORM
ββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββ
β PostgreSQL β
β Tables: patients Β· daily_logs Β· analysis_results β
β baseline_snapshots β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββ΄βββββββββββββ
β β
βββββββββΌββββββββ βββββββββΌββββββββ
β diskcache β β Twilio SMS β
β Poll results β β Patient + β
β + weather β β Clinic alert β
βββββββββββββββββ βββββββββββββββββ
```
---
## β¨ Key Features
### 1. Stability Index (ML Engine)
The core signal. Computed on every log submission from 10 biometric features:
| Feature | Source | Clinical Meaning |
|---|---|---|
| `hrv_sdnn` | Wearable | Total autonomic resilience |
| `rmssd` | Wearable | Parasympathetic withdrawal |
| `hr_mean` | Wearable | Cardiac load |
| `steps` | Wearable | Activity context |
| `hydration_score` | Self-report | Primary VOC trigger |
| `urine_color` | Self-report | Haemolysis marker |
| `pain_level` | Self-report | Crisis threshold gate |
| `body_temp` | Wearable | Internal stress |
| `environment_temp` | Lagos Weather API | Cold front multiplier |
| `HRV_deviation` | Computed | Delta vs 7-day baseline |
Score range: `1.00` (perfectly stable) β `0.00` (immediate crisis).
**Heuristic Override:** `dark_amber_urine` bypasses the ML entirely and fires `CRITICAL` immediately. Haemolysis cannot wait for a model confidence score.
**Baseline exclusion:** Logs with `pain_level β₯ 6` (Moderate/Severe) are excluded from the 7-day baseline calculation, preventing crisis-day readings from polluting the patient's healthy profile.
### 2. Emergency QR & Offline Triage
Every patient has a QR code that links to `/triage/{patient_id}` β a server-rendered Jinja2 page with **zero JavaScript and zero CDN dependencies**. It displays:
- Patient name, genotype (HbSS/HbSC), comorbidities
- 7-day biometric log table with crisis days highlighted
- Current anomaly score + method badge
- Baseline snapshot (HRV avg, hydration avg, HR avg)
- Last crisis event timestamp
Designed to load in hospital basements. The QR page also generates a downloadable wallet-size PDF (html2canvas + jsPDF, auto-sized to content β no clipping).
### 3. Smart SMS Alerts (Twilio)
Triggered when `is_crisis = True`:
- **MEDIUM risk:** Patient SMS only
- **CRITICAL risk:** Patient SMS + Clinic SMS (dual-channel)
SMS payload includes patient name, risk level, stability score, and a shortened triage URL.
### 4. Wearable Integration
Continuous 5-second polling via `/apistatus/latest` (stitched endpoint) populates:
- HRV SDNN, RMSSD (from Apple Watch / Xiaomi Mi Fitness)
- Heart rate, steps (BLE sync)
- Environmental temperature (Visual Crossing Weather API, Lagos)
Wearable fields are **display-only** in the log form β the patient cannot edit them. `buildPayload()` reads directly from `$store.vitals`.
### 5. Dashboard β Mission Control
Real-time dashboard with 5-second auto-refresh:
- **Risk banner** β pulses on CRITICAL
- **2Γ2 score card grid** β stability score, risk level, HRV today, vs-baseline delta
- **7-day sparkline** β bar chart coloured by daily risk level
- **Triggered flags strip** β fadein on escalation
- **SMS status rows** β live delivery confirmation
- **QR button** β visible only on MEDIUM/CRITICAL, pulses on CRITICAL
- **Demo state switcher** β Ada (stable) / Chidi (weather) / Ngozi (critical VOC)
---
## π₯ Demo Patients
Three seeded patients covering all three clinical states:
| State | Patient | Genotype | UUID (first 8) |
|---|---|---|---|
| `stable` | Ada Okonkwo | HbSC | `12cac1f5` |
| `weather_triggered` | Chidi Eze | HbSS | `6f2b4d3b` |
| `critical_voc` | Ngozi Adeyemi | HbSS + Asthma | `7df78b03` |
**Ngozi's demo scenario:** Dark amber urine detected β heuristic override fires β `CRITICAL` regardless of ML score β dual SMS fired to patient + clinic β emergency QR shows "Haemolysis likely."
Access demo states at `/dashboard?patient=stable`, `/dashboard?patient=weather_triggered`, `/dashboard?patient=critical_voc`.
---
## π οΈ Tech Stack
| Layer | Technology | Why |
|---|---|---|
| Backend | FastAPI (Python 3.12+) | Async event loop, auto OpenAPI docs, speed |
| ORM | SQLModel (SQLAlchemy + Pydantic) | Type-safe models, single source of truth |
| Database | PostgreSQL | JSONB for flags/metadata, relational integrity |
| ML | Isolation Forest (scikit-learn, joblib) | Unsupervised β no labelled crisis data needed |
| Cache | diskcache | Zero-config, filesystem-backed poll cache |
| Frontend | Alpine.js 3.14 + Tailwind CSS CDN | Low-JS, fast on low-end Nigerian mobile devices |
| Fonts | IBM Plex Sans + IBM Plex Mono | Medical/clinical aesthetic, Google Fonts |
| Templates | Jinja2 | Thin shell renders β all data fetched by JS |
| SMS | Twilio | Programmable SMS, Nigerian numbers supported |
| QR | qrcode[pil] | Python-native QR generation, ERROR_CORRECT_M |
| PDF | html2canvas + jsPDF (CDN) | Auto-sized to content β zero clipping |
| Weather | Visual Crossing API | Lagos ambient temperature enrichment |
| Deploy | Render | Free tier, PostgreSQL add-on |
---
## π Project Structure
```
sickleshield/
βββ src/
β βββ main.py # FastAPI app, lifespan, CORS, router registration
β βββ config.py # Pydantic settings (DATABASE_URL, API keys)
β βββ database.py # Engine, session factory, SessionDep
β βββ logger.py # Shared logging config
β βββ cache.py # diskcache setup
β βββ ml_model.py # Isolation Forest load/unload + feature map
β βββ models/
β β βββ models.py # Patient, DailyLog, AnalysisResult, BaselineSnapshot
β βββ schemas/
β β βββ schema.py # LoginRequest, LoginResponse, Pydantic payloads
β βββ routers/
β β βββ api.py # /api/submit-log/, /apistatus/latest, /demo/*
β β βββ auth.py # /api/auth/login, /api/auth/get-patient
β β βββ dashboard_router.py # /api/dashboard/sparkline, /api/dashboard/sms-status
β β βββ qr_router.py # /api/qr/data, /api/qr/wallet-card
β βββ templates.py # Thin Jinja2 template routes
β βββ services.py # ML inference, heuristic engine, SMS dispatch
βββ templates/
β βββ base.html # Alpine.js load order, Tailwind config, script slots
β βββ _header.html # Shared app header partial (drawer + stats strip)
β βββ login.html # Auth page
β βββ log.html # 3-step daily log form (urine β hydration β pain)
β βββ dashboard.html # Mission control dashboard
β βββ qr.html # Emergency QR + wallet card PDF download
β βββ triage.html # Offline ER triage (zero JS, zero CDN)
βββ static/
β βββ script/
β β βββ components/
β β β βββ config.js # BASE_URL (localhost vs production)
β β β βββ vitals.js # $store.vitals + vitalsPoller (5s polling)
β β β βββ log.js # logForm Alpine component
β β β βββ dashboard.js # dashboardApp Alpine component
β β β βββ login.js # loginForm Alpine component
β β β βββ urine-wheel.js # urineWheel Alpine component
β β β βββ hydration-log.js # hydrationLog Alpine component
β β βββ api.js # API singleton (all endpoints, getPatient())
β β βββ auth.js # Auth utilities (getKey, require, logout)
β βββ style/
β βββ main.css # Custom CSS (app-header, card styles, etc.)
βββ models/
β βββ isolation.pkl # Trained Isolation Forest model
βββ seed.py # Seeds 3 demo patients + 30-day logs
βββ requirements.txt
βββ .env
```
---
## π§ Installation & Setup
### Prerequisites
- Python 3.12+
- PostgreSQL 14+
- Node.js (optional β only if building Tailwind locally)
### 1. Clone the repository
```bash
git clone https://github.com/yourusername/sickleshield.git
cd sickleshield
```
### 2. Set up environment variables
Create a `.env` file in the project root:
```env
DATABASE_URL=postgresql://user:password@localhost:5432/sickleshield
VISUAL_CROSSING_WEATHER_API_KEY=your_key_here
APP_URL=https://your-domain.com
```
> **Render note:** If your `DATABASE_URL` starts with `postgres://`, the app automatically rewrites it to `postgresql://` for SQLAlchemy compatibility.
### 3. Install dependencies
```bash
pip install -r requirements.txt
```
Key dependencies:
```
fastapi[standard]
sqlmodel
psycopg2-binary
uvicorn
twilio
qrcode[pil]
joblib
scikit-learn
diskcache
python-dotenv
pydantic-settings
httpx
```
### 4. Initialise the database
```bash
# Tables are auto-created on first startup via SQLModel.metadata.create_all()
uvicorn src.main:app --reload
```
### 5. Seed demo patients
```bash
python seed.py
```
This creates Ada, Chidi, and Ngozi with 30 days of synthetic logs and analysis results.
### 6. Run the server
```bash
# Development
uvicorn src.main:app --reload --port 8000
# Production (Render uses this automatically)
uvicorn src.main:app --host 0.0.0.0 --port $PORT
```
The app is available at `http://127.0.0.1:8000`. API docs at `/docs`.
---
## π‘ API Reference
### Authentication
| Method | Endpoint | Description |
|---|---|---|
| `POST` | `/api/auth/login` | Email + password β `{ patient_id, name, status }` |
| `GET` | `/api/auth/get-patient?id=` | Fetch patient by UUID |
All protected endpoints require `X-Patient-ID: ` header.
### Core
| Method | Endpoint | Description |
|---|---|---|
| `POST` | `/api/submit-log/` | Submit daily log β triggers ML inference |
| `GET` | `/apistatus/latest` | Stitched patient status (vitals + analysis) |
| `GET` | `/api/poll-status/` | Legacy cache endpoint |
| `GET` | `/api/hrv/latest` | Live HRV stub (wearable integration) |
### Dashboard
| Method | Endpoint | Description |
|---|---|---|
| `GET` | `/api/dashboard/sparkline` | 7-day HRV bars for sparkline |
| `GET` | `/api/dashboard/sms-status` | Latest SMS delivery state |
### QR
| Method | Endpoint | Description |
|---|---|---|
| `GET` | `/api/qr/data` | QR image (base64) + risk state |
| `GET` | `/api/qr/wallet-card?patient_id=` | Printable PDF card (stub β 501) |
### Demo
| Method | Endpoint | Description |
|---|---|---|
| `GET` | `/demo/stable` | Ada's stable state |
| `GET` | `/demo/weather_triggered` | Chidi's weather state |
| `GET` | `/demo/critical_voc` | Ngozi's critical VOC state |
### Template Routes (Jinja2)
| Route | Page |
|---|---|
| `GET /` | Index |
| `GET /login` | Login |
| `GET /log?patient={state}` | Daily log form |
| `GET /dashboard?patient={state}` | Dashboard |
| `GET /qr?patient={state}` | Emergency QR |
| `GET /triage/{patient_id}` | Offline ER triage |
| `GET /triage/demo/{state}` | Demo triage (no QR scan needed) |
### `/apistatus/latest` Response Shape
```json
{
"patient_id": "12cac1f5-...",
"patient_info": { "name": "Ada Okonkwo", "genotype": "HbSC" },
"vitals": { "hr": 65.2, "hrv": 75.0, "temp": 0, "steps": 0 },
"manual": { "hydration": 1, "pain": 0, "urine": "pale_yellow" },
"analysis": {
"stability_score": 0.64,
"risk_level": "low",
"is_crisis": false,
"flags": [],
"last_updated": "2026-04-11T09:41:00Z"
}
}
```
> **Score convention:** `stability_score` where `1.0 = LOW risk` and `0.0 = CRITICAL`. The frontend inverts colour logic accordingly.
---
## ποΈ Data Models
```python
class Patient(SQLModel, table=True):
id: uuid.UUID # Primary key
email: EmailStr
password: str
name: str
genotype: str # "HbSS" | "HbSC"
has_asthma: bool
phone_number: str
clinic_phone: str
created_at: datetime
class DailyLog(SQLModel, table=True):
id: int
patient_id: uuid.UUID
steps: Optional[int]
rmssd: Optional[float]
hrv_sdnn: Optional[float]
hr_mean: Optional[float]
body_temp: Optional[float] # Internal patient temp
environment_temp: Optional[float] # Lagos ambient temp
hydration_score: Optional[float] # 0.0β1.0 (8 glasses = 1.0)
urine_color: Optional[str] # very_pale | pale_yellow | yellow | dark_yellow | dark_amber
pain_level: Optional[int] # 0 | 3 | 6 | 9
logged_at: datetime
class AnalysisResult(SQLModel, table=True):
id: int
log_id: int # FK β daily_logs
anomaly_score: float
raw_anomaly_score: float
risk_level: str # low | medium | critical
is_crisis: bool
method_used: str # isolation_forest | heuristic_override
triggered_flags: List[str] # JSONB
ml_metadata: dict # JSONB
class BaselineSnapshot(SQLModel, table=True):
patient_id: uuid.UUID # PK β one snapshot per patient
hr_mean_avg: float
hrv_sdnn_avg: float
hydration_avg: float
updated_at: datetime
```
---
## π€ ML Model β Isolation Forest
### Why Isolation Forest?
Sickle Cell crisis data is rare by definition β patients are not in crisis most days. Supervised learning requires labelled crisis examples we don't have at hackathon scale. Isolation Forest is **unsupervised**: it learns the patient's healthy baseline distribution and flags statistical outliers as anomalous.
### Feature Map (10 dimensions)
```
1. hr_mean β Cardiac load (tachycardia = stress signal)
2. steps β Activity context (lethargy at high HR = crisis signal)
3. rmssd β High-frequency HRV (vagus nerve withdrawal)
4. hrv_sdnn β Total autonomic resilience
5. environment_temp β Lagos ambient temperature (cold = viscosity spike)
6. hydration_score β Primary VOC trigger
7. HR_deviation β Current HR minus 24h mean (spike detection)
8. steps_deviation β Sudden lethargy vs mean (prodromal signal)
9. HRV_deviation β Delta-HRV (loss of physiological flexibility)
10. rmssd_deviation β Parasympathetic withdrawal delta
```
### Heuristic Safety Net
The ML model can be bypassed by clinical rules that are deterministic:
```python
if urine_color == "dark_amber":
risk_level = "CRITICAL"
method_used = "heuristic_override"
# Dark amber urine = haemolysis β cannot wait for model confidence
```
Pain-level β₯ 6 (Moderate/Severe) excludes the log from baseline recalculation, preventing crisis-phase readings from polluting the patient's healthy distribution.
### Model File
```
models/isolation.pkl # Trained Isolation Forest, joblib format
```
If the model file is missing at startup, the system falls back to the heuristic-only engine and logs a warning.
---
## π₯οΈ Frontend Architecture
### Philosophy
"Low-JS" β the browser does as little as possible. Template routes are thin shells that render HTML with `state` and `prefill` only. All patient data, risk state, and analysis are fetched client-side via `API.getPatient()` and the 5-second polling loop.
### Script Load Order (critical)
```html
{% block scripts %}{% endblock %}
```
### Authentication Flow
```
User submits email + password
β POST /api/auth/login
β { patient_id: "uuid" }
β localStorage.setItem('X-Patient-ID', uuid)
β redirect to /log
Every subsequent API call:
β API.get(path) adds header: X-Patient-ID: uuid
β API.getPatient() fetches /api/auth/get-patient?id=uuid
β 401/404 β Auth.logout() β redirect to /login?next=...
```
### Polling Architecture
```
vitalsPoller (mounted on every page via base.html):
βββ GET /apistatus/latest every 5s β $store.vitals.* + dispatches vitals:analysis event
βββ GET /api/api/temperature every 60s β $store.vitals.temp
βββ GET /api/hrv/latest every 10s β $store.vitals.hrv (wearable stub)
dashboardApp (dashboard page only):
βββ listens to vitals:analysis events
βββ GET /api/dashboard/sparkline every 30s β sparklineBars[]
βββ GET /api/dashboard/sms-status every 10s β smsStatus{patient, clinic}
```
### Pain Scale Design Decision
The log form uses 4 clinical categories instead of a 0β10 slider:
| Button | Value sent | Baseline exclusion |
|---|---|---|
| None π | 0 | No |
| Mild π | 3 | No |
| Moderate π£ | 6 | Yes (`pain_level β₯ 4`) |
| Severe π | 9 | Yes |
Reason: a 0β10 slider has a precision illusion. Patients anchor on round numbers and can't reliably reproduce the same value day-to-day, making the exclusion threshold noisy. Four clinical categories map directly to medical terminology and are reproducible.
---
## π© Technical Debt & Hackathon Bypasses
To ensure 100% demo reliability during HSIL 2026, the following engineering trade-offs were made deliberately:
| Bypass | Detail | Production fix |
|---|---|---|
| **Weather fallback** | If Visual Crossing times out or hits rate limit, defaults to `31.0Β°C` (Lagos constant) | Implement retry + circuit breaker |
| **X-Patient-ID auth** | Custom header used instead of OAuth2/JWT | Replace with JWT (RS256) + refresh tokens |
| **Postgres prefix** | `postgres://` β `postgresql://` auto-rewrite for Render | Standardise in ENV |
| **Plain text passwords** | Passwords stored as-is for demo speed | bcrypt hashing + salting |
| **In-process ML** | Model loaded into main FastAPI process | Move to dedicated inference service or Celery worker |
| **Wallet card PDF** | `GET /api/qr/wallet-card` returns 501 | Implement ReportLab or WeasyPrint server-side PDF |
| **No migrations** | Tables created via `SQLModel.metadata.create_all()` | Alembic versioned migrations |
| **Demo patients hardcoded** | UUIDs baked into `DEMO_PATIENT_MAP` | Dynamic patient discovery |
---
## π Future Roadmap
**Backend**
- [ ] Alembic migrations β versioned schema management
- [ ] SMART on FHIR integration β international interoperability standards
- [ ] Celery + Redis β async SMS and PDF generation workers
- [ ] JWT hardening β rotatable token-based auth (RS256)
- [ ] bcrypt password hashing
- [ ] Rate limiting on `/api/submit-log/` (prevent duplicate submissions)
**ML**
- [ ] Per-patient model fine-tuning as baseline data accumulates
- [ ] Gradient Boosting ensemble alongside Isolation Forest
- [ ] Federated learning β train on aggregated patient cohort without exposing individual data
**Wearable**
- [ ] Native Apple HealthKit integration (iOS HealthKit API)
- [ ] Xiaomi Mi Fitness BLE direct sync
- [ ] RMSSD real-time stream via WebSocket
**Clinical**
- [ ] Clinician dashboard (separate role + auth)
- [ ] Medication tracking integration
- [ ] Hospital EHR API (NHIS Nigeria)
---
## π₯ Team
Built at **HSIL Hackathon 2026 β Lagos Hub** in 24 hours.
| Role | Contribution |
|---|---|
| **Backend Lead** | FastAPI architecture, rules engine, template routes, frontend integration |
| **ML Engineer** | Isolation Forest training, feature map, joblib export |
| **AI Engineer** | LLM prompt engineering, Twilio SMS integration |
| **PM / Designer** | Pitch deck, UI/UX, business model, demo choreography |
**Developed by:** Gbenga Opeyemi β Computer Science, University of Lagos.
---
## βοΈ Legal Disclaimer
**FOR EDUCATIONAL PURPOSES ONLY.**
This project was built for a hackathon competition. It is **not** a clinically validated medical device and has **not** been assessed by any regulatory body (NAFDAC, FDA, CE). Do not use this software for the diagnosis, treatment, prevention, or monitoring of any medical condition.
Any clinical decisions should be made by qualified medical professionals. The anomaly scores produced by this system are statistical indicators, not medical diagnoses.
---
## π Licence
MIT β see `LICENSE` for details.
---
*SickleShield Β· HSIL 2026 Β· Built for Nigeria Β· HbSS Β· HbSC*