एखादा रुग्ण “Disconnect My Data” लेबल असलेले बटण क्लिक करतो. वेब ॲप एक हिरवे टिक मार्क आणि एक आनंदी पुष्टीकरण (confirmation) दाखवते. बॅकग्राउंड क्यूमध्ये, कुठेतरी एक वर्कर प्रोसेस त्याच्या नाईटली सिंकसाठी जागा होते, काल तयार झालेली एक जॉब घेते आणि दोन वर्षांचा औषधांचा इतिहास (medication history) डाऊनस्ट्रीम ॲनालिटिक्स क्लस्टरला स्ट्रीम करण्यास सुरुवात करते. वापरकर्त्याने इंटरफेसवर विश्वास ठेवला होता. पण सिस्टिमने त्या विश्वासाचा विश्वासघात केला.

ही विशिष्ट त्रुटी (failure mode) आरोग्य डेटा आर्किटेक्चरमध्ये मोठी समस्या निर्माण करते कारण यामध्ये जोखीम खूप जास्त असते. कालबाह्य झालेली परवानगी (stale permission) ही केवळ एक किरकोळ त्रुटी नाही; तर तो एक सक्रिय डेटा ब्रीच आहे. याचे निराकरण म्हणजे प्रत्येक डेटा विनंतीला एका 'संमती पावतीशी' (consent receipt) जोडणे: एक लहान, संरचित रेकॉर्ड जे वापरकर्त्याचा हेतू UI पासून तुमच्या पॉलिसी इंजिनपर्यंत, तुमच्या डेटाबेस ट्रान्झॅक्शन्सपर्यंत आणि प्रत्येक बॅकग्राउंड वर्करपर्यंत पोहोचवते. यामध्ये क्लिनिकल व्हॅल्यूज कधीही साठवल्या जात नाहीत. ते फक्त त्या डेटाला ॲक्सेस करण्याचा अधिकार साठवते, ज्यावर एक व्हर्जन नंबर असतो जो पडद्यामागे गुपचूप बदलता येत नाही.

पावतीमध्ये प्रत्यक्षात काय असते

पावतीला एका 'स्कोपड कॉन्ट्रॅक्ट' (scoped contract) प्रमाणे समजा, केवळ 'सेशन फ्लॅग' (session flag) म्हणून नाही. यामध्ये एक ग्रँट आयडेंटिफायर (grant identifier), डेटा सब्जेक्ट, ॲक्सेसची नेमकी व्याप्ती (lab results, vitals, medication history), वेळेवर आधारित वैधता कालावधी (time-bound validity window) आणि एक व्हर्जन नंबर असतो. जेव्हा एखादा फ्रंटएंड वापरकर्त्याच्या वतीने ॲक्सेसची विनंती करतो, तेव्हा API ही पावती जारी करते. फ्रंटएंड ती पावती जवळ ठेवते. ज्या प्रत्येक डाऊनस्ट्रीम सर्व्हिसला आरोग्य डेटा वाचायचा आहे, तिला रेकॉर्ड उघडण्यापूर्वी मध्यवर्ती पॉलिसी लेअरला ही पावती सादर करावी लागते आणि तिथून स्पष्ट परवानगी घ्यावी लागते.

हे महत्त्वाचे आहे कारण आरोग्य प्रणाली अनेकदा युजर अकाउंट टोकनला संमती (consent) समजण्याची चूक करतात. टोकन सांगते की तुम्ही कोण आहात. पावती सांगते की तुम्हाला सध्या काय करण्याची परवानगी आहे. जर या दोघांमध्ये तफावत निर्माण झाली, तर पावतीचा निर्णय नेहमी अंतिम असावा.

प्रत्येक गोष्टीचे व्हर्जन ठेवा

