mario c35ec4180d Squashed commit of the following:
commit d2ec8c0f07
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Thu May 15 15:42:33 2025 +0700

    add: db tx commit and rollback implementation

commit 264435f67e
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Thu May 15 14:34:20 2025 +0700

    fix: shortlink generation logic update/create

commit 047ab1937a
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Thu May 15 11:06:04 2025 +0700

    fix: if multiple studies patient, show first study by default

commit c13f834b92
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Thu May 15 09:46:32 2025 +0700

    add: register and login with DB query AND some struct type correction

commit dd4451c2a8
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Wed May 14 10:23:33 2025 +0700

    new file structure & koneksi ke DB

commit 8289881df3
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Tue May 13 16:49:07 2025 +0700

    edit: rm debug route

commit dd784da232
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Tue May 13 15:44:11 2025 +0700

    add: implement shortlink

commit 2687a761cc
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Tue May 13 11:47:19 2025 +0700

    add new dummy doctor user

commit eb67eaca46
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Tue May 13 11:46:28 2025 +0700

    add: ref_doctor studylist filter

commit 0d4825d152
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Tue May 13 10:07:16 2025 +0700

    edit study_iuids & accNum in patient jwt to array

commit 2d1f135fda
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Tue May 13 09:52:45 2025 +0700

    patient see their multiple studies

commit 13bb380f51
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Fri May 9 10:13:16 2025 +0700

    add: cors handler route and readme

commit 6c9ab574ce
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Mon May 5 11:50:36 2025 +0700

    add: login & token validation tapi belum connect ke DB

commit 297c9a6a01
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Mon Apr 28 15:37:02 2025 +0700

    add readme.md

commit 9b8e0260f3
Author: mario <dev.mario@sismedika@gmail.com>
Date:   Mon Apr 7 15:46:07 2025 +0700

    connected-to-google

commit f340bc5916
Author: mario <dev.mario@sismedika.com>
Date:   Mon Apr 7 11:14:18 2025 +0700

    init
2025-05-15 15:50:40 +07:00
2025-05-15 15:50:40 +07:00
2025-05-15 15:50:40 +07:00
2025-05-15 15:50:40 +07:00
2025-05-15 15:50:40 +07:00
2025-05-15 15:50:40 +07:00
2025-05-15 15:50:40 +07:00
2025-05-15 15:50:40 +07:00
2025-05-15 15:50:40 +07:00

GO-OHIF-Proxy

1. Gambaran Umum

Tujuan

App ini dibuat untuk menyalurkan dicomWeb request dari OHIF ke Google Healthcare. Proxy berperan hanya sebagai authenticator ke Google dengan service-account.json, tanpa merubah / menambah request

Berikut adalah cara clone project ini:

2. Alur Kerja Aplikasi

+----------------+      +----------------+      +----------------------+
|                |      |                |      |                      |
|  OHIF Viewer   |----->| GO-OHIF-Proxy |----->| Google Healthcare    |
|  (Web Client)  |<-----|                |<-----| DICOM API            |
|                |      |                |      |                      |
+----------------+      +----------------+      +----------------------+
  1. Permintaan Klien: OHIF Viewer mengirimkan permintaan DICOMweb (misalnya, untuk mengambil studi).
  2. Pemrosesan Proxy:
    • Proxy mencegat permintaan.
    • Menambahkan header autentikasi yang sesuai.
    • Meneruskan permintaan ke Google Cloud Healthcare API.
  3. Pemrosesan Google Cloud: Healthcare API memproses permintaan DICOM.
  4. Penanganan Respons: Proxy meneruskan respons kembali ke klien.

2b. Arsitektur

go-ohif-proxy/
│
├── cmd/
│   └── server/           # Application entry point
│       └── main.go       # Main server initialization
│
├── config/               # Configuration management
│   ├── config.go         # Configuration loader
│   └── config.yaml       # Application configuration
│
├── credentials/          # Authentication credentials
│   └── service-account.json  # Google Cloud service account
│
├── internal/
│   ├── api/              # API endpoints
│   │   ├── handler.go    # HTTP request handlers
│   │   ├── middleware.go # Request middleware
│   │   └── routes.go     # API route definitions
│   │
│   ├── auth/             # Authentication services
│   │   └── google.go     # Google Cloud authentication
│   │
│   ├── proxy/            # Proxy service
│   │   └── dicomweb.go   # DICOMweb request handling
│   │
│   └── utils/            # Utility functions
│       ├── http.go       # HTTP utilities
│       └── logger.go     # Logging functionality
│
├── test/                 # Testing resources
│   └── http/             # HTTP test requests
│
├── Dockerfile            # Container definition
├── docker-compose.yml    # Multi-container orchestration
├── go.mod                # Go module definition
├── go.sum                # Module dependency checksums
└── README.md             # Project documentation

2c. Alur Kerja Kode

Secara umum kode di repo ini kurang lebih memiliki alur:

Routes --> Handlers --> Service --> Repository

3. Instalasi dan Penggunaan

Prasyarat

  • Go versi 1.19 atau lebih tinggi.
  • Akun Google Cloud dengan Healthcare API diaktifkan.
  • Kredensial akun layanan dengan akses ke DICOM store.

Clone dan Setup

# Clone repositori
git clone https://devone.aplikasi.web.id/gitea/mario/go-ohif-proxy.git
cd go-ohif-proxy

# Install dependencies
go mod download

Konfigurasi

  1. Salin file konfigurasi contoh:

    cp config/config.yaml.example config/config.yaml
    
  2. Edit config/config.yaml sesuai kebutuhan:

    server:
      port: 5555
      read_timeout_seconds: 30
      write_timeout_seconds: 30
      idle_timeout_seconds: 60
    
    log_level: "info"  # debug, info, warn, error
    
    google:
      project_id: "id-proyek-gcp-anda"
      location: "lokasi-anda"
      dataset: "nama-dataset-anda"
      dicom_store: "nama-dicom-store-anda"
      credentials_path: "./credentials/service-account.json"
    
    allowed_origins:
      - "http://localhost:3000"  # URL OHIF Viewer
    
  3. Letakkan kredensial akun layanan Google Cloud Anda di credentials/service-account.json.

Menjalankan Aplikasi

Build dan Jalankan Secara Langsung

# Build aplikasi
go build -o ohif-proxy ./cmd/server

# Jalankan aplikasi
./ohif-proxy

Menggunakan Docker

# Build image Docker
docker build -t go-ohif-proxy .

# Jalankan dengan Docker
docker run -p 5555:5555 -v $(pwd)/config:/app/config -v $(pwd)/credentials:/app/credentials go-ohif-proxy

Menggunakan Docker Compose

docker-compose up

Run Aplikasi Tanpa Build

  1. Transfer ./ohif-proxy ke server tujuan. Contoh:
    scp ohif-proxy pacs@152.42.173.210:/home/pacs/google-ohif-proxy
    
  2. Pastikan server tujuan terinstall go versi >1.19. Cek dengan:
  3. Buat direktori:
    mkdir -p ~/google-ohif-proxy
    mkdir -p ~/google-ohif-proxy/config
    mkdir -p ~/google-ohif-proxy/credentials
    
  4. Tambahkan config.go dan config.yaml.
    scp -r config/* pacs@152.42.173.210:/home/pacs/google-ohif-proxy/config/
    
  5. Tambahkan credential /credentials/service-account.json
    nano credentials/service-account.json
    # atau
    # scp dari local
    

Pengujian

Aplikasi ini menyertakan permintaan HTTP uji di direktori test/http yang dapat digunakan dengan klien REST seperti ekstensi REST Client di VSCode.

# Jalankan pengujian yang disertakan
make test

Untuk informasi lebih lanjut tentang OHIF: https://ohif.org/ Untuk informasi lebih lanjut tentang Google Cloud Healthcare API: https://cloud.google.com/healthcare

GO-OHIF-Proxy Architecture

Project Structure

go-ohif-proxy/
├── cmd/
│   └── server/              # Application entry point
│       └── main.go          # Main function and application start
│
├── config/                  # Configuration 
│   ├── config.go            # Config structure definitions
│   └── config.yaml          # YAML configuration file
│
├── credentials/             # Authentication credentials
│   └── service-account.json # Google service account credentials
│
├── internal/                # Internal packages (not importable)
│   ├── api/                 # API implementation
│   │   ├── handlers/        # HTTP request handlers
│   │   │   ├── auth.go      # Authentication handlers
│   │   │   ├── dicom.go     # DICOM request handlers
│   │   │   └── healthcheck.go # Health check endpoint
│   │   │
│   │   ├── middleware/      # HTTP middleware
│   │   │   ├── auth.go      # Authentication middleware
│   │   │   └── logging.go   # Request logging middleware
│   │   │
│   │   ├── models/          # Data models
│   │   │   └── user.go      # User and authentication models
│   │   │
│   │   ├── repository/      # Data access layer
│   │   │   ├── interfaces.go # Repository interfaces
│   │   │   └── mysql_repository.go # MySQL implementation
│   │   │
│   │   ├── service/         # Business logic 
│   │   │   ├── auth_service.go # Authentication service
│   │   │   └── db_repository.go # Legacy repository code (to be removed)
│   │   │
│   │   └── routes.go        # API route definitions
│   │
│   ├── auth/                # Authentication utilities
│   │   ├── google.go        # Google authentication client
│   │   └── jwt.go           # JWT generation and validation
│   │
│   ├── logger/              # Logging utilities
│   │   └── logger.go        # Logger configuration
│   │
│   └── proxy/               # DICOM web proxy functionality
│       └── client.go        # Google Healthcare API client
│
├── pkg/                     # Public packages (importable)
│
├── test/                    # Test files
│   └── http/                # HTTP test requests
│       ├── ohif-flow.http   # OHIF workflow tests
│       └── test.http        # General API tests
│
├── docker-compose.yaml      # Docker Compose configuration
├── Dockerfile               # Docker build instructions
├── go.mod                   # Go module definition
├── go.sum                   # Go module checksums
├── Makefile                 # Build automation
└── README.md                # Project documentation

Architecture Diagram

graph TD
    subgraph Client
        OHIF[OHIF Viewer]
    end

    subgraph API_Gateway
        Router[Chi Router]
        Auth_MW[Auth Middleware]
        Logging_MW[Logging Middleware]
        CORS_MW[CORS Middleware]
        PatientView_MW[Patient View Restriction]
    end

    subgraph Services
        AuthService[Auth Service]
        DicomService[DICOM Service]
    end

    subgraph Repositories
        UserRepo[User Repository]
        TokenRepo[Token Repository]
        PatientRepo[Patient Repository]
        DoctorRepo[Doctor Repository]
    end

    subgraph External
        GoogleHealthcare[Google Healthcare API]
        MySQL[MySQL Database]
    end

    subgraph Utilities
        JWTManager[JWT Manager]
        GoogleAuth[Google Auth Client]
        Logger[Logger]
    end

    OHIF -->|HTTP Requests| Router
    Router --> Auth_MW
    Auth_MW --> Logging_MW
    Logging_MW --> CORS_MW
    CORS_MW --> PatientView_MW
    PatientView_MW --> DicomService

    Router -->|Auth Routes| AuthService
    AuthService -->|Uses| JWTManager
    AuthService -->|Uses| UserRepo
    AuthService -->|Uses| TokenRepo

    DicomService -->|Uses| GoogleHealthcare
    DicomService -->|Uses| PatientRepo

    UserRepo -->|Implements| MySQL
    TokenRepo -->|Implements| MySQL
    PatientRepo -->|Implements| MySQL
    DoctorRepo -->|Implements| MySQL

    DicomService -->|Uses| GoogleAuth
    GoogleAuth -->|Authenticates| GoogleHealthcare

Authentication Flow

sequenceDiagram
    participant Client
    participant API as API Gateway
    participant AuthService
    participant Repo as Repository
    participant JWT as JWT Manager
    participant DB as Database

    Client->>API: POST /auth/login
    API->>AuthService: Login(email, password)
    
    alt Database Auth Enabled
        AuthService->>Repo: GetUserByEmail(email)
        Repo->>DB: SELECT * FROM users
        DB->>Repo: User Data
        Repo->>AuthService: User Object
        AuthService->>JWT: Generate Tokens
        JWT->>AuthService: Access + Refresh Tokens
        AuthService->>Repo: StoreRefreshToken()
        Repo->>DB: INSERT INTO refresh_tokens
    else Hardcoded Auth
        AuthService->>JWT: Generate Tokens
        JWT->>AuthService: Access + Refresh Tokens
    end
    
    AuthService->>API: Tokens + User Info
    API->>Client: Auth Response
    
    Note over Client,API: Later - Protected Request
    
    Client->>API: GET /dicomWeb/* with Bearer Token
    API->>AuthService: ValidateToken()
    AuthService->>JWT: ParseToken()
    JWT->>AuthService: Claim Data
    AuthService->>API: User Context
    API->>Client: Protected Resource

DICOM Request Flow

sequenceDiagram
    participant Client
    participant API as API Gateway
    participant Auth as Auth Middleware
    participant PatientMW as Patient Restriction MW
    participant DicomHandler
    participant GCP as Google Healthcare API

    Client->>API: GET /dicomWeb/studies/{studyUID}
    
    alt Whitelisted Path
        API->>DicomHandler: Forward Request (Skip Auth)
    else Protected Path
        API->>Auth: Check Authentication
        Auth->>API: User Context
        API->>PatientMW: Check Access Rights
        
        alt Patient Role
            PatientMW->>Repo: IsStudyAssignedToPatient()
            Repo->>PatientMW: Access Result
            alt Study Assigned
                PatientMW->>DicomHandler: Forward Request
            else Study Not Assigned
                PatientMW->>Client: 403 Forbidden
            end
        else Doctor Role
            PatientMW->>DicomHandler: Forward Request
        end
    end
    
    DicomHandler->>GCP: Forward Request to DICOM Store
    GCP->>DicomHandler: DICOM Data
    DicomHandler->>Client: DICOM Response
Description
No description provided
Readme 24 MiB
Languages
Go 98.8%
Dockerfile 0.7%
Makefile 0.5%