159 lines
5.5 KiB
Go
159 lines
5.5 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/api/models"
|
|
"devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/api/service"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// PydicomHandler handles operations related to PYDICOM uploads
|
|
type PydicomHandler struct {
|
|
logger *zap.Logger
|
|
shortLinkService *service.ShortLinkService
|
|
registerService *service.RegisterService
|
|
}
|
|
|
|
// NewPydicomHandler creates a new PydicomHandler
|
|
func NewPydicomHandler(logger *zap.Logger, shortLinkService *service.ShortLinkService, registerService *service.RegisterService) *PydicomHandler {
|
|
return &PydicomHandler{
|
|
logger: logger,
|
|
shortLinkService: shortLinkService,
|
|
registerService: registerService,
|
|
}
|
|
}
|
|
|
|
// HandleUploadedDicom processes a request from the PYDICOM uploader service to register a patient and generate a shortlink
|
|
func (h *PydicomHandler) HandleUploadedDicom(w http.ResponseWriter, r *http.Request) {
|
|
// Parse the request body into a temporary struct that matches the expected JSON
|
|
var reqData struct {
|
|
Email string `json:"email"`
|
|
Password string `json:"password"`
|
|
Name string `json:"name"`
|
|
Role string `json:"role"`
|
|
Patient struct {
|
|
PatientID string `json:"patient_id"`
|
|
PatientName string `json:"patient_name"`
|
|
DateOfBirth string `json:"date_of_birth"`
|
|
} `json:"patient"`
|
|
Studies []struct {
|
|
StudyInstanceUID string `json:"study_instance_uid"`
|
|
AccessionNumber string `json:"accession_number"`
|
|
StudyDate string `json:"study_date"`
|
|
StudyDescription string `json:"study_description"`
|
|
} `json:"studies"`
|
|
}
|
|
|
|
if err := json.NewDecoder(r.Body).Decode(&reqData); err != nil {
|
|
h.logger.Error("Failed to parse uploaded DICOM request", zap.Error(err))
|
|
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Validate the request
|
|
if reqData.Email == "" || reqData.Password == "" || reqData.Name == "" {
|
|
h.logger.Error("Missing required user fields in uploaded DICOM request")
|
|
http.Error(w, "Missing required user fields", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if reqData.Patient.PatientID == "" || reqData.Patient.DateOfBirth == "" {
|
|
h.logger.Error("Missing required patient fields in uploaded DICOM request")
|
|
http.Error(w, "Missing required patient fields", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if len(reqData.Studies) == 0 || reqData.Studies[0].StudyInstanceUID == "" {
|
|
h.logger.Error("Missing required study fields in uploaded DICOM request")
|
|
http.Error(w, "Missing required study fields", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Convert to our internal models
|
|
patientDetails := &models.PatientDetails{
|
|
PatientID: reqData.Patient.PatientID,
|
|
PatientName: reqData.Patient.PatientName,
|
|
DateOfBirth: reqData.Patient.DateOfBirth,
|
|
}
|
|
|
|
// Convert studies to our internal model
|
|
studies := make([]models.Study, len(reqData.Studies))
|
|
for i, s := range reqData.Studies {
|
|
studies[i] = models.Study{
|
|
StudyInstanceUID: s.StudyInstanceUID,
|
|
AccessionNumber: s.AccessionNumber,
|
|
StudyDate: s.StudyDate,
|
|
StudyDescription: s.StudyDescription,
|
|
}
|
|
}
|
|
|
|
// Create registration request
|
|
regRequest := &service.RegisterRequest{
|
|
Email: reqData.Email,
|
|
Password: reqData.Password,
|
|
Name: reqData.Name,
|
|
Role: "patient", // Force the role to be "patient" regardless of what was sent
|
|
Patient: patientDetails,
|
|
Studies: studies,
|
|
}
|
|
|
|
// Register the patient (or confirm it exists) using the RegisterService
|
|
user, err := h.registerService.Register(regRequest)
|
|
if err != nil {
|
|
// If the error is about duplicate email, we'll continue with generating a shortlink
|
|
// Otherwise, return the error
|
|
if err != service.ErrEmailExists {
|
|
h.logger.Error("Failed to register patient", zap.Error(err))
|
|
http.Error(w, fmt.Sprintf("Failed to register patient: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
h.logger.Info("Patient already exists, continuing with shortlink generation",
|
|
zap.String("email", reqData.Email),
|
|
zap.String("patientID", reqData.Patient.PatientID))
|
|
} else {
|
|
h.logger.Info("Patient registered successfully",
|
|
zap.String("userID", user.ID),
|
|
zap.String("email", reqData.Email),
|
|
zap.String("patientID", reqData.Patient.PatientID))
|
|
}
|
|
|
|
// For each study, generate a shortlink
|
|
// For simplicity, we'll just use the first study in the array
|
|
study := reqData.Studies[0]
|
|
|
|
// Create a shortlink request
|
|
shortLinkReq := &models.GenerateShortLinkRequest{
|
|
PatientID: reqData.Patient.PatientID,
|
|
StudyUID: study.StudyInstanceUID,
|
|
DOB: reqData.Patient.DateOfBirth,
|
|
ExpiresIn: 0, // Set to 0 to use the default expiry from config
|
|
}
|
|
|
|
// Generate a shortlink
|
|
// We set empty string as creatorID because you mentioned ShortlinkCreate_UserID is now nullable
|
|
shortLinkResp, err := h.shortLinkService.GenerateShortLink(shortLinkReq, "")
|
|
if err != nil {
|
|
h.logger.Error("Failed to generate shortlink",
|
|
zap.Error(err),
|
|
zap.String("patientID", reqData.Patient.PatientID),
|
|
zap.String("studyUID", study.StudyInstanceUID))
|
|
http.Error(w, fmt.Sprintf("Failed to generate shortlink: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Log successful shortlink generation
|
|
h.logger.Info("Shortlink generated for uploaded DICOM",
|
|
zap.String("patientID", reqData.Patient.PatientID),
|
|
zap.String("studyUID", study.StudyInstanceUID),
|
|
zap.String("shortToken", shortLinkResp.ShortToken))
|
|
|
|
// Return the shortlink response
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(shortLinkResp)
|
|
}
|