तुमचे संमती स्टोअर (consent store) एक 'अपेंड-ओन्ली लॉग' (append-only log) म्हणून तयार करा. जेव्हा एखादा वापरकर्ता पहिल्यांदा त्यांच्या लसीकरणाच्या रेकॉर्डसाठी ॲक्सेस देतो, तेव्हा ते व्हर्जन एक असते. जर त्यांनी नंतर विशिष्ट प्रोव्हायडर्सना वगळून व्याप्ती मर्यादित केली, किंवा जर त्यांनी पूर्णपणे संमती काढून घेतली, तर पहिली नोंद ओव्हरराईट करू नका. त्याऐवजी व्हर्जन दोन लिहा. वर्करच्या हातात असलेली पावती अजूनही व्हर्जन एकच दर्शवेल, आणि पॉलिसी इंजिनला नेमके व्हर्जन एक काय परवानगी देत होते आणि ते एका विशिष्ट टाइमस्टॅम्पला बदलले गेले होते, हे स्पष्टपणे पाहता येईल.

ही 'इम्युटेबिलिटी' (immutability) तुमचा ऑडिट बॅकबोन आहे. सहा महिन्यांनंतर, जेव्हा एखादा कंप्लायन्स ऑफिसर विचारतो की एखादा विशिष्ट ETL जॉब गुरुवार दुपारी का चालला होता, तेव्हा तुम्ही तो जॉब कोणत्या ग्रँट व्हर्जनसह चालला होता याचा मागोवा घेऊ शकता आणि तो जॉब सुरू असताना वैध होता हे सिद्ध करू शकता. जर तुम्ही युजर प्रोफाइलमध्ये संमती केवळ एका सिंगल बुलियन फ्लॅग (boolean flag) म्हणून साठवली, तर तुम्ही तो इतिहास पुसून टाकता. "याला कधीच परवानगी नव्हती" आणि "जॉब सुरू असताना याची परवानगी होती पण दोन तासांनंतर वापरकर्त्याने आपला निर्णय बदलला" यातील फरक ओळखण्याची क्षमता तुम्ही गमावता.

प्रामाणिकतेसाठी एंडपॉइंट्स डिझाइन करा

एका संमती API ने स्पष्ट आणि विशिष्ट रूट्स (routes) उपलब्ध करून दिले पाहिजेत. POST /grants द्वारे नवीन परवानगी तयार होऊ द्या. GET /grants/{id} द्वारे विशिष्ट पावतीची सध्याची स्थिती मिळवा. POST /grants/{id}/revoke द्वारे संमती रद्द करण्याची प्रक्रिया सुरू करा. रिव्होक (revoke) बटण दाबल्यामुळे तुमच्या पाइपलाइनमध्ये असलेला आरोग्य डेटाच्या सर्व प्रती त्वरित पुसल्या जातील, असा आभास करू नका. त्याऐवजी, 202 Accepted स्टेटससह एक रिव्होकेशन ऑपरेशन आयडी (revocation operation ID) परत करा. यामुळे वापरकर्त्याला समजते की त्यांची विनंती खरी आहे, ती प्रक्रिया सुरू झाली आहे आणि ते तिचा मागोवा घेऊ शकतात.

जेव्हा इंटरफेस संथ वाटल्यामुळे वापरकर्ता दोनदा क्लिक करतो, तेव्हा तो ऑपरेशन आयडी अत्यंत महत्त्वाचा ठरतो. जर त्यांनी दुसरी रिव्होकेशन विनंती पाठवली, तर मूळ ऑपरेशन आयडीच परत करा. येथे 'आयडेम्पोटन्सी' (Idempotency) ही केवळ एक सोय नसून, ती दुप्पट गोंधळ टाळते आणि वापरकर्त्याला त्यांच्या विनंतीच्या स्थितीसाठी एकच 'सोर्स ऑफ ट्रुथ' (source of truth) प्रदान करते.

शक्य तितक्या शेवटच्या क्षणी परवानगी मागा

