Comment construire un Device History Record avec TofuPilot
Le Device History Record (DHR) est un document obligatoire pour les dispositifs médicaux réglementés par la FDA. C'est l'enregistrement de production complet pour chaque dispositif fini : ce qui a été fabriqué, comment il a été testé et quels ont été les résultats. TofuPilot fournit automatiquement la composante données de test du DHR.
Ce que la FDA exige
Le 21 CFR 820.184 (Device History Record) exige la documentation de :
| Composante du DHR | Ce qu'elle inclut | Rôle de TofuPilot |
|---|---|---|
| Dates de production | Quand le dispositif a été fabriqué | Horodatages des exécutions de test |
| Quantité fabriquée | Combien dans le lot/batch | Nombre d'exécutions par batch |
| Enregistrements d'acceptation | Résultats de test prouvant la conformité | Toutes les mesures avec limites |
| Étiquette d'identification primaire | Numéro de série, UDI | Numéro de série de l'unité testée |
| Étiquetage | Étiquettes utilisées sur le dispositif | (Hors périmètre TofuPilot) |
| Équipements utilisés | Stations de test, état de calibration | Identification de la station |
Les données de test comme preuve du DHR
Chaque exécution de test dans TofuPilot est un enregistrement de preuve pour le DHR. Pour chaque numéro de série de dispositif, TofuPilot stocke :
from tofupilot import TofuPilotClient
client = TofuPilotClient()
# ICT (test in-circuit)
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},
],
}],
)
# Test fonctionnel
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},
],
}],
)
# Sécurité électrique
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},
],
}],
)
# Inspection finale
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},
],
}],
)Compiler le DHR
Recherchez par numéro de série dans TofuPilot pour récupérer tous les enregistrements de test d'un dispositif.
Pour le dispositif MD-2025-00421, la section test du DHR affiche :
| Test | Date | Résultat | 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 |
Chaque ligne renvoie aux données de mesure complètes : chaque valeur, chaque limite, chaque statut pass/fail.
Gestion des non-conformités dans le DHR
Lorsqu'un dispositif échoue à un test et est retravaillé, le DHR doit montrer :
- La défaillance originale (quelle mesure, quelle valeur)
- La décision de disposition (retravail, mise au rebut, utilisation en l'état)
- Le résultat du retest après retravail
TofuPilot capture automatiquement les points 1 et 3. Pour le point 2, documentez la disposition dans votre SMQ et faites la référence croisée avec l'identifiant d'exécution TofuPilot.
# Test original en échec
# ID d'exécution : run-001 (fuite patient à 12,3 uA, limite 10 uA)
# Après retravail (connecteur remplacé), 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},
],
}],
)Le DHR de ce dispositif affiche maintenant : l'échec original, la disposition de retravail (depuis le SMQ) et le retest réussi.
Rapports DHR par lot
Pour la libération de lot, récupérez tous les dispositifs d'un lot de production et vérifiez l'exhaustivité des enregistrements de test.
from tofupilot import TofuPilotClient
client = TofuPilotClient()
# Procédures requises pour un DHR complet
required_procedures = [
"ICT-MEDICAL-BOARD",
"FUNC-CARDIAC-MONITOR",
"SAFETY-IEC60601",
"FINAL-INSPECTION",
]
# Vérifier tous les dispositifs du lot
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)} dispositifs ont des DHR incomplets :")
for d in incomplete:
print(f" {d['serial']} : manquant {d['missing']}")
else:
print("Tous les dispositifs ont des DHR complets. Lot prêt pour la libération.")Conservation et récupération
La FDA exige la conservation du DHR pendant la durée de vie du dispositif plus des années supplémentaires. TofuPilot stocke toutes les données de test avec horodatages et pistes d'audit. Configurez votre politique de conservation des données en fonction de vos exigences réglementaires.
Lorsque la FDA demande le DHR d'un dispositif spécifique lors d'une inspection, recherchez par numéro de série et exportez l'historique de test complet. Des enregistrements structurés, horodatés et immuables remplacent les classeurs papier et les fichiers Excel.
Intégration avec votre SMQ
TofuPilot gère la composante données de test du DHR. Votre SMQ (système de management de la qualité) gère :
- La nomenclature et la traçabilité des composants
- Les ordres de fabrication
- Les enregistrements de retravail et de disposition
- Les enregistrements d'étiquetage et de conditionnement
- Les enregistrements de libération et de distribution
Ensemble, TofuPilot et votre SMQ fournissent le DHR complet. L'essentiel est d'utiliser des numéros de série cohérents dans les deux systèmes pour que les enregistrements puissent être croisés.