Како препишав специфичен софтвер од Clipper во Tauri [WORKFLOW]

Технички post-mortem за миграција на специјализиран систем за молекуларна генетика и кариотипирање. CA-Clipper 5.2 / dBASE III+ › Tauri 2 + Rust + React + PostgreSQL 16.

Проектот е правен за клиент од USA, документиран секој чекор. Детали, демо и слики од самиот софтвер нема да споделам поради NDA.

Стар јазик: CA-Clipper 5.2   |   Стара база: dBASE III+ .dbf   |   Траење: 6 месеци   |   Мигрирани варијанти: ~290 000


1. Контекст и проблем

Лабораторијата работеше на две паралелни насоки: цитогенетика (кариотипирање) и молекуларна генетика (детекција на точкести мутации, мали инсерции и делеции). Стариот Clipper систем беше напишан во 1991 година, прво само за кариотипирање. Со текот на годините, молекуларните анализи беа додавани преку нови .dbf датотеки без централна архитектура. До 2025, системот имаше 17 неповрзани .dbf датотеки и ниту еден foreign key.

ROOT CAUSE При concurrent write од две машини, последниот кој ја затворал .dbf датотеката ги презапишувал промените на другиот позадиснки, без грешка.

ОРИГИНАЛНА СТРУКТУРА НА .DBF ДАТОТЕКИТЕ

ДатотекаНаменаЗаписиКритичен проблем
PATIENT.DBFДемографија + фамилија31 240Pedigree само како слободен текст
KARIOTYPЕ.DBFISCN нотација на кариотип28 900Без валидација на ISCN синтакса
MUTATIONS.DBFДетектирани мутации189 400HGVS нотација рачно внесена, без стандард
GENES.DBFЛиста на гени847Без поврзување со OMIM/HGNC
PANELS.DBFГенски панели94Без верзионирање на панели
REAGENTS.DBFPCR реагенси и primers3 120Без lot-tracking по анализа
PATOL.DBFКлинички фенотипови12 600Слободен текст наместо HPO термини

ГЛАВЕН ТЕХНИЧКИ ПРОБЛЕМ Нема ниту еден unique constraint, ниту еден foreign key, ниту валидација на HGVS нотација. Истата мутација беше запишана на 6 различни начини: c.5266dupC, 5266dupC, c.5266insC, BRCA1 ins 5266 итн.

2. Нова архитектура: PostgreSQL schema

Дизајнот на новата база беше раководен со два стандарди: HGVS нотација за сите варијанти и HPO термини за клиничките фенотипови. Без тоа, никаква интеграција со ClinVar или OMIM не е возможна.

ГЛАВНИ ТАБЕЛИ

patientТипБелешка
iduuid PK 
ssnvarchar(13) UNIQUEЕдинствен матичен број
sexchar(1)M / F
dobdate 
proband_iduuid NULLABLE FK(self)За фамилијарно групирање
ethnic_grouptextЗа внатрешна AF калибрација

variantТипБелешка
iduuid PK 
gen_iduuid FK 
hgvs_ctext NOT NULLНормализирана HGVS нотација
hgvs_ptext NULLABLEПротеинска нотација
rsidvarchar(20)dbSNP идентификатор
acmg_classacmg_enumPATHOGENIC / VUS / BENIGN…
clinvar_idbigint NULLABLE 
gnomad_afnumeric(10,8)Алелска фреквенција

patient_variantТипБелешка
iduuid PK 
patient_iduuid FK 
variant_iduuid FK 
zygosityzygosity_enumHET / HOM / HEMIZYGOUS
heredityheredity_tipDE_NOVO / MAT / PAT
detection_methodtextNGS / SANGER / MLPA
reagent_lot_iduuid FKЗа трасабилност

reference_valuesТипБелешка
iduuid PK 
analysis_iduuid FK 
sexchar(1) NULLABLENULL = важи за сите
age_fromint NULLABLE 
age_toint NULLABLE 
min_valnumeric(10,3) 
max_valnumeric(10,3) 

PostgreSQL DDL   Enum типови и партиционирање


3. Фаза 1: HGVS нормализација пред миграција

Пред да се пренесе ниту еден запис, беше неопходно да се нормализираат 189 000 мутациски записи. Истата варијанта постоеше во 6 до 12 различни текстуални форми. Без нормализација, базата би наследила хаос.

Python 3.12   HGVS нормализација преку Biocommons hgvs библиотека