एक सामान्य चूक म्हणजे API गेटवेवर संमती तपासणे आणि नंतर वर्करच्या आत कॅश केलेल्या (cached) फ्लॅगवर विश्वास ठेवणे. असे करू नका. वर्करने त्याच्या जॉब लाइफसायकलमध्ये स्वतःची पावती सोबत ठेवली पाहिजे. आरोग्य रेकॉर्ड स्टोअरवर क्वेरी एक्झिक्युट करण्याच्या अगदी आधी, त्याने पॉलिसी लेअरला विचारले पाहिजे: "या विशिष्ट ग्रँटचे व्हर्जन तीन अजूनही या नेमक्या व्याप्तीसाठी वैध आहे का?" जर उत्तर 'नाही' असेल, तर वर्कर थांबला पाहिजे. तो जॉब फेल झाला पाहिजे. तो पुन्हा प्रयत्न (retry) करू नये.

येथे 'रिट्राय लॉजिक' (retry logic) विषारी ठरू शकते. व्हर्जनमधील तफावत ही नेटवर्कमधील तांत्रिक अडचण नाही. तो एक मानवी निर्णय आहे. वापरकर्त्याने संमती रद्द केली आहे, किंवा ग्रँटची वैधता संपली आहे, किंवा व्याप्ती कमी झाली आहे. जर तुम्ही तीन वेळा प्रयत्न केले आणि चौथ्या वेळी रेस कंडिशनमुळे (race condition) यशस्वी झालात, तर तुम्ही संमतीचे उल्लंघन केले आहे. या तफावतीला एक 'हार्ड फेल्युअर' (hard failure) म्हणून treating करा, ती तुमच्या डेड-लेटर क्यू (dead-letter queue) किंवा ऑपरेशन्स डॅशबोर्डवर पाठवा आणि मानवी तपासासाठी सोडा.

गुंतागुंतीच्या परिस्थिती हाताळा

वास्तविक प्रणाली शिस्तबद्ध टप्प्यांत काम करत नाहीत. वापरकर्ते जुन्या ब्राउझर टॅब्स उघडे ठेवतात. बल्क इम्पोर्ट्स (Bulk imports) वीस मिनिटे चालतात. सिंक (sync) अर्ध्यावर असताना स्कोप (Scopes) बदलतात. तुमच्या कन्सेंट API ला या क्षणांसाठी स्पष्ट नियमांची आवश्यकता आहे.

जुन्या (Stale) ब्राउझर टॅब्स. वापरकर्ता नुकत्याच उघडलेल्या टॅबमध्ये प्रवेश रद्द (revoke) करतो. जुना टॅब, ज्यामध्ये मागील पेज लोडचा 'ग्रँट ऑब्जेक्ट' (grant object) अजूनही आहे, पुन्हा कनेक्ट करण्याचा प्रयत्न करतो. तुमच्या बॅकएंडने (backend) तो जुना रिसिप्ट (stale receipt) त्वरित नाकारला पाहिजे आणि नवीन कन्सेंट रिव्ह्यूसाठी (consent review) भाग पाडणे आवश्यक आहे. रद्द केलेला ग्रँट (revoked grant) हा रद्द झालेल्या पासपोर्टसारखा असावा: धारकाला कपाटात जुनी प्रत सापडली म्हणून तो पुन्हा जिवंत होत नाही.

चालू असलेले इम्पोर्ट्स (In-flight imports). जर बल्क इम्पोर्ट सुरू असेल आणि वापरकर्त्याने प्रवेश रद्द केला, तर दोन गोष्टी एकाच वेळी घडणे आवश्यक आहे. पहिले म्हणजे, व्हर्जन (version) नाकारले जाताच नवीन 'writes' करण्यास परवानगी देणे थांबवा. दुसरे म्हणजे, ऑपरेशन आयडी (operation ID) द्वारे वापरकर्त्याला प्रत्यक्ष क्लिनअप प्रगती दाखवा. त्यांना एक सत्य स्थिती पृष्ठ (status page) द्या: “रद्द करणे स्वीकारले गेले आहे. अठरा प्रलंबित writes काढून टाकले जात आहेत.” ज्या ग्रँट व्हर्जनला आधीच अवैध (invalid) म्हणून चिन्हांकित केले आहे, त्याचा वापर करून वर्कर्सना डेटा कमिट (commit) करू देऊ नका.

स्कोपमधील बदल (Scope changes). समजा वापरकर्त्याने सुरुवातीला पाच वर्षांच्या इतिहासाचा प्रवेश दिला आणि नंतर तो सहा महिन्यांपर्यंत मर्यादित केला. मूळ ग्रँटमध्ये बदल (mutate) करू नका. व्हर्जन १ बंद करा, कमी मर्यादेसह व्हर्जन २ जारी करा आणि कोणत्याही सुरू असलेल्या प्रक्रियांना नवीन मर्यादेनुसार जुळवून घेण्यास (reconcile) भाग पाडा. जुने व्हर्जन तुमच्या लॉगमध्ये ऐतिहासिक तथ्य म्हणून राहील, जिवंत परवानगी (living permission) म्हणून नाही.

कडक सुरक्षा नियम (Hard Security Rules)

रिसिप्ट्स (Receipts) स्वतः संवेदनशील असतात, परंतु ते क्लिनिकल डेटा (clinical data) नाहीत. तुमच्या आर्किटेक्चरमध्ये (architecture) त्यांना वेगळे ठेवा. केवळ रुग्ण किंवा विशेषतः नियुक्त केलेली भूमिका—जसे की कायदेशीर पालक किंवा अधिकृत काळजीवाहू—च रिसिप्ट पाहू किंवा रद्द करू शकली पाहिजे. हे केवळ UI राउटिंग टेबलमध्येच नाही, तर डेटा लेयरमध्ये (data layer) लागू करा.

जेव्हा जॉब्स फेल होतात, तेव्हा तुमचे एरर लॉग्स (error logs) आरोग्य डेटा (health data) खेचून घेण्याचा प्रयत्न करतील. या प्रवृत्तीचा आक्रमकपणे प्रतिकार करा. एखादा वर्कर (worker) अवैध कन्सेंट रिसिप्ट सादर केल्यामुळे बंद पडला, तर ग्रँट आयडी (grant ID), व्हर्जन आणि एरर लॉग करा. वर्कर ज्या पेशंट आयडेंटिफायर (patient identifier), डायग्नोसिस कोड (diagnosis code) किंवा लॅब व्हॅल्यू (lab value) मिळवण्याचा प्रयत्न करत होता, ते कधीही लॉग करू नका. लॉगमधील आरोग्य डेटा बुरशीसारखा पसरतो: तो बॅकअप घेतला जातो, इंडेक्स केला जातो आणि तुमच्या सामान्य ॲक्सेस कंट्रोल्सना (access controls) बगल देणाऱ्या पद्धतीने विसरला जातो.

शेवटी, सिस्टम रिकव्हरी दरम्यान कधीही जुना सक्रिय ग्रँट (active grant) रिस्टोर करू नका. जर तुम्ही डेटाबेस रोलबॅक (roll back) केला किंवा असा स्नॅपशॉट (snapshot) रिस्टोर केला ज्यामध्ये ग्रँट टेबलचे रद्द करण्यापूर्वीचे व्हर्जन असेल, तर सेवा नवीन ट्रॅफिक स्वीकारण्यापूर्वी तुमच्या रनबुकने (runbook) ते पुनरुज्जीवित झालेले परवानग्या (resurrected permissions) आपोआप अक्षम (disable) केली पाहिजेत. ऐतिहासिक कन्सेंट स्थिती ऑडिट लॉगमध्ये (audit log) असावी, सक्रिय नियम संचामध्ये (active rule set) कधीही नाही.