Agregados los metodo GetDocumentReference en ips/client/client.go y CreateQR y Validate en vhl/client/client.go

This commit is contained in:
Alejandro Gomez Auad 2026-05-06 01:43:24 +00:00
parent 8de3aa6ab4
commit 92ba4e6e45
2 changed files with 156 additions and 26 deletions

View File

@ -3,7 +3,6 @@ package client
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"ips-lacpass-backend/pkg/errors" "ips-lacpass-backend/pkg/errors"
"ips-lacpass-backend/pkg/utils" "ips-lacpass-backend/pkg/utils"
"net/http" "net/http"
@ -49,21 +48,61 @@ func request(client *http.Client, req *http.Request) (*http.Response, error) {
} }
func (c *IpsClient) GetDocumentReference(identifier string) (*Bundle, error) { func (c *IpsClient) GetDocumentReference(identifier string) (*Bundle, error) {
// TODO: To be implemented by the participant req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/DocumentReference?identifier=%s", c.BaseURL, identifier), nil)
return nil, &errors.HttpError{ if err != nil {
StatusCode: 500, return nil, &errors.HttpError{
Body: []map[string]interface{}{{"error": "Not implemented error", "message": "this method is not implemented yet"}}, StatusCode: http.StatusInternalServerError,
Err: fmt.Errorf("failed to get document reference"), Body: []map[string]interface{}{{"error": "internal_error", "message": "Failed to create request"}},
Err: err,
}
} }
req.Header.Set("Accept", "application/fhir+json, application/json")
resp, err := request(c.Client, req)
if err != nil {
return nil, err
}
defer utils.CloseBody(resp.Body)
var bundle Bundle
if err := json.NewDecoder(resp.Body).Decode(&bundle); err != nil {
return nil, &errors.HttpError{
StatusCode: http.StatusInternalServerError,
Body: []map[string]interface{}{{"error": "internal_error", "message": "Failed to decode DocumentReference bundle"}},
Err: fmt.Errorf("failed to decode DocumentReference bundle: %w", err),
}
}
return &bundle, nil
} }
func (c *IpsClient) GetIpsBundle(url string) (map[string]interface{}, error) { func (c *IpsClient) GetIpsBundle(url string) (map[string]interface{}, error) {
// TODO: To be implemented by the participant req, err := http.NewRequest(http.MethodGet, url, nil)
return nil, &errors.HttpError{ if err != nil {
StatusCode: 500, return nil, &errors.HttpError{
Body: []map[string]interface{}{{"error": "Not implemented error", "message": "this method is not implemented yet"}}, StatusCode: http.StatusInternalServerError,
Err: fmt.Errorf("failed to get document reference"), Body: []map[string]interface{}{{"error": "internal_error", "message": "Failed to create request"}},
Err: err,
}
} }
req.Header.Set("Accept", "application/fhir+json, application/json")
resp, err := request(c.Client, req)
if err != nil {
return nil, err
}
defer utils.CloseBody(resp.Body)
var bundle map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&bundle); err != nil {
return nil, &errors.HttpError{
StatusCode: http.StatusInternalServerError,
Body: []map[string]interface{}{{"error": "internal_error", "message": "Failed to decode IPS bundle"}},
Err: fmt.Errorf("failed to decode IPS bundle: %w", err),
}
}
return bundle, nil
} }
func (c *IpsClient) GetIpsICVP(idBundle string, immunizationId *string) (string, error) { func (c *IpsClient) GetIpsICVP(idBundle string, immunizationId *string) (string, error) {
@ -73,4 +112,4 @@ func (c *IpsClient) GetIpsICVP(idBundle string, immunizationId *string) (string,
Body: []map[string]interface{}{{"error": "Not implemented error", "message": "this method is not implemented yet"}}, Body: []map[string]interface{}{{"error": "Not implemented error", "message": "this method is not implemented yet"}},
Err: fmt.Errorf("failed to get document reference"), Err: fmt.Errorf("failed to get document reference"),
} }
} }

View File

@ -9,6 +9,7 @@ import (
"ips-lacpass-backend/pkg/errors" "ips-lacpass-backend/pkg/errors"
"ips-lacpass-backend/pkg/utils" "ips-lacpass-backend/pkg/utils"
"net/http" "net/http"
"net/url"
) )
type VhlClient struct { type VhlClient struct {
@ -27,29 +28,119 @@ func NewClient(baseURL string, icvpValidatorUrl string) VhlClient {
func (c *VhlClient) CreateQr(ctx context.Context, body CreateQrRequest) (*QrData, error) { func (c *VhlClient) CreateQr(ctx context.Context, body CreateQrRequest) (*QrData, error) {
// TODO: To be implemented by the participant // TODO: To be implemented by the participant
return nil, &errors.HttpError{ resp, err := c.Client.Post(fmt.Sprintf("%s/v2/vshcIssuance", c.BaseURL), "application/json", bytes.NewBuffer(body))
StatusCode: 500, if resp.StatusCode != http.StatusOK {
Body: []map[string]interface{}{{"error": "Not implemented error", "message": "this method is not implemented yet"}}, return nil, &errors.HttpError{
Err: fmt.Errorf("failed to get document reference"), StatusCode: 500,
Body: []map[string]interface{}{{"error": "Not implemented error", "message": "this method is not implemented yet"}},
Err: fmt.Errorf("failed to get document reference"),
}
} }
return resp, nil
} }
func (c *VhlClient) Validate(ctx context.Context, qrData string) (*QRValidationResponse, error) { func (c *VhlClient) Validate(ctx context.Context, qrData string) (*QRValidationResponse, error) {
// TODO: To be implemented by the participant body, err := json.Marshal(QrValidationRequest{QRCodeContent: qrData})
return nil, &errors.HttpError{ if err != nil {
StatusCode: 500, return nil, fmt.Errorf("failed to marshal validation payload: %w", err)
Body: []map[string]interface{}{{"error": "Not implemented error", "message": "this method is not implemented yet"}},
Err: fmt.Errorf("failed to get document reference"),
} }
resp, err := c.Client.Post(fmt.Sprintf("%s/v2/vshcValidation", c.BaseURL), "application/json", bytes.NewBuffer(body))
if err != nil {
return nil, &errors.HttpError{
StatusCode: http.StatusBadGateway,
Body: []map[string]interface{}{{"error": "service_unavailable", "message": "Failed to connect to VHL service"}},
Err: err,
}
}
defer utils.CloseBody(resp.Body)
if resp.StatusCode != http.StatusOK {
bodyBytes, readErr := io.ReadAll(resp.Body)
if readErr != nil {
return nil, &errors.HttpError{
StatusCode: resp.StatusCode,
Body: []map[string]interface{}{{"error": "internal_error", "message": "Failed to read response body"}},
Err: readErr,
}
}
return nil, &errors.HttpError{
StatusCode: resp.StatusCode,
Body: []map[string]interface{}{{"error": "service_error", "message": string(bodyBytes)}},
Err: fmt.Errorf("unexpected status code %d: %s", resp.StatusCode, string(bodyBytes)),
}
}
var valResp QRValidationResponse
if err := json.NewDecoder(resp.Body).Decode(&valResp); err != nil {
return nil, &errors.HttpError{
StatusCode: http.StatusInternalServerError,
Body: []map[string]interface{}{{"error": "internal_error", "message": "Failed to decode response"}},
Err: err,
}
}
return &valResp, nil
} }
func (c *VhlClient) GetIpsUrl(ctx context.Context, shLink string, passCode string) (*VhlManifestResponse, error) { func (c *VhlClient) GetIpsUrl(ctx context.Context, shLink string, passCode string) (*VhlManifestResponse, error) {
// TODO: To be implemented by the participant u, err := url.Parse(fmt.Sprintf("%s/ips-url", c.BaseURL))
return nil, &errors.HttpError{ if err != nil {
StatusCode: 500, return nil, &errors.HttpError{
Body: []map[string]interface{}{{"error": "Not implemented error", "message": "this method is not implemented yet"}}, StatusCode: http.StatusInternalServerError,
Err: fmt.Errorf("failed to get document reference"), Body: []map[string]interface{}{{"error": "internal_error", "message": "Failed to create request"}},
Err: err,
}
} }
q := u.Query()
q.Set("shLink", shLink)
q.Set("passCode", passCode)
u.RawQuery = q.Encode()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
if err != nil {
return nil, &errors.HttpError{
StatusCode: http.StatusInternalServerError,
Body: []map[string]interface{}{{"error": "internal_error", "message": "Failed to create request"}},
Err: err,
}
}
req.Header.Set("Accept", "application/json")
resp, err := c.Client.Do(req)
if err != nil {
return nil, &errors.HttpError{
StatusCode: http.StatusBadGateway,
Body: []map[string]interface{}{{"error": "service_unavailable", "message": "Failed to connect to VHL service"}},
Err: err,
}
}
defer utils.CloseBody(resp.Body)
if resp.StatusCode != http.StatusOK {
bodyBytes, readErr := io.ReadAll(resp.Body)
if readErr != nil {
return nil, &errors.HttpError{
StatusCode: resp.StatusCode,
Body: []map[string]interface{}{{"error": "internal_error", "message": "Failed to read response body"}},
Err: readErr,
}
}
return nil, &errors.HttpError{
StatusCode: resp.StatusCode,
Body: []map[string]interface{}{{"error": "service_error", "message": string(bodyBytes)}},
Err: fmt.Errorf("unexpected status code %d: %s", resp.StatusCode, string(bodyBytes)),
}
}
var manifest VhlManifestResponse
if err := json.NewDecoder(resp.Body).Decode(&manifest); err != nil {
return nil, &errors.HttpError{
StatusCode: http.StatusInternalServerError,
Body: []map[string]interface{}{{"error": "internal_error", "message": "Failed to decode manifest response"}},
Err: err,
}
}
return &manifest, nil
} }
func (c *VhlClient) ICVPValidate(ctx context.Context, qrData string) (*ICVPQRValidationResponse, error) { func (c *VhlClient) ICVPValidate(ctx context.Context, qrData string) (*ICVPQRValidationResponse, error) {