Systém pro správu pacientských dat s podporou DICOM/MRI snímků.
PatientDataApp je .NET aplikace zaměřená na správu pacientských dat včetně:
- Správy DICOM/MRI snímků
- GraphQL API pro flexibilní přístup k datům
- Diagnostických výsledků
- REST API pro práci se soubory
- .NET 8.0
- PostgreSQL
- GraphQL (HotChocolate)
- Docker a Docker Compose
- DICOM standard
- Cornerstone.js pro DICOM vizualizaci
{
"FileStorage": {
"MriImagesPath": "/app/data/mri-images",
"AllowedExtensions": [".dcm", ".jpg", ".png", ".pdf"]
}
}
GET /api/file/mri/{id}
- Vrací soubor snímku s příslušným Content-Type
- Podporované formáty: DICOM (.dcm), JPEG (.jpg), PNG (.png), PDF (.pdf)
- Chybové stavy:
- 404: Snímek nebo soubor nenalezen
- 500: Interní chyba serveru
API je dostupné na http://localhost:5001/graphql/
type Patient {
id: ID! # Unikátní identifikátor
firstName: String! # Jméno pacienta
lastName: String! # Příjmení pacienta
dateOfBirth: DateTime! # Datum narození
personalId: String! # Rodné číslo
insuranceCompany: String # Zdravotní pojišťovna
lastDiagnosis: String # Poslední diagnóza
lastExaminationDate: DateTime # Datum poslední prohlídky
diagnosticResults: [DiagnosticResult!] # Seznam diagnostických výsledků
mriImages: [MriImage!] # Seznam MRI snímků
updatedAt: DateTime! # Datum poslední aktualizace
createdAt: DateTime! # Datum vytvoření záznamu
}
type DiagnosticResult {
id: ID! # Unikátní identifikátor
patientId: Int! # ID pacienta
diagnosis: String! # Diagnóza
description: String # Popis diagnózy
date: DateTime! # Datum vyšetření
patient: Patient! # Vazba na pacienta
}
type MriImage {
id: ID! # Unikátní identifikátor
patientId: Int! # ID pacienta
acquisitionDate: DateTime! # Datum pořízení snímku
imagePath: String! # Cesta k souboru snímku
imageUrl: String! # URL pro stažení snímku
description: String # Popis snímku
findings: String # Nálezy
createdAt: DateTime! # Datum vytvoření záznamu
patient: Patient! # Vazba na pacienta
}
- Instalace závislostí:
npm install @apollo/client graphql
# Pro DICOM vizualizaci
npm install cornerstone-core cornerstone-wado-image-loader
- Nastavení Apollo Client:
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:5001/graphql/',
cache: new InMemoryCache()
});
// V root komponentě
function App() {
return (
<ApolloProvider client={client}>
<YourApp />
</ApolloProvider>
);
}
- Komponenta pro zobrazení MRI snímků:
Pro běžné obrazové formáty (JPG, PNG):
const MriViewer = ({ imageUrl }) => {
return (
<div>
<img
src={imageUrl}
alt="MRI snímek"
style={{ maxWidth: '100%', height: 'auto' }}
/>
</div>
);
};
Pro DICOM soubory:
import * as cornerstone from 'cornerstone-core';
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
const DicomViewer = ({ imageUrl }) => {
const viewerRef = useRef(null);
useEffect(() => {
if (viewerRef.current) {
cornerstone.enable(viewerRef.current);
const loadAndDisplayImage = async () => {
const image = await cornerstone.loadImage(imageUrl);
cornerstone.displayImage(viewerRef.current, image);
};
loadAndDisplayImage();
}
return () => {
if (viewerRef.current) {
cornerstone.disable(viewerRef.current);
}
};
}, [imageUrl]);
return <div ref={viewerRef} style={{ width: '512px', height: '512px' }} />;
};
- Příklad použití v komponentě:
const MriImagesList = () => {
const { loading, error, data } = useQuery(gql`
query GetMriImages {
mriImages {
id
imageUrl
acquisitionDate
description
findings
}
}
`);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
{data.mriImages.map(image => (
<div key={image.id}>
<h3>MRI snímek {image.id}</h3>
<p>Pořízeno: {new Date(image.acquisitionDate).toLocaleDateString()}</p>
{image.imageUrl.endsWith('.dcm') ? (
<DicomViewer imageUrl={image.imageUrl} />
) : (
<MriViewer imageUrl={image.imageUrl} />
)}
<p>Popis: {image.description}</p>
<p>Nálezy: {image.findings}</p>
</div>
))}
</div>
);
};
API podporuje filtrování a řazení pomocí HotChocolate middleware.
query {
patients(
where: {
lastName: { contains: "Nov" }
dateOfBirth: { gt: "1990-01-01" }
}
) {
id
firstName
lastName
}
}
query {
patients(
order: [
{ lastName: ASC }
{ firstName: ASC }
]
) {
id
firstName
lastName
}
}
Backend vrací chyby ve formátu:
{
"errors": [
{
"message": "Error message",
"locations": [{ "line": 2, "column": 3 }],
"path": ["fieldName"],
"extensions": {
"code": "ERROR_CODE"
}
}
]
}
Příklad zpracování chyb na frontendu:
const { loading, error, data } = useQuery(QUERY);
if (error) {
if (error.graphQLErrors) {
// Zpracování GraphQL chyb
error.graphQLErrors.forEach(({ message, extensions }) => {
console.error(
`GraphQL error: ${message}`,
`Code: ${extensions.code}`
);
});
}
if (error.networkError) {
// Zpracování síťových chyb
console.error(`Network error: ${error.networkError}`);
}
}
-
Cachování
- Využívejte Apollo Cache pro optimalizaci výkonu
- Nastavte správné cache policies pro jednotlivé typy
- Pro MRI snímky zvažte implementaci lokálního cachování
-
Optimalizace dotazů
- Požadujte pouze potřebná pole
- Využívejte fragmenty pro znovupoužitelné části dotazů
- Implementujte pagination pro velké seznamy
-
Error Handling
- Vždy implementujte zpracování chyb
- Poskytněte uživatelsky přívětivé chybové hlášky
- Logujte chyby pro debugging
-
Práce s DICOM soubory
- Používejte Cornerstone.js pro zobrazení DICOM souborů
- Implementujte lazy loading pro velké DICOM soubory
- Zvažte použití Web Workers pro zpracování DICOM dat
- Naklonujte repozitář:
git clone [URL_repozitáře]
cd PatientDataApp
- Spusťte deployment script:
chmod +x deploy.sh # Nastavení práv pro spuštění
./deploy.sh
Script automaticky:
- Zastaví běžící kontejnery
- Vyčistí Docker images
- Nastaví správný port (5001)
- Sestaví a spustí aplikaci
- Zobrazí průběh nasazení a logy
Po dokončení bude aplikace dostupná na:
- GraphQL API: http://localhost:5001/graphql/
- REST API pro soubory: http://localhost:5001/api/file/
Pouze pokud nemůžete použít automatické nasazení:
-
Požadavky:
- .NET 8.0 SDK
- PostgreSQL
- Nastavený connection string v appsettings.json
- Nastavená cesta pro ukládání souborů v appsettings.json
-
Spuštění:
dotnet restore
dotnet build
dotnet run
Databázové schéma je automaticky inicializováno při prvním spuštění pomocí migrace. Inicializační skripty pro základní data jsou umístěny v /init-scripts
.
- Pro vývoj je dostupný GraphQL Playground na
/graphql
v development módu - DICOM metadata lze filtrovat a zpracovávat pomocí specializovaných filtrů
- Projekt používá repository pattern pro oddělení datové vrstvy
- Soubory jsou ukládány v konfigurovaném adresáři s podporou více formátů