How to Build a Device History Record with TofuPilot
The Device History Record (DHR) is a mandatory document for FDA-regulated medical devices. It's the complete production record for each finished device: what was built, how it was tested, and what the results were. TofuPilot provides the test data component of the DHR automatically.
What the FDA Requires
21 CFR 820.184 (Device History Record) requires documentation of:
| DHR component | What it includes | TofuPilot's role |
|---|---|---|
| Production dates | When the device was manufactured | Test run timestamps |
| Quantity manufactured | How many in the lot/batch | Run count by batch |
| Acceptance records | Test results showing conformity | All measurements with limits |
| Primary identification label | Serial number, UDI | Unit under test serial |
| Labeling | Labels used on the device | (Outside TofuPilot scope) |
| Equipment used | Test stations, calibration status | Station identification |
Test Data as DHR Evidence
Every test run in TofuPilot is a DHR evidence record. For each device serial number, TofuPilot stores:
from tofupilot import TofuPilotClient
client = TofuPilotClient()
# ICT (In-Circuit Test)
client.create_run(
procedure_id="ICT-MEDICAL-BOARD",
unit_under_test={
"serial_number": "MD-2025-00421",
"part_number": "CARDIAC-MONITOR-PCB-R5",
},
run_passed=True,
steps=[{
"name": "Component Verification",
"step_type": "measurement",
"status": True,
"measurements": [
{"name": "r1_resistance_kohm", "value": 10.02, "unit": "kohm", "limit_low": 9.5, "limit_high": 10.5},
{"name": "c1_capacitance_uf", "value": 4.72, "unit": "uF", "limit_low": 4.23, "limit_high": 5.17},
{"name": "u1_continuity", "value": 1, "unit": "bool", "limit_low": 1},
],
}],
)
# Functional test
client.create_run(
procedure_id="FUNC-CARDIAC-MONITOR",
unit_under_test={"serial_number": "MD-2025-00421"},
run_passed=True,
steps=[{
"name": "ECG Signal Chain",
"step_type": "measurement",
"status": True,
"measurements": [
{"name": "ecg_gain_db", "value": 60.2, "unit": "dB", "limit_low": 59.0, "limit_high": 61.0},
{"name": "ecg_cmrr_db", "value": 112, "unit": "dB", "limit_low": 100},
{"name": "ecg_noise_uv_rms", "value": 8.3, "unit": "uV", "limit_high": 15},
],
}],
)
# Electrical safety
client.create_run(
procedure_id="SAFETY-IEC60601",
unit_under_test={"serial_number": "MD-2025-00421"},
run_passed=True,
steps=[{
"name": "Patient Leakage",
"step_type": "measurement",
"status": True,
"measurements": [
{"name": "patient_leakage_normal_ua", "value": 4.2, "unit": "uA", "limit_high": 10},
{"name": "patient_leakage_sfc_ua", "value": 22.1, "unit": "uA", "limit_high": 50},
],
}],
)
# Final inspection
client.create_run(
procedure_id="FINAL-INSPECTION",
unit_under_test={"serial_number": "MD-2025-00421"},
run_passed=True,
steps=[{
"name": "Cosmetic and Label Check",
"step_type": "measurement",
"status": True,
"measurements": [
{"name": "label_present", "value": 1, "unit": "bool", "limit_low": 1},
{"name": "cosmetic_pass", "value": 1, "unit": "bool", "limit_low": 1},
{"name": "udi_barcode_readable", "value": 1, "unit": "bool", "limit_low": 1},
],
}],
)Compiling the DHR
Search by serial number in TofuPilot to retrieve all test records for a device.
For device MD-2025-00421, the DHR test section shows:
| Test | Date | Result | Station |
|---|---|---|---|
| ICT-MEDICAL-BOARD | 2025-03-15 09:22 | PASS | STN-ICT-02 |
| FUNC-CARDIAC-MONITOR | 2025-03-15 10:15 | PASS | STN-FUNC-01 |
| SAFETY-IEC60601 | 2025-03-15 11:30 | PASS | STN-SAFETY-01 |
| FINAL-INSPECTION | 2025-03-15 14:00 | PASS | STN-FINAL-01 |
Each row links to the complete measurement data: every value, every limit, every pass/fail status.
Handling Nonconformities in the DHR
When a device fails a test and is reworked, the DHR must show:
- The original failure (which measurement, what value)
- The disposition decision (rework, scrap, use-as-is)
- The retest result after rework
TofuPilot captures #1 and #3 automatically. For #2, document the disposition in your QMS and cross-reference the TofuPilot run ID.
# Original test failed
# Run ID: run-001 (patient leakage at 12.3 uA, limit 10 uA)
# After rework (replaced connector), retest
client.create_run(
procedure_id="SAFETY-IEC60601-RETEST",
unit_under_test={"serial_number": "MD-2025-00421"},
run_passed=True,
steps=[{
"name": "Patient Leakage (Post-Rework)",
"step_type": "measurement",
"status": True,
"measurements": [
{"name": "patient_leakage_normal_ua", "value": 3.8, "unit": "uA", "limit_high": 10},
],
}],
)The DHR for this device now shows: original fail, rework disposition (from QMS), and passing retest.
Batch DHR Reports
For batch release, pull all devices in a production lot and verify complete test records.
from tofupilot import TofuPilotClient
client = TofuPilotClient()
# Required procedures for a complete DHR
required_procedures = [
"ICT-MEDICAL-BOARD",
"FUNC-CARDIAC-MONITOR",
"SAFETY-IEC60601",
"FINAL-INSPECTION",
]
# Check all devices in the batch
batch_serials = [f"MD-2025-{i:05d}" for i in range(400, 450)]
incomplete = []
for serial in batch_serials:
runs = client.get_runs(unit_serial=serial)
completed_procedures = {r["procedure_id"] for r in runs if r["run_passed"]}
missing = set(required_procedures) - completed_procedures
if missing:
incomplete.append({"serial": serial, "missing": missing})
if incomplete:
print(f"{len(incomplete)} devices have incomplete DHRs:")
for d in incomplete:
print(f" {d['serial']}: missing {d['missing']}")
else:
print("All devices have complete DHRs. Batch ready for release.")Retention and Retrieval
FDA requires DHR retention for the lifetime of the device plus additional years. TofuPilot stores all test data with timestamps and audit trails. Configure your data retention policy to match your regulatory requirements.
When FDA asks for a specific device's DHR during an inspection, search by serial number and export the complete test history. Structured, timestamped, immutable records replace paper binders and Excel files.
Integration with Your QMS
TofuPilot handles the test data component of the DHR. Your QMS (quality management system) handles:
- Bill of materials and component traceability
- Manufacturing work orders
- Rework and disposition records
- Labeling and packaging records
- Release and distribution records
Together, TofuPilot and your QMS provide the complete DHR. The key is using consistent serial numbers across both systems so records can be cross-referenced.