OpenDolphin HTML/PDF Viewer プロジェクト

 

はじめに

以前に Save the DolphinS というプロジェクトをやっていた。

OpenDolphin という電子カルテは、データ構造に癖があり、カルテ記載内容の抽出ですら、それなりに難しい。
そのため Save the DolphinS では、データベースに直接アクセスしてデータの抽出を行うソフトの作成を行なっていた。ソフトは -味も素っ気もない言い方だが-「データ移行ツール」と呼んでいた。

「データ移行ツール」は dolphin データベースに直接アクセスして、一応

・カルテ記載内容全履歴→プレーンテキスト(画像などの特殊タグ付き)+画像など

・カルテ記載内容全履歴→ rtf 形式ファイル(画像などの特殊タグ付き)+画像など

に抽出するところまではできていた。

OpenDolphin 本体はおろかアプリケーションサーバである WildFly がなくてもデータベースさえ活きていれば、このソフト単体で動作してデータ抽出が行えるのでそれなりに重宝していた。

ただ、これだと、データを他のシステムに移行する場合には便利でも、たとえば保管はしておきたいが閲覧だけでいいという場合、視認性の面で今ひとつの感は拭えない。

何かうまい解決方法はないかなと思っていたのだが、ひょんなことから移行ツールの出力を html 形式で書きだせばいいことに気がついて、ソースコードを改変して試してみたところ、まずまずうまく動いた。

細かいところでさらに修正したいところはあるのだが、例えば、以下のカルテ画面(↓)

を、html 形式で書き出すとこんな感じになる。

 

2号用紙風のレイアウトやフォントの属性、画像の添付位置までほぼ完全に再現されていると思う。

データ抽出というコンセプトは同じでも、(移行を考慮して)データをテキストと画像などに分離させて出力するのと(閲覧性を重視して)それらをを html にまとめるのは、使用目的の点で微妙に異なる。

また、この機能を移行ツール内に同居させておくのは、ソースコード管理の面でも何かと不便だ。

そこで、この機能を分離させ、単独のソフトとして独立させることにした。

今後はこちらを

OpenDolphin Viewer
OpenDolphin HTML Viewer
OpenDolphin HTML/PDF Viewer (PDF 出力にも対応したため改名)

と呼ぶことにする。

 

開発グループを代表して
猪股弘明

背景色を変更

実務的にはまるで意味がないのだが、白背景は味気ない気がするので背景色を OpenDolphin 特有の薄い緑( dolphin’s green というのだそうだ)に変更。

ドルフィン感が強くなった。

 

レスポンシブ対応

最近のウェブデザインは凝っていて、ブラウザの横幅を変更するとレイアウトを自動で調整してくれる。レスポンシブデザインなどというようだ。
この仕組みのおかげでPCのブラウザでもスマフォのブラウザでも、それなりに「見れる」レイアウトになっている。
これを狙って CSS を若干修正。

通常時がこうだとすると

ブラウザの横幅を縮小させるとある値(ブレークポイント)を境に右のいわゆる P 欄が左(SOA欄)の下に回り込む。

スマフォで閲覧することなどないかもしれないが。

 

P 欄(カルテ右半分)の検討

これまで、カルテの右半分(P 欄)は文字情報だけ抜いてきたが、実は処置・薬剤のレセ電コードも抜ける。

まだ、うまくまとめきれてないのだが、かなり雑にデータを書き出すとこんな具合になる。

赤枠で囲んだ部分が処置や薬剤の識別子(コード)で、その多くはレセ電コードと同一なはずだ。

実運用としては、ドルフィンから処置内容を ORCA に送った際に、この情報を受け取った ORCA はこれらコード番号に基づいて保険点数や窓口負担額を計算し、最終的にはレセプトに反映させている。

病院のシステムを入れ替えた際に、よくこのコードが引き継げなくて処方内容を一から打ち込むことがよくある。とても負担だ。

本プロジェクトはデータの「閲覧」を強く意識しているが、上記の点に留意し P 欄に関しては若干レイアウトを崩してもこれらコードが表示できるようにしたいと考えている。

P 欄(カルテ右半分)の検討(続き)

通常 P 欄に記載される内容は、診断料や処方のほか各種検査のオーダーなどもある。
だから、まずドルフィン元カルテをこんな風にした。

カルテ左の SOA 領域よりも難しいのは、項目毎に処理を変えなくてはいけない点。

ここら辺、工夫してコードを修正。
現状だとこのようになっている。

プロトタイプとしては、十分な出来だろう。
なお、レセ電コードは、某所で聞いて見たところ「あったほうがいい」ということだったので、多少元カルテの表示と異なってくるが、表示させることにした。

また、この改変を機に元の OpenDolphin のコードは全て削ぎ落とした。
単純に表示させるだけなら、

dolphin データベース >> 読み込み >> オブジェクトの生成 >>
適当に修正して html 用に変換 >> 書き出し

とやった方が楽なのだが、P 欄に関してはレセ電コードを打ち出せるようには構成されていないので、結局、ここら辺のコードは全て廃棄した。
(SOA 欄は特殊タグを表示させる関係上、移行ツールの頃から使っていない)

html → PDF 変換

ところで、OpenDolphin の標準のカルテ画面の PDF 文書作成機能は、文字などもベクトルデータに変換していわば「画像」として PDF を生成しているようだ。
Mac の場合、フォントの関係(物理フォントと論理フォントというものがある)でデフォルトでは文字化けしてしまう。

そちらの修正はひとまずおいて、html → PDF 作成ができないか検討。

あれこれやっていたら、以下のように
フォント埋め込み形式の PDF が生成できた。

データ移行に関する厚労省の見解

実は、公式な文書はない。

ガイドラインの要請からして

・カルテ記載の文字情報や診断の根拠となったような画像の類

・処置内容の文字情報

・修正履歴や途中経過版

は最低でも移行しなければならないでしょう。

口頭でもそれっぽいことは言っていた。

現在、問い合わせ中です。

 

OpenDolphin は『真正性』すら満たしていないかもしれない

以前にもサーバの API を通して偽造カルテをデータベースに入れ込む、みたいなことをやったのだが、

今度はもうちょっと巧妙なカルテの改竄(対策)を考えてみる。

OpenDolphin では、hibernate というORMを使って、「カルテを修正したときは、元のバージョンは消去せず、必ず新しいバージョンを作る」ということで改竄を防止している。
なのだが、これは「データベースにアクセスするときは hibernate を使う」というのが大前提になっている。
実際のカルテ実体のデータは、データベースの blob 領域というところに保存されている。当たり前だが blob オブジェクトには hibernate を使わずともアクセスできる

最も単純な例を考えてみよう。
id=11 のレコードに blob で test と書き込む。

ところが、このときの oid(lob への一種のポインタみたいなものです)は、データベースに直接問い合わせることで知ることができる。

このときは 47410。

この値を使って、blob を書き換えることは可能だ。
‘test’ は16進数表記だと 0x74657374 になるのだが、これを 0x74747474 に変更する。
hibernate を使って id=11 のレコードを再度復元すると該当する blob は ‘tttt’ (0x74747474)となっている。

実際は、blob を書き換えた時に oid も変更されてしまうので(47410 → 47412 に変化している)、よくできた管理者であれば、この異常に気がつくと思うが、そうでない人ならば、改竄されたところで気がつきもしないだろう。

OpenDolphin はソースコードが公開された時点では「データ構造が複雑なので、真正性は担保されている」みたいなことが言われていたが、データ構造が複雑だからといって、それは解読不能ということでも、想定していた方法以外での操作が不可能ということでもない。

思うのだが、データベースなどの何らかのストレージに医療記録を平文で「普通」に記録する方式はもうそろそろ限界なのかもしれない。

かといって、ブロックチェーンみたいな話をいきなりされてもなあ。。。という感じで、ここら辺は難しいところですね。


ところで先ほど openEHR というオープンソースの EHR のサイトを覗いてきたが、ここら辺は配慮がされているようで、記録は persistence layer という一種の抽象化されたレイヤーを通して行うようだ。
要するに永続化の手段まで具体的に決めてしまうと、そのセキュリティホールを突いて記録を改竄する輩が出てくるため、特定のストレージに限定しないということなのだろう。

ところで、openEHR はけっこう間違った情報が流れているみたいですね。よく PHP で書かれて、みたいな紹介のされ方しているが、普通に Java コードも確認できたけど?

 

猪股弘明

 

Java hibernate を利用した PotsgreSQL LOB の取り扱い

以前に OpenDolphin-2.7m という電子カルテのプロジェクトをやっていたとき、ユーザー(大半は医師の方々)の理解がアヤしいと感じた箇所は LOB のあたり。

一般的に『データベース=巨大なエクセル』みたいな説明がなされているので、「電子カルテの実体は LOB 領域に永続化されています」と言って即座に理解できる医師はそう多くなかった。

OpenDolphin 自体のデータ構造がかなりわかりにくく、コーディングもかなり「正統派」スタイルだったため、敷居が高かったせいもあるのかもしれない。

PostgreSQL の LOB に関しては、sql ・jdbc などのドライバ・ORM (Java であれば hibernate)などを介して操作できる。

プログラミング言語を介して LOB を操作するのであれば、やはり ORM を使うのが一番楽だと思う。

最もシンプルな書き方は以下の通り。


@Entity
public class Lobs implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String content;
    
    @Lob
    private byte[] binarylob;
        
    @Lob
    private String charlob;

    (以下、セッター・ゲッターなどを定義)

適当な名前の String と byte[] を用意して @Lob アノテーションを付ければ、hibernate はこれを LOB (それぞれ clob, blob になる)として取り扱ってくれる。

プロジェクトが適切に構成されていれば、アプリ起動時に hibernate は class Lobs に対応したテーブル lobs を自動で作成してくれる。

実際に得られたテーブルは以下の通り。

この書き方だと

・blob, clob とも oid 型になる

・String は character varying(255) となる

のが「へえ」という感じだ。

 

次回は、lob の書き込み/読み込みの具体的な方法あたり。

 

猪股弘明

 

保護中: tomcat FAQ

このコンテンツはパスワードで保護されています。閲覧するには以下にパスワードを入力してください。