Le FDA 21 CFR Part 820 exige que les fabricants de dispositifs médicaux maintiennent un dossier d'historique de dispositif (DHR) pour chaque unité produite. Capturer les résultats de test, les numéros de série, les mesures et les verdicts dans un enregistrement immuable correspond directement aux exigences FDA et ISO 13485.
Vue d'ensemble des exigences réglementaires
La traçabilité des tests de dispositifs médicaux se situe à l'intersection de deux référentiels. Les deux exigent des preuves documentées que chaque dispositif a été fabriqué et testé conformément aux procédures approuvées.
| Réglementation | Clause | Exigence | Où se trouve la preuve |
|---|---|---|---|
| 21 CFR 820.184 | DHR | Enregistrements démontrant que le dispositif est fabriqué selon le DMR | Enregistrements de test par numéro de série avec nom de procédure |
| 21 CFR 820.80 | Réception, en-cours, acceptation du dispositif fini | Activités d'acceptation avec acceptation/rejet documentés | Verdicts avec limites de mesure |
| 21 CFR 820.90 | Produit non conforme | Investigation documentée des non-conformités | Exécutions échouées avec détail au niveau des mesures |
| 21 CFR 820.180 | Exigences générales (enregistrements) | Enregistrements conservés pendant la durée de vie du dispositif ou 2 ans | Stockage cloud immuable avec rétention |
| 21 CFR 820.250 | Techniques statistiques | Techniques statistiques valides pour la capabilité | Cpk, cartes de contrôle, rendement au premier passage |
| ISO 13485 7.5.3 | Traçabilité | Enregistrements par unité ou lot tout au long de la production | Suivi par numéro de série, historique d'unité, liens de sous-assemblages |
| ISO 13485 8.2.4 | Surveillance et mesure | Preuves de conformité aux critères d'acceptation | Mesures avec unités, limites et verdicts |
Ce tableau indique où se trouvent les preuves. Ce n'est pas une déclaration de conformité : votre système qualité, votre validation et vos procédures sont ce qui satisfait la réglementation, les enregistrements de test n'en étant qu'une entrée. Les logiciels utilisés en production relèvent aussi du 21 CFR 820.70(i) : l'outillage lui-même doit être validé pour son usage prévu.
Structurer les tests pour la conformité DHR
Le DHR doit inclure les résultats de test prouvant que chaque dispositif a été fabriqué conformément à son dossier maître (DMR). Structurez vos tests OpenHTF de sorte que chaque procédure corresponde à un protocole documenté.
test_medical_device.py74 lines
# Test de production de dispositif médical aligné sur les exigences DHRimport openhtf as htffrom openhtf.util import unitsfrom tofupilot.openhtf import upload@htf.measures( htf.Measurement("impedance_channel_1") .in_range(minimum=980, maximum=1020) .with_units(units.OHM) .doc("Impédance d'électrode selon IEC 60601-1, canal 1"), htf.Measurement("impedance_channel_2") .in_range(minimum=980, maximum=1020) .with_units(units.OHM) .doc("Impédance d'électrode selon IEC 60601-1, canal 2"), htf.Measurement("leakage_current") .in_range(maximum=0.00001) .with_units(units.AMPERE) .doc("Courant de fuite patient, partie appliquée Type BF selon IEC 60601-1"),)def electrical_safety(test): test.measurements.impedance_channel_1 = 1002.3 test.measurements.impedance_channel_2 = 997.1 test.measurements.leakage_current = 0.000003@htf.measures( htf.Measurement("signal_accuracy_pct") .in_range(minimum=99.0, maximum=101.0) .doc("Précision de mesure par rapport à une référence traçable NIST"), htf.Measurement("noise_floor") .in_range(maximum=0.000005) .with_units(units.VOLT) .doc("Bruit rapporté à l'entrée, bande passante 0,05-150 Hz"), htf.Measurement("common_mode_rejection") .in_range(minimum=100) .doc("CMRR à 50/60 Hz, en dB"),)def signal_performance(test): test.measurements.signal_accuracy_pct = 99.8 test.measurements.noise_floor = 0.0000021 test.measurements.common_mode_rejection = 112.4@htf.measures( htf.Measurement("firmware_version") .doc("Version du firmware installé, doit correspondre à la révision du DMR"), htf.Measurement("self_test_result") .in_range(minimum=1, maximum=1) .doc("Auto-test du dispositif : réussi (1) ou échoué (0)"), htf.Measurement("battery_capacity_pct") .in_range(minimum=95) .doc("Capacité de la batterie par rapport à la capacité nominale"),)def system_validation(test): test.measurements.firmware_version = "3.2.1-release" test.measurements.self_test_result = 1 test.measurements.battery_capacity_pct = 98.7def main(): test = htf.Test( electrical_safety, signal_performance, system_validation, procedure_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # UUID de procédure du dashboard part_number="MD-100", ) test.add_output_callbacks(upload()) test.execute(lambda: "MD-2026-04-00192")if __name__ == "__main__": main()Installez-le avec pip install "tofupilot[openhtf]". Chaque mesure référence la norme applicable via .doc() et porte ses limites d'acceptation : l'enregistrement montre donc ce qui était exigé autant que ce qui a été mesuré.
Versionnez la procédure à chaque changement de limites. Un DHR n'est défendable que si vous pouvez dire quels critères d'acceptation s'appliquaient à une unité donnée le jour de son test, ce qui devient impossible une fois les limites déplacées sans marqueur de version.
Activités d'acceptation (21 CFR 820.80)
La FDA exige des activités d'acceptation documentées à la réception, en cours de fabrication et sur le dispositif fini. Exécutez des procédures séparées pour chaque étape, toutes avec le même numéro de série.
test_acceptance_stages.py64 lines
# Test d'acceptation en trois étapes pour la conformité FDA 820.80import openhtf as htffrom openhtf.util import unitsfrom tofupilot.openhtf import uploadRECEIVING_PROCEDURE_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"IN_PROCESS_PROCEDURE_ID = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"FINISHED_PROCEDURE_ID = "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz"@htf.measures( htf.Measurement("incoming_visual_pass") .in_range(minimum=1, maximum=1), htf.Measurement("incoming_dimension_check") .in_range(minimum=24.9, maximum=25.1) .with_units(units.MILLIMETRE),)def receiving_inspection(test): test.measurements.incoming_visual_pass = 1 test.measurements.incoming_dimension_check = 25.02@htf.measures( htf.Measurement("solder_paste_height") .in_range(minimum=0.10, maximum=0.15) .with_units(units.MILLIMETRE), htf.Measurement("component_presence") .in_range(minimum=1, maximum=1),)def in_process_inspection(test): test.measurements.solder_paste_height = 0.12 test.measurements.component_presence = 1@htf.measures( htf.Measurement("final_functional_test") .in_range(minimum=1, maximum=1), htf.Measurement("label_verification") .in_range(minimum=1, maximum=1),)def finished_device_acceptance(test): test.measurements.final_functional_test = 1 test.measurements.label_verification = 1def run_stage(phase, procedure_id, serial): test = htf.Test( phase, procedure_id=procedure_id, part_number="MD-100", ) test.add_output_callbacks(upload()) test.execute(lambda: serial)def main(): serial = "MD-2026-04-00192" run_stage(receiving_inspection, RECEIVING_PROCEDURE_ID, serial) run_stage(in_process_inspection, IN_PROCESS_PROCEDURE_ID, serial) run_stage(finished_device_acceptance, FINISHED_PROCEDURE_ID, serial)if __name__ == "__main__": main()Les trois étapes utilisent des procédures distinctes pour être suivies indépendamment, tandis que le numéro de série partagé les réunit sur un seul historique d'unité. En production, ce sont trois scripts sur trois stations, à des jours d'intervalle ; ils sont réunis ici pour rendre le motif visible.
La page de l'unité pour ce numéro de série affiche les trois étapes dans l'ordre, ce qu'un inspecteur demande à voir.
Produit non conforme (21 CFR 820.90)
Quand un dispositif échoue au test, la FDA exige une investigation documentée. L'enregistrement contient la mesure exacte qui a déclenché la défaillance, sa valeur et la limite dépassée.
Les exécutions échouées restent visibles dans l'historique de l'unité aux côtés de chaque retest : le cycle investigation, reprise, retest est donc traçable. Cela couvre le volet documentaire du 820.90. Les décisions d'investigation et de disposition elles-mêmes vivent dans votre système CAPA ; les données de test l'alimentent, elles ne s'y substituent pas.
Traçabilité des composants avec les sous-unités
La clause 7.5.3 de l'ISO 13485 exige la traçabilité des composants de chaque dispositif. sub_units est un champ de htf.Test(...) qui lie les numéros de série des composants au dispositif fini.
test_component_traceability.py30 lines
# Enregistrer les numéros de série des composants pour la traçabilité ISO 13485import openhtf as htffrom tofupilot.openhtf import upload@htf.measures( htf.Measurement("assembly_complete") .in_range(minimum=1, maximum=1),)def final_assembly(test): test.measurements.assembly_complete = 1def main(): test = htf.Test( final_assembly, procedure_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", part_number="MD-100", sub_units=[ {"serial_number": "SENSOR-2026-08812"}, {"serial_number": "PCBA-2026-04410"}, {"serial_number": "BATT-2026-11023"}, ], ) test.add_output_callbacks(upload()) test.execute(lambda: "MD-2026-04-00192")if __name__ == "__main__": main()Les numéros de série sont codés en dur ici pour la concision. Sur une vraie ligne, ils proviennent de scans collectés avant la construction du test, puisque sub_units est un argument du constructeur.
Si un fournisseur émet un rappel, la hiérarchie d'unités est ce qui vous dit quels dispositifs finis contiennent les pièces concernées, au lieu de mettre en quarantaine tout ce qui a été fabriqué sur une plage de dates.
Piste d'audit et exports
Les enregistrements soutiennent ce que demandent les auditeurs FDA et ISO 13485 :
- Dossier d'historique du dispositif. Chaque exécution de test pour un numéro de série, avec procédure, station, opérateur, mesures et résultat. Cela constitue la partie test du DHR.
- Capabilité du procédé. Valeurs Cpk et cartes de contrôle pour toute mesure, en appui du contrôle statistique selon 21 CFR 820.250.
- Analyse des défaillances. Pareto et histogrammes de mesures pour soutenir les investigations CAPA.
- Conservation des enregistrements. Stockage immuable, les enregistrements historiques n'étant pas modifiables via l'interface standard.
Exportez les données depuis le tableau de bord pour inclusion dans votre dossier DHR formel. Les enregistrements incluent horodatages, identifiants de station et toutes les valeurs de mesure avec leurs critères d'acceptation.
Vérifiez les durées de conservation au regard de votre propre exigence de durée de vie du dispositif, et gardez une voie d'export qui ne dépend pas d'un fournisseur unique. Les obligations du 820.180 survivent à tout outil particulier.