КЛУЧЕН НАОД: По нормализацијата, беа идентификувани 34 пациенти чии варијанти беа класифицирани поинаку поради inconsistent HGVS нотација. Тоа се 34 случаи каде стариот систем потенцијално носел погрешна клиничка информација.


4. Фаза 2: VCF парсирање во Rust

Новата лабораторија добива резултати во VCF формат директно од NGS секвенцерот. Стариот систем нема концепт за тоа. Новиот Tauri backend имплементира VCF pipeline директно во Rust преку noodles crate.

Rust + noodles   src-tauri/src/commands/vcf.rs


5. ACMG класификација на варијанти

Ова е централната нова функционалност. ACMG (American College of Medical Genetics) дефинира 28 критериуми за класификација на секоја варијанта. Стариот Clipper систем немаше никакво знаење за тоа.

Rust   src-tauri/src/acmg.rs – AcmgScore::classify()


6. Фамилијарен pedigree: de novo детекција

Стариот систем го чуваше фамилијарниот контекст само во текстуалното поле HISTORY (ANAMNEZA). Новата структура ги поврзува пациентите во фамилијарен граф преку self-referencing табела. Варијанта е de novo ако не постои ниту кај мајката ниту кај таткото.

PostgreSQL   De novo детекција преку recursive CTE

ПЕРФОРМАНСИ Query за de novo детекција на 31 000 пациенти преку recursive CTE: 340ms на PostgreSQL 16 со composite индекс. На истите податоци во .dbf формат, истиот резултат траеше повеќе од 4 минути преку Clipper SEEK loop.


7. Tauri архитектура: логика и IPC

Tauri апликацијата е два одвоени runtime-а кои комуницираат преку строго дефиниран IPC канал. Core процесот е Rust бинарен со целосен OS пристап. WebView процесот е системски браузер кој ги рендерира React компонентите. WebView не може директно да допре до filesystem или мрежа без Rust да одобри.

APPSTATE И DEPENDENCY INJECTION

Rust   src-tauri/src/state.rs

EVENT SYSTEM: RUST EMIT, REACT LISTEN

VCF импортот може да трае минута-две. Наместо блокирање, Rust емитира прогрес-настани, React ги слуша и ажурира UI во реално време. Нема polling, нема websocket, нема Redux middleware.

TypeScript + React   src/components/VcfImport.tsx

ТИПИЗИРАНИ ГРЕШКИ НИЗ ЦЕЛИОТ STACK

Rust   src-tauri/src/errors.rs

ISCN PARSER: RUST + NOM

Секоја кариотипска анализа мора да биде во ISCN 2020 формат. Стариот Clipper систем немаше никаква валидација. Новиот имплементира Rust parser со nom комбинатор библиотека. Записот не може да се зачува додека нотацијата не е валидна.

Rust + nom   src-tauri/src/kariotyp/iscn_parser.rs

CAPABILITY SECURITY МОДЕЛ

Tauri 2 воведе capability систем. Секоја capability е JSON фајл кој дефинира точно кои пермисии се дозволени. За LIMS: дозволен е пристап само до конкретни директориуми.

JSON   src-tauri/capabilities/lims.json

ЗОШТО Е ОВА ВАЖНО Ако напаѓач инјектира малициозен JavaScript преку XSS во некој VCF коментар, тој не може да чита датотеки надвор од $TEMP и lab_data. Electron нема еквивалентен механизам без значителна дополнителна конфигурација.


8. Зошто баш Tauri: образложение на одлуката

Изборот на технолошки stack за медицински софтвер не е само технички, туку и регулаторен и оперативен. Во овој дел ги објаснувам конкретните причини зошто се одлучив за Tauri 2 и PostgreSQL, кои алтернативи ги разгледував сериозно, зошто ги отфрлив, и во кои сценарија би избрал поинаку.

ФИКСНИ БАРАЊА

БарањеОписСтатус
Работи офлајнАпликацијата мора да работи целосно без мрежаКритично
Linux апаратВграден Linux до NGS секвенцерот, 4 GB RAMКритично
ISO 15189Секоја промена на податок мора да биде трасабилнаКритично
Еден dev, долг рокЗрела технологија, без vendor lock-inВажно

LINUX АПАРАТ ДО СЕКВЕНЦЕРОТ: ОДЛУЧУВАЧКИ ФАКТОР

Покрај болничките работни станици под Windows, постоеше уште едно целно опкружување кое во голема мера ја запечати одлуката. Лабораторискиот секвенцер е поврзан со вградена Linux машина со само 4 GB RAM. На неа треба да работи истата апликација за прием на VCF резултати и нивен внес во базата. Тоа беше барање кое ниту еден друг candidate не го исполни без сериозни компромиси.

На машина со 4 GB RAM, Tauri апликацијата при старт зафаќа 42 MB RAM. Секвенцерот, PostgreSQL и апликацијата работат паралелно без проблем. Истиот сценарио со Electron: 310 MB само за апликацискиот процес, пред да е отворен ниту еден пациент. При обработка на VCF со 50 000 записи, Electron го доведе системот до 3.7 GB и почна да swap-ува на диск. Таури заврши за 94 секунди, без swap.


СПОРЕДБА ПО RAM УПОТРЕБА

ТехнологијаRAM при стартRAM (VCF 50k записи)Linux поддршка
Tauri 2 (избран)42 MB430 MBWebKit2GTK, native
Electron310 MB3.7 GB (swap!)Да, no bundled Chromium
Flutter Desktop168 MB~600 MBДа, no runtime overhead
Python + PyQt6120 MB~400 MBДа, no GPL license

Ова исто така ми беа единствени опции поради програмските јазици. .NET, JAVA,C++ не ми беа опција бидејќи немам доволмо познавање од нив.


CROSS-COMPILATION: ЕДЕН CI PIPELINE ЗА СИТЕ ПЛАТФОРМИ

YAML   .github/workflows/release.yml


ПЕТТЕ КОНКРЕТНИ ПРИЧИНИ ЗОШТО TAURI ПОБЕДИ

[01]  Rust memory safety за медицински податоци  Во генетска лабораторија, data corruption не е само bug, туку потенцијално погрешна дијагноза. Rust-овиот borrow checker го прави невозможно случајното пишување надвор од граници на buffer или data race при concurrent VCF import. Компајлерот фати 14 потенцијални race condition грешки кои во Electron само ќе се манифестираа при runtime.

[02]  SQLx compile-time query validation  SQLx ги верификува SQL queries директно при компајлирање, против вистинска PostgreSQL инстанца. Ако табелата или колоната не постои, или типовите не се совпаѓаат, компајлот паѓа. За апликација со 60+ SQL queries, тоа е значајна сигурносна мрежа.

[03]  Системски WebView без Chromium  Tauri го користи WebKit2GTK на Linux, WebKit на macOS, WebView2 на Windows. Безбедносните patches доаѓаат преку системски пакет менаџер, не преку нов release на апликацијата. Electron апликациите бараат регуларни нови releases само за безбедносни Chromium апдејти.

[04]  Capability security модел и IPC изолација  Capability системот ми дозволи да дефинирам прецизно кои делови од OS-от ги допира апликацијата. WebView нема директен пристап до PostgreSQL или filesystem надвор од дефинираните директориуми.

[05]  React ecosystem за UI без компромис  React со TanStack Table, React Query и Radix UI ги решава сите UI проблеми со зрели, добро тестирани библиотеки. Dart/Flutter и Qt немаат еквивалентен UI ecosystem со иста зрелост.


КОГА НЕМА ДА ГО ИЗБЕРАМ TAURI

СценариоПодобар изборПричина
Тим без Rust искуствоElectronRust има стрмна крива на учење
Cloud-native / SaaSNext.js / SvelteKitПобрзо, поевтино, push updates
Сложена нативна UIQtПодлабока OS интеграција
МобилностFlutterTauri mobile е сеуште во бета

РЕТРОСПЕКТИВНА ОЦЕНКА ПО 6 МЕСЕЦИ: По 6 месеци развој и 6 месеци продукција, би ја донел истата одлука. Единствениот дел каде ја почувствував ограниченоста е при complex drag-and-drop за pedigree editor во WebView2. Сè останато: производство, стабилност, безбедност беше над очекувањата.

“Генетскиот запис е перманентен. Системот кој го чува, исто така треба да биде.”

Clipper кодот е архивиран во git. Новиот систем ги задоволува барањата на ISO 15189. Секоја варијанта, секоја рекласификација, секој lot-број е трасабилен.

Стани премиум член и доби пристап до сите содржини, специјален попуст на над 2.200 производи во ИТ маркет, верификуван профил и можност за огласување на ИТ Огласник. Плус ќе го поддржиш медиумот кој го градиме цели 16 години!

basic

членство

42 ден./мес

зачлени се

1337

членство

125 ден./мес

зачлени се
* плаќањето е на годишно ниво

Доколку веќе имаш премиум членство, најави се тука.

Добивај известувања
Извести ме за
guest
0 Коментари
Најнови
Најстари Со највеќе гласови
Inline Feedbacks
View all comments