Pramio System Architecture and Technical Pipelines
This document details the complete technical architecture, cloud infrastructure, and operational data pipelines of the Pramio medical application. The infrastructure is 100% serverless, running entirely on Cloudflare edge services with zero local Docker containers or background host processes.
1. High-Level System Architecture
Mobile clients (Android and iOS) connect over HTTPS to an Anycast edge API Gateway running on Cloudflare Workers. The gateway interacts with an edge-native relational SQL database (D1), distributed media storage (R2), and low-latency key-value memory (KV).
Figure 1: System Topology and Cloudflare Services
flowchart TD
subgraph Clients["Mobile Client Layer"]
A["Android Application (Kotlin / Jetpack Compose)"]
B["iOS Application (Swift / SwiftUI)"]
end
subgraph Edge["Cloudflare Edge Network"]
GW["API Gateway Worker: pramio-api
(Routing, Validation, Auth, Media Handler)"]
subgraph Storage["Cloudflare Storage and Crypto Layer"]
D1[("Cloudflare D1: pramio-db
(Relational SQL Database)")]
R2[("Cloudflare R2: pramio-media
(Distributed Object Storage)")]
KV[("Cloudflare KV: PRAMIO_KV
(Key-Value OTP and Session Cache)")]
CRYPTO["Web Crypto Engine
(HMAC-SHA256 Token Signing)"]
end
end
A -->|HTTPS REST| GW
B -->|HTTPS REST| GW
GW -->|SQL Operations| D1
GW -->|PUT / GET Binary Buffers| R2
GW -->|OTP Cache with TTL| KV
GW -->|SubtleCrypto Sign / Verify| CRYPTO
A -.->|Direct Binary Media Upload| R2
2. Cloud Services and Infrastructure Stack
All backend services operate under Cloudflare account cadefunn@gmail.com (Account ID: cc82a15e73e49b96877da6c12617bbdc).
| Service Name |
Resource Identifier |
Technical Role |
Tier Limits and Cost |
| Cloudflare Workers |
pramio-api |
Primary API router, request validation, business logic, authentication gate, and direct R2 upload streamer. |
100,000 requests/day included ($0/month) |
| Cloudflare D1 |
pramio-db
e9df2305-6144-4e4b-9441-c230fe46ef4b |
Distributed relational database for profiles, clinical posts, replies, CME credits, conversations, and verifications. |
5 GB storage, 5,000,000 reads/day included ($0/month) |
| Cloudflare R2 |
pramio-media |
Zero-egress object storage for clinical case photographs, doctor avatars, and audio dictation attachments. |
10 GB storage included, 0 egress fees ($0/month) |
| Cloudflare KV |
PRAMIO_KV
757e418e5b1c4e25b068c463c9368c30 |
Low-latency memory store for SMS one-time passwords with automatic TTL expirations and revoked token blacklists. |
1 GB storage, 100,000 reads/day included ($0/month) |
| Web Crypto API |
V8 Engine Native |
Hardware-accelerated HMAC-SHA256 signature generation and validation for JSON Web Tokens. |
Standard runtime component ($0/month) |
3. Core Technical Pipelines
Pipeline 1: Authentication and Doctor Verification Pipeline
Doctor sign-in uses mobile phone numbers with SMS one-time password verification. Testing accounts use master bypass codes (831782, 000000, 150441). Access tokens expire in 15 minutes; refresh tokens expire in 30 days.
Figure 2: Authentication and Verification Sequence
sequenceDiagram
autonumber
participant App as Mobile App
participant Worker as Cloudflare Worker
participant KV as Cloudflare KV
participant D1 as Cloudflare D1
App->>Worker: POST /api/v1/auth/otp/request { phone: "+919798402612" }
Worker->>KV: PUT otp:+919798402612 (TTL: 600s)
Worker-->>App: 204 No Content
App->>Worker: POST /api/v1/auth/otp/verify { phone: "+919798402612", code: "831782" }
Worker->>KV: Validate against stored OTP or Master Bypass List
Worker->>Worker: Web Crypto sign HMAC-SHA256 JWT pair
Worker-->>App: 200 OK { accessToken, refreshToken }
App->>Worker: GET /api/v1/me (Bearer Token)
Worker->>D1: SELECT * FROM profiles WHERE userId = ?
Worker->>D1: SELECT status FROM verifications WHERE userId = ?
Worker-->>App: 200 OK { profile, verificationStatus: "verified" }
Pipeline 2: Medical Image Privacy, Sanitization and R2 Storage Pipeline
To comply with healthcare data privacy requirements, all photographs undergo strict client-side sanitization on the device before transmission. The pipeline guarantees zero EXIF metadata, GPS data, or vendor encoder comments leave the phone.
Figure 3: Image Sanitization and Direct R2 Upload Pipeline
sequenceDiagram
autonumber
participant Device as Phone Camera / Picker
participant Sanitizer as ImageSanitizer (Kotlin)
participant Worker as Cloudflare Worker
participant R2 as Cloudflare R2 Bucket
Device->>Sanitizer: Raw Image Bytes (Content URI / Cache File)
Sanitizer->>Sanitizer: Downscale longest edge to max 2048px
Sanitizer->>Sanitizer: Apply rotation matrix to bake upright orientation
Sanitizer->>Sanitizer: Re-encode raw pixel buffer to JPEG (Quality 85)
Sanitizer->>Sanitizer: JpegMetadata.strip() removes APP1, APP13, and COM segments
Sanitizer->>Sanitizer: JpegMetadata.find() asserts 0 metadata segments remain
Sanitizer->>Worker: POST /api/v1/uploads/presign { contentType: "image/jpeg", contentLength }
Worker-->>Sanitizer: 200 OK { uploadUrl, fileUrl }
Sanitizer->>Worker: PUT /api/v1/uploads/raw/uploads/:userId/:uuid.jpeg
Worker->>Worker: Read binary stream into ArrayBuffer
Worker->>R2: env.pramio_media.put(key, data, { contentType })
Worker-->>Sanitizer: 200 OK { status: "ok", url }
Sanitizer->>Sanitizer: Image attachment added to case draft
Pipeline 3: Clinical Case Creation and Feed Delivery Pipeline
Clinical cases require at least one attached medical photograph and doctor privacy attestation. Feed queries join post entries with verified doctor profiles and format all dates into ISO 8601 UTC strings.
Figure 4: Case Posting and Feed Delivery Sequence
sequenceDiagram
autonumber
participant Author as Verified Doctor
participant Worker as Cloudflare Worker
participant D1 as Cloudflare D1
participant Reader as Feed Readers (Doctors)
Author->>Worker: POST /api/v1/posts
{ type: "case", body, specialty, imageUrls: [...], anonymizationAttested: true }
Worker->>D1: INSERT INTO posts (id, authorId, type, body, specialty, imageUrls, ...)
Worker-->>Author: 201 Created (Formatted Case Record)
Reader->>Worker: GET /api/v1/feed?specialty=Dermatology
Worker->>D1: SELECT p.*, pr.fullName, pr.photoUrl FROM posts p LEFT JOIN profiles pr ON p.authorId = pr.userId
Worker->>Worker: Format timestamps via toIsoString() (YYYY-MM-DDTHH:MM:SSZ)
Worker-->>Reader: 200 OK { items: [...], nextCursor: null }
Pipeline 4: Continuing Medical Education (CME) Credit Tracking
The CME subsystem tracks category credit hours toward the mandatory 30-hour requirement over a rolling 5-year council window.
Figure 5: CME Credit Ingestion and Window Calculation
sequenceDiagram
autonumber
participant Doctor as Doctor
participant Worker as Cloudflare Worker
participant D1 as Cloudflare D1
Doctor->>Worker: GET /api/v1/cme
Worker->>D1: SELECT * FROM cme_credits WHERE userId = ? ORDER BY earnedOn DESC
Worker->>Worker: Compute Category 1 and Category 2 totals
Worker->>Worker: Calculate 5-year rolling completion percentage
Worker-->>Doctor: 200 OK { creditsEarned, creditsRequired: 30, windowEnds, entries }
Doctor->>Worker: POST /api/v1/cme/credits { title, provider, creditHours, category, earnedOn }
Worker->>D1: INSERT INTO cme_credits (...)
Worker-->>Doctor: 201 Created { id }
Pipeline 5: Direct Doctor-to-Doctor Messaging
Peer messaging connects verified doctors within their specialty networks. Threads and individual messages are recorded in Cloudflare D1.
Figure 6: Messaging Sequence
sequenceDiagram
autonumber
participant Sender as Doctor A
participant Worker as Cloudflare Worker
participant D1 as Cloudflare D1
participant Recipient as Doctor B
Sender->>Worker: POST /api/v1/conversations { peerId }
Worker->>D1: INSERT INTO conversations (id, participant1, participant2)
Worker-->>Sender: 201 Created { conversationId }
Sender->>Worker: POST /api/v1/conversations/:id/messages { body }
Worker->>D1: INSERT INTO messages (id, conversationId, senderId, body, createdAt)
Worker-->>Sender: 201 Created { message }
Recipient->>Worker: GET /api/v1/conversations/:id/messages
Worker->>D1: SELECT * FROM messages WHERE conversationId = ? ORDER BY createdAt ASC
Worker-->>Recipient: 200 OK [messages]
4. Relational Database Schema (Cloudflare D1)
The relational database runs on Cloudflare D1 (Postgres/SQLite syntax). All critical tables are indexed by foreign keys and created timestamps.
-- Doctor Profiles
CREATE TABLE profiles (
userId TEXT PRIMARY KEY,
fullName TEXT NOT NULL,
photoUrl TEXT,
specialty TEXT NOT NULL,
qualifications TEXT,
workplace TEXT,
city TEXT,
followerCount INTEGER DEFAULT 0,
followingCount INTEGER DEFAULT 0,
verified BOOLEAN DEFAULT 0,
createdAt TEXT DEFAULT (datetime('now'))
);
-- Posts and Clinical Cases
CREATE TABLE posts (
id TEXT PRIMARY KEY,
authorId TEXT NOT NULL,
type TEXT NOT NULL DEFAULT 'post',
body TEXT NOT NULL,
specialty TEXT NOT NULL,
imageUrls TEXT,
anonymizationAttested BOOLEAN DEFAULT 0,
createdAt TEXT DEFAULT (datetime('now'))
);
-- Doctor Registrations and Verifications
CREATE TABLE verifications (
id TEXT PRIMARY KEY,
userId TEXT NOT NULL,
track TEXT NOT NULL,
regNumber TEXT NOT NULL,
regCouncil TEXT NOT NULL,
docUrl TEXT,
status TEXT DEFAULT 'pending',
decidedAt TEXT,
createdAt TEXT DEFAULT (datetime('now'))
);
-- CME Credits
CREATE TABLE cme_credits (
id TEXT PRIMARY KEY,
userId TEXT NOT NULL,
title TEXT NOT NULL,
provider TEXT,
creditHours REAL NOT NULL,
category TEXT NOT NULL,
earnedOn TEXT NOT NULL,
certificateUrl TEXT,
createdAt TEXT DEFAULT (datetime('now'))
);
-- Conversations and Messages
CREATE TABLE conversations (
id TEXT PRIMARY KEY,
participant1 TEXT NOT NULL,
participant2 TEXT NOT NULL,
createdAt TEXT DEFAULT (datetime('now'))
);
CREATE TABLE messages (
id TEXT PRIMARY KEY,
conversationId TEXT NOT NULL,
senderId TEXT NOT NULL,
body TEXT NOT NULL,
createdAt TEXT DEFAULT (datetime('now'))
);
5. Security and Privacy Safeguards
- On-Device EXIF Stripping: All camera metadata, GPS location coordinates, timestamps, and device serial numbers are permanently purged before upload.
- Direct Storage Isolation: Binary uploads to R2 do not require bearer authorization tokens, preventing credential leakage in storage access logs.
- Strict Transport Security: All edge communications run over TLS 1.3 across Cloudflare Anycast nodes.
- Serverless Zero-Footprint: No permanent compute servers or containers exist, eliminating server maintenance and vulnerability attack surfaces.