COVID-19 住院患者即時動態(上)
DevOps 的實踐是一種組織文化與哲學的轉變,其中對內外在環境的迅速應變也是一個非常重要的議題,在 Covid-19 疫情嚴峻之際,筆者特別以「Covid-19 住院患者即時動態」為例,以兩上、下期來介紹,醫院是如何用運 DevOps 工具快速解決管理及臨床人員的痛點。
文/鄭重男
國內 Covid-19 疫情進入社區流行階段
衛福部於 5/16 宣布國內 Covid-19 疫情正式進入社區流行階段,眼看全國各地確診人數逐日上升,疫情開始自北向南逐漸蔓延,全國醫療院所無一不緊繃神經來面對這場人與病毒的戰爭。國軍高雄總醫院,身為高屏地區之區域教學醫院,平日除肩負國軍官士兵之健康維護外,也兼具守護一般民眾健康與就醫能量,在疫情嚴峻之時,醫院為了保全正常醫療量能,本院亦遵照中央流行疫情指揮中心與高雄市政府指揮,將全院 2.5 成病床轉為專責病房以因應隨時增加的確診住院人數。
隨疫情加遽,本院新冠確診需住院隔離人數也於 5 月底開始明顯增加,醫院專責病床數使用率逐漸上升,院長柯朝元將軍隨即指示全院各相關部門應妥善調度醫療資源,務必傾全力支援以面對此一挑戰。此時,如何即時得知普通病房是否有新的陽性個案出現,專責病房有哪些患者隔離期滿可轉出隔離病房者,病患住院動態的掌握及床位的調度,便成為控床人員一項極大的負擔與挑戰。
在本院專責病房患者人數急遽增加之際,奉院長指示負有專責病房調度之責的胸腔內科主任,便與筆者商討是否可以在每天早上,提供一份院內住院患者核酸檢驗陽性的患者清單,以便掌握確診人數及利於專責病床之調度,由於現行的醫療資訊系統(HIS)並沒有提供類似的查詢報表功能,一般常見的處理方式,就是額外撰寫資料庫語法,並將查詢結果存成 Excel 檔案,提供使用者自行運用。此一方式雖然可順利取得全院 PCR 陽性病患清單,但執行成效卻不甚理想,每天除了需要有資訊人力手動執行查詢外,使用者收到檔案後也要再自行加工篩選,一旦遇到出完報表後,又因病房隨時會有新的病例增加,加上患者的資料異動,調度人員可能產生 24 小時的空窗期,進而影響專責病房調度及輪轉率。
就這樣給了兩天的 Excel 檔案後,筆者開始思考是否可以使用前一期文章中提到 DevOps 方式,以開發快速著稱的 Rails 來開發一個即時動態看板,於是便打了個電話詢問胸腔科主任,此 PCR 陽性住院人數明細報表的需求,預估會維持多久時間?主任思考了一下答道:「至少一個月」。雖然時間不長,但試想,若可以用最簡單的功能及最小可用版本,開發一個網頁應用系統,只要可以減輕一點點臨床或住院服務人員負擔(Optimize for staff happiness),就該值得去做,也符合 Rails 「快樂優先的基本主義(Optimize for programmer happiness)」,更可藉此驗證 DevOps 和極限程式設計(XP)方法,在於醫院數位轉型的實踐。
極限程式設計(Extreme programming,XP)
XP 是一種敏捷開發的方法,其實踐原則在於鼓勵團隊以最簡單快速的方式完成當下專注的功能或任務,簡單來說,就是把軟體生命週期(System Development Life Cycle,SDLC)的迭代過程盡可能的壓縮,使之變得更為快速。因此,它可能不會完全依照標準的 SDLC 模式進行,而是在開發過程中允許使用者需求不斷變動、回饋、修改與重構。
Rails 其實也算是一個 XP 的開發框架,由於開發速度很快,很多新創團隊都喜歡用它來作為新點子的概念驗證(Proof Of Concept,POC)或直接快速迭代出全新的產品。在國外,有經驗的 Rails 開發者(可獨立完成專案者)之薪資水準也一直都位居榜首,大約是其他程式語言開發者的 1.5 倍左右,原因就在於它可以讓你在最短的時間及更少的人力,完成一個可上線運行的網頁應用系統。
一般來說,Rails 是屬於後端(資料庫)的開發框架,對於網頁前端(頁面顯示及操作體驗),通常是打包其他如 Vue、React 或 Angular 之類的 Javascript 框架來處理,坦白說,對一個前端不是非常熟悉的人來說,是真的有點不那麼友善,也是後來有些人從 Rails 跳槽跑去寫前端的原因之一。但據筆者觀察認為,去年耶誕節的時候,Rails 發布了 7.0 版,原開發者 DHH(David Heinemeier Hansson)替 Rails 量身打造了一個輕量型的前端框架 Hotwire(Html Over The Wire),並以它作為 Rails 預設的前端框架,我覺得事情就變得不大一樣了。
DHH 希望藉由 Hotwire 讓 Rails 開發者在完全不用改變既有的開發模式,不再需要額外的前端框架,也不需使用 JSON 與前端溝通,而直接用瀏覽器本來就可以看懂的 HTML 取代。因此,開發者僅需撰寫很少的 Javascript,甚至可以完全不寫的情形下,也可以做出類似單頁式的應用程式(Single-Page Application,SPA)或不用重新整理頁面就可以指定更新頁面中一部分資料的前端效果。這也是筆者選擇使用 Rails 7.0 來開發 「Covid-19 住院患者即時動態」專案的主要原因。
最小可用產品(Minimum Viable Production,MVP)
最小可用產品(MVP)和極限程式設計(XP)的特性是一致的,其目標都是:「使用最低的成本及最短的時間,讓使用者故事(需求)上線運作」,直接讓使用者檢驗結果是否有如預期,再經由使用者的意見回饋不斷地修正與調整,甚至允許衍生其他新的想法,快速迭代出一個真正面向使用者需求的系統。
因此,以本文提到專案來說,一開始我們只需要專注在解決病房調度人員的需求即可,也就是應該要讓病房調度人員,隨時可取得本院目前確診病患動態。其他,隨著使用時間增加及大環境各項內外在因素的改變等,慢慢的,需求就會自己找到出口,無論是需求新增、轉變或開發者突如其來的靈感,都會在迭代循環中自然而然地重複發生,完全符合我們用無限循環符號(∞)來代表 DevOps 的意涵。
使用者故事
基於前面所述,我們就來看看這個專案的使用者故事應該會是什麼樣子?
- 身為「專責病房調度者」,我想要知道即時的「全院核酸檢驗陽性的住院患者」,以利「病床調度」。
- 身為「住院服務人員」,我想要知道「在各普通病房的患者被檢出陽性的住院患者」,以利儘速「轉入專責病房」。
- 身為「住院服務人員」,我想知道「在專責病房的患者已經住滿八天」,以利將其「轉出到緩衝病房」。
基於極限程式設計與最小可用產品原則,要能快速解決讓控床人員的痛點,一開始不需要講太多「故事」,而是要思考的是多快可以上線使用?因此,一開始筆者就沒有打算花太多時間寫出一堆天馬行空的「故事」,而把時間留給盡快讓使用者有系統可以使用。
主頁面流程
當第一版使用者故事確定後,就可以使用任何你熟悉的工具如:Word、Powerpoint、Draw.io 或甚至簡單的紙跟筆,畫出一個主頁面流程草圖(圖1)。
從主頁面草圖中,我們可以知道網頁主要畫面上方應要有三個字型較大的數字,分別用來顯示 PCR 檢驗的總人數、陽性確診人數及專責病房已達 8 天的人數。另一方面(草圖左半部),為了要讓頁面可以自動更新資料(戰情看板模式),我們還要另外寫一個資料庫語法(Structured Query Language,SQL),用來擷取全院住院患者最新 PCR 檢驗結果,並設定其每十分鐘執行一次。
資料表模型
Rails 以開發快速著稱,一部分原因在於它的資料庫的操作方式與一般程式開發常見的作法不大一樣,一開始你幾乎可以忽略(SQL)語法,只要專注在你的醫療或臨床的商業邏輯即可,你可以想像一下,當你在使用 Excel 工作表之間的關聯時,其實也沒有知道太多它底層運作的原理。同樣地,Rails 只要把資料模型(Model)的關聯建立好就可以了,Rails 會自動幫你做 SQL 的轉換並回應你要處理(Create、Read、Update、Destroy,CRUD)資料庫的操作。
Rails 還有一件非常值得一提的特性,就是資料庫遷移(Migrations),我們之前說過,資料庫就像醫院系統的心臟,一般傳統的開發模式,程式撰寫跟資料庫的設計是分開處理的,當一個系統不管是需求的變更或是版本迭代需要,一定會有資料庫異動或新增欄位的需求,因此,我們就常常聽到使用者抱怨說系統更新後,就跳出欄位不足或資料型態不一致的錯誤,輕則僅影響部份系統功能,重則整個系統炸鍋。
我們來看看 Rails 是如何避免類似的問題發生的,Rails 對於資料表的新增或異動,會自動依據系統時間產生一個遷移(migration)檔案,在系統啟動的過程中,若發現遷移版本不一致就會跳出要求執行遷移的提示,所以,在開發環境中,若沒有執行資料庫遷移(migrate),你是無法繼續開發下去的,錯誤在還沒進入測試環境時就已經被抓出來,更不用說要跑去到正式環境了。這樣的好處是,在多人協同開發專案時,不管哪一個開發者對資料庫做了異動,資料庫遷移版本永遠都會一致,因此,就可以完全避免上述資料庫不一致的錯誤發生。基於這個特性,不管對系統維運(Ops)或品質管理(QA)來說絕對是一大優勢,也是吸引筆者使用 Rails 的另一個原因。
本專案因為需要從既有的 HIS 資料庫定時轉出資料,因此,一開始只需要一張資料表就夠了,如圖2所示。除了紀錄原來 HIS 的住院資料及檢驗結果之外,還自行增加一些系統會使用到的欄位,如:「專責病房否?」(HIS 原本沒有的欄位),作法跟一般資料分析常用的資料清洗(Data cleansing)類似,目的就是為了前端介面(UI)的顯示及邏輯的判斷。
建立專案
要建立一個新的專案,我們只要在已經安裝好 Rails 環境的電腦,開啟終端機程式,並執行下面的語法,就可以建立一個名為 covid19 的專案了。
rails new covid19 -c tailwind -d postgresql
- -c tailwind 代表 css 要使用 tailwind(也可以使用其他如 bootstrap 或其他 css)。
- -d postgresql 代表資料庫要使用 postgresql。
版本控制
DevOps 實踐哲學中,版本控制(Git)是一個必要的元素,因此,我們通常會在建立專案之後,就將專案做 Git 儲存庫(Repository)的初始化(Initialize),並將新建立出來的專案程式碼推進去(Push),你可以選擇使用公有雲的 Github 或像筆者一樣自行用 Gitea 建立的落地服務。如圖3所示。
從 Git 的紀錄來看,我們幾乎只用了一天(6/1)的時間,就把第一版使用者故事完成,並實際在醫院內部的測試環境上線使用,也完全符合了極限程式開發與最小可用產品的設計原則。
即時動態看板
如圖4所示,是上線使用的主要頁面,也如預期在最短的時間內,順利的讓病床調度人員使用醫院內部網路的任何一台電腦的瀏覽器(Chrome),連到測試主機進行數字正確性及功能驗證。此系統除了定時於每十分鐘自動更新資料的基本功能外,又陸續補了一些功能,如:因應臨床可能隨時需要更即時的資料的「手動更新」按鈕功能。之後,如同前面所述,不斷有修正、功能新增以及各種發布的相關細節,我們就留待下集再談。
(本文授權非營利轉載,請註明出處:CIO Taiwan)