Four defences before a reading is stored
The device route checks its per-device rate limit before doing any cryptographic work — the cheap check first, so a flood cannot force expensive hashing. Authentication then resolves the device row and verifies the key with bcrypt in a thread pool, because bcrypt is CPU-bound and would otherwise stall the event loop for everyone.
Entity and patient are always resolved from the authenticated device row and never from the request body. That closes the obvious attack: a compromised key can only write readings for the patient its device belongs to. A retired or suspended device is rejected even with a valid key, which is the mechanism for revoking a stolen credential.
Value ranges are enforced as schema constraints per vital type — systolic, diastolic, heart rate, weight, glucose, oxygen saturation and temperature each have a plausible band — plus a validator requiring the fields that match the declared reading type. A device reporting a body temperature of two hundred degrees is a malfunction, and it should be rejected at the door rather than alerted on.
