Plan

0 comments0 reviews

For the prototype:

                    ┌──────────────────────┐
                    │       FRONTEND       │
                    │                      │
                    │ Patient / Screening  │
                    │ Upload / Results     │
                    │ Reports / Dashboard  │
                    └──────────┬───────────┘
                               │
                              HTTP
                               │
                    ┌──────────▼───────────┐
                    │       BACKEND        │
                    │                      │
                    │ Auth                 │
                    │ Patients             │
                    │ Screening Sessions    │
                    │ Image Management      │
                    │ ML orchestration      │
                    │ Results               │
                    │ Reports               │
                    └──────┬───────┬───────┘
                           │       │
                    ┌──────▼───┐ ┌─▼──────────┐
                    │ DATABASE │ │ FILE STORE │
                    │          │ │            │
                    │ Patients │ │ Fundus     │
                    │ Sessions │ │ images     │
                    │ Results  │ │ Grad-CAM   │
                    └──────────┘ │ reports    │
                                 └────────────┘
                                     
                           ┌───────────────┐
                           │  ML ENGINE    │
                           │               │
                           │ Quality       │
                           │ DR grading    │
                           │ Lesions       │
                           │ Grad-CAM      │
                           └───────────────┘

The critical architectural decision is:

The backend should not care how the ML model works.

Today the ML team may have a Python prototype. Later it may become MATLAB code, a MATLAB-generated service, or something else. The backend should simply send an image and receive a standardized result.


#2. Three things we're building now

#A. Backend

Responsible for:

  • users
  • patients
  • screening sessions
  • image uploads
  • invoking ML
  • storing predictions
  • storing reports
  • exposing APIs
  • audit/history

#B. Frontend

Responsible for:

  • login
  • patient registration
  • new screening
  • image upload
  • processing status
  • results
  • Grad-CAM visualization
  • screening history
  • report viewing

#C. Database/storage

Responsible for metadata, not necessarily the actual retinal images.

Database
   │
   ├── users
   ├── patients
   ├── screening_sessions
   ├── images
   ├── predictions
   ├── lesions
   └── reports

File/Object Storage
   │
   ├── original images
   ├── processed images
   ├── Grad-CAM images
   └── generated reports

#3. Suggested technology stack

#Frontend

React + TypeScript

React
TypeScript
Vite

#Backend

Python + FastAPI

FastAPI
   │
   ├── REST API
   ├── authentication
   ├── image handling
   ├── ML orchestration
   └── database access

#Database

PostgreSQL

#Image/file storage

For development:

/local storage

Later:

S3-compatible object storage

#ML

Keep this completely separate:

ML model

The backend talks to it through an interface.


#4. The database schema

Who operates the system.

users
-----
id
name
email
password_hash
role
created_at

Possible roles:

ADMIN
SCREENING_OPERATOR
OPHTHALMOLOGIST

The person being screened.

patients
--------
id
patient_code
name
age
sex
contact
created_at

One screening event.

screening_sessions
-------------------
id
patient_id
operator_id
status
created_at
completed_at

Possible statuses:

CREATED
IMAGE_UPLOADED
PROCESSING
COMPLETED
REVIEW_REQUIRED
FAILED

The actual image metadata.

images
------
id
session_id
original_path
processed_path
width
height
quality_status
created_at

Example:

quality_status:

PENDING
ACCEPTABLE
BORDERLINE
UNGRADABLE

#5. predictions

predictions
-----------
id
session_id

dr_grade
referable_dr

confidence

model_name
model_version

created_at

For example:

{
  "dr_grade": 3,
  "referable_dr": true,
  "confidence": 0.91,
  "model_name": "DRClassifier",
  "model_version": "0.1.0"
}

#6. lesions

lesions
-------
id
session_id
type
confidence
x
y
width
height
severity

Possible:

MICROANEURYSM
EXUDATE
HEMORRHAGE
NEOVASCULARIZATION

#7. reports

reports
-------
id
session_id
report_path
generated_at
review_status
reviewer_id
reviewed_at
review_notes
ML
 ↓
Result
 ↓
Ophthalmologist
 ↓
Review
 ↓
Confirm / modify
 ↓
Final report

#8. API

#Patients

POST /api/patients
GET  /api/patients
GET  /api/patients/{id}

#Screening

POST /api/screenings
GET  /api/screenings/{id}

#Image

POST /api/screenings/{id}/image

#Processing

POST /api/screenings/{id}/analyze
GET  /api/screenings/{id}/status

#Results

GET /api/screenings/{id}/result

#Report

GET /api/screenings/{id}/report

#Review

POST /api/screenings/{id}/review

#9. ML Contract

Create an interface such as:

POST /ml/analyze

Input:

fundus image

Output:

{
  "quality": {
    "status": "ACCEPTABLE",
    "confidence": 0.96
  },

  "dr": {
    "grade": 3,
    "referable": true,
    "confidence": 0.91
  },

  "explainability": {
    "gradcam_path": "...",
    "annotated_image_path": "..."
  },

  "lesions": []
}

#10. Frontend pages

#1. Login

┌──────────────────────────┐
│      DR Screening        │
│                          │
│ Email                    │
│ [____________________]   │
│                          │
│ Password                 │
│ [____________________]   │
│                          │
│       [ Login ]          │
└──────────────────────────┘

#2. Dashboard

Dashboard

Today's screenings       42
Pending reviews           7
Completed                35
Ungradable                3

[ New Screening ]

Recent screenings
─────────────────────────
Patient   Status    Grade
P-001     Complete     1
P-002     Review       3
P-003     Complete     0

#3. Patient

Patient

Patient ID: P-001
Name: ...
Age: ...
Sex: ...

[ Start New Screening ]

Previous screenings

#4. New screening

New Screening

Patient: P-001

Upload fundus image

┌────────────────────────┐
│                        │
│     Drop image here    │
│                        │
└────────────────────────┘

[ Analyze ]

#5. Processing

Analyzing retinal image...

✓ Image uploaded
✓ Quality assessment
● DR analysis
○ Explainability
○ Report

#6. Results

SCREENING RESULT

┌───────────────────────────────┐
│       Fundus Image            │
│                               │
│       [ IMAGE ]               │
└───────────────────────────────┘

DR Grade
Level 3

Referable DR
YES

Confidence
91%

────────────────────────────────

Explainability

[ Original ] [ Grad-CAM ] [ Annotated ]

────────────────────────────────

Lesion Evidence

Microaneurysms       Detected
Exudates             Detected
Hemorrhages          Detected

────────────────────────────────

[ Review ] [ Generate Report ]

#11. The user flow

The whole application can then be thought of as one pipeline:

LOGIN
  ↓
DASHBOARD
  ↓
SELECT PATIENT
  ↓
NEW SCREENING
  ↓
UPLOAD FUNDUS IMAGE
  ↓
QUALITY CHECK
  │
  ├──── UNGRADABLE
  │         ↓
  │    Recapture
  │
  └──── ACCEPTABLE
            ↓
         ML ANALYSIS
            ↓
       DR CLASSIFICATION
            ↓
       EXPLAINABILITY
            ↓
          RESULT
            ↓
    ┌───────┴────────┐
    ↓                ↓
Auto complete     Human review
    ↓                ↓
    └───────┬────────┘
            ↓
          REPORT

#12. One important architectural decision

Avoid:

Frontend → ML

Use:

Frontend
    ↓
Backend
    ↓
ML

Because eventually the backend needs to handle:

  • authentication
  • patient information
  • image storage
  • model versions
  • screening history
  • audit trail
  • reports
  • human review

#13. Repository structure

dr-screening/
│
├── frontend/
│   ├── src/
│   ├── public/
│   └── README.md
│
├── backend/
│   ├── app/
│   │   ├── api/
│   │   ├── models/
│   │   ├── schemas/
│   │   ├── services/
│   │   ├── database/
│   │   └── main.py
│   │
│   └── tests/
│
├── ml/
│   └── README.md
│
├── storage/
│   └── .gitkeep
│
├── docs/
│   ├── architecture.md
│   ├── api.md
│   └── ml-contract.md
│
├── docker-compose.yml
└── README.md