package encounter import ( "context" "database/sql" "encoding/json" "fmt" "net/url" "service/internal/infrastructure/database" "service/internal/interfaces/satusehat" ) type Repository interface { Create(ctx context.Context, payload interface{}) (*satusehat.FHIRResponse, error) Update(ctx context.Context, id string, payload interface{}) (*satusehat.FHIRResponse, error) Patch(ctx context.Context, id string, payload EncounterPatchRequest) (*satusehat.FHIRResponse, error) GetByID(ctx context.Context, id string) (*satusehat.FHIRResponse, error) Search(ctx context.Context, queryParams url.Values) (*satusehat.FHIRResponse, error) GetPendaftaranByID(ctx context.Context, idxdaftar int64) (*PendaftaranDB, error) SearchPatientByNIK(ctx context.Context, nik string) (*satusehat.FHIRResponse, error) SearchPractitionerByNIK(ctx context.Context, nik string) (*satusehat.FHIRResponse, error) } type repository struct { client satusehat.SatuSehatClient db database.Service } func NewRepository(client satusehat.SatuSehatClient, db database.Service) Repository { return &repository{client: client, db: db} } func (r *repository) executeRequest(ctx context.Context, method, endpoint string, payload interface{}) (*satusehat.FHIRResponse, error) { resp, err := r.client.DoRequest(ctx, method, endpoint, payload) if err != nil { return nil, err } return r.parseAndProcessResponse(resp) } func (r *repository) parseAndProcessResponse(data []byte) (*satusehat.FHIRResponse, error) { var result map[string]interface{} if err := json.Unmarshal(data, &result); err != nil { return nil, fmt.Errorf("failed to unmarshal response: %w", err) } // Ekstrak ID dari resource jika ada var resourceID string if id, ok := result["id"].(string); ok { resourceID = id } // Buat response terstruktur fhirResponse := &satusehat.FHIRResponse{ ID: resourceID, FullResponse: result, RawResponse: data, // Simpan data mentah untuk logging atau audit } return fhirResponse, nil } func (r *repository) Create(ctx context.Context, payload interface{}) (*satusehat.FHIRResponse, error) { return r.executeRequest(ctx, "POST", "/Encounter", payload) } func (r *repository) Update(ctx context.Context, id string, payload interface{}) (*satusehat.FHIRResponse, error) { endpoint := fmt.Sprintf("/Encounter/%s", id) return r.executeRequest(ctx, "PUT", endpoint, payload) } func (r *repository) Patch(ctx context.Context, id string, payload EncounterPatchRequest) (*satusehat.FHIRResponse, error) { endpoint := fmt.Sprintf("/Encounter/%s", id) return r.executeRequest(ctx, "PATCH", endpoint, payload) } func (r *repository) GetByID(ctx context.Context, id string) (*satusehat.FHIRResponse, error) { endpoint := fmt.Sprintf("/Encounter/%s", id) return r.executeRequest(ctx, "GET", endpoint, nil) } func (r *repository) Search(ctx context.Context, queryParams url.Values) (*satusehat.FHIRResponse, error) { endpoint := fmt.Sprintf("/Encounter?%s", queryParams.Encode()) return r.executeRequest(ctx, "GET", endpoint, nil) } func (r *repository) SearchPatientByNIK(ctx context.Context, nik string) (*satusehat.FHIRResponse, error) { endpoint := fmt.Sprintf("/Patient?identifier=https://fhir.kemkes.go.id/id/nik|%s", nik) return r.executeRequest(ctx, "GET", endpoint, nil) } func (r *repository) SearchPractitionerByNIK(ctx context.Context, nik string) (*satusehat.FHIRResponse, error) { endpoint := fmt.Sprintf("/Practitioner?identifier=https://fhir.kemkes.go.id/id/nik|%s", nik) return r.executeRequest(ctx, "GET", endpoint, nil) } func (r *repository) GetPendaftaranByID(ctx context.Context, idxdaftar int64) (*PendaftaranDB, error) { // Ambil koneksi database internal db, err := r.db.GetReadDB("default") if err != nil { return nil, err } var p PendaftaranDB query := ` SELECT p.idxdaftar, p.nomr, p.jamreg, p.masukpoly, p.keluarpoly, p.batal, p.kdpoly, p.poli_name_hfis, p.dokter_id_hfis, p.dokter_name_hfis, COALESCE(NULLIF(mp.noktp_baru, ''), mp.noktp) AS pasien_nik, dp.nik AS dokter_nik, dpas."Nomor_satusehat" AS patient_ihs, dp."Kode_satusehat" AS practitioner_ihs FROM public.t_pendaftaran p LEFT JOIN public.m_pasien mp ON p.nomr = mp.nomr LEFT JOIN public.data_pasien dpas ON p.nomr = dpas."Nomor_rekamedik" LEFT JOIN public.data_pegawai dp ON p.kddokter = dp."Kode_DPJP" WHERE p.idxdaftar = $1` err = db.QueryRowContext(ctx, query, idxdaftar).Scan( &p.IdxDaftar, &p.NoMR, &p.JamReg, &p.MasukPoly, &p.KeluarPoly, &p.Batal, &p.KdPoly, &p.PoliNameHFIS, &p.DokterIDHFIS, &p.DokterNameHFIS, &p.PasienNIK, &p.DokterNIK, &p.PatientIHS, &p.PractitionerIHS, ) if err != nil { if err == sql.ErrNoRows { return nil, fmt.Errorf("pendaftaran dengan idxdaftar %d tidak ditemukan", idxdaftar) } return nil, err } return &p, nil }