package handlers import ( "log" "net/http" "github.com/AmanTahiliani/FHIR-Sandbox/app/fhir" "github.com/AmanTahiliani/FHIR-Sandbox/app/middleware" "github.com/AmanTahiliani/FHIR-Sandbox/app/models" ) // HandleDashboard renders the stable patient dashboard. // All clinical data is read from the local database; no live FHIR calls are // made here. Use POST /dashboard/sync to refresh data from the EHR. // // GET /dashboard func (h *Handler) HandleDashboard(w http.ResponseWriter, r *http.Request) { sess := middleware.SessionFromContext(r.Context()) practitionerUser := middleware.UserFromContext(r.Context()) if sess == nil || practitionerUser == nil { h.handleUnauthorized(w, r) return } ehrURL := sess.EHRURL patientID := sess.PatientFHIRID // Fetch patient demographics from the FHIR server. This is a cheap single // resource call and keeps the patient card always current. fhirClient := fhir.NewClient(ehrURL, sess.AccessToken) patient, err := fhirClient.GetPatient(patientID) if err != nil { log.Printf("handlers: dashboard fetch Patient/%s failed: %v", patientID, err) h.renderError(w, http.StatusBadGateway, "Failed to fetch patient details from the FHIR server.") return } patientUser := fhir.ExtractUserFromPatient(patient, ehrURL) // Read clinical data from the local database. observations, err := h.store.ListObservations(patientID, ehrURL) if err != nil { log.Printf("handlers: dashboard ListObservations Patient/%s: %v", patientID, err) // Non-fatal; render with empty slice. } conditions, err := h.store.ListConditions(patientID, ehrURL) if err != nil { log.Printf("handlers: dashboard ListConditions Patient/%s: %v", patientID, err) } docRefs, err := h.store.ListDocumentReferences(patientID, ehrURL) if err != nil { log.Printf("handlers: dashboard ListDocumentReferences Patient/%s: %v", patientID, err) } latestSync, err := h.store.LatestSync(patientID, ehrURL) if err != nil { log.Printf("handlers: dashboard LatestSync Patient/%s: %v", patientID, err) } h.render(w, "dashboard.html", dashboardData{ Patient: patientUser, Practitioner: practitionerUser, RawPatient: patient, Observations: observations, Conditions: conditions, DocumentReferences: docRefs, LatestSync: latestSync, Session: sess, }) } // dashboardData is the view model passed to the dashboard template. type dashboardData struct { Patient *models.User Practitioner *models.User RawPatient *fhir.Patient Observations []models.Observation Conditions []models.Condition DocumentReferences []models.DocumentReference LatestSync *models.PatientSync Session *models.Session } // handleUnauthorized redirects to root for dashboard requests. func (h *Handler) handleUnauthorized(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/", http.StatusSeeOther) }