Files
chis_osi/health_record_upsert_runtime.go
T

81 lines
2.9 KiB
Go
Raw Normal View History

package main
import (
"context"
"fmt"
"chis_osi/cache"
"chis_osi/contract"
"chis_osi/mapping"
"chis_osi/osi"
"chis_osi/pipeline"
"chis_osi/source"
)
type healthRecordRuntimeClient interface {
QueryDoctors(context.Context, osi.DoctorQuery) ([]osi.Doctor, osi.Result, error)
QueryOrgs(context.Context, osi.OrgQuery) ([]osi.Org, osi.Result, error)
FindHealthRecord(context.Context, osi.FindHealthRecordQuery) ([]contract.FindHealthRecord, osi.Result, error)
CreateHealthRecord(context.Context, contract.HealthRecordCreate) (contract.HealthRecordSaveResult, osi.Result, error)
UpdateHealthRecord(context.Context, contract.HealthRecordCreate) (contract.HealthRecordSaveResult, osi.Result, error)
}
type serverHealthRecordUpserter struct {
client healthRecordRuntimeClient
idempotency *pipeline.MemoryIdempotencyStore
}
func newServerHealthRecordUpserter(client healthRecordRuntimeClient) *serverHealthRecordUpserter {
return &serverHealthRecordUpserter{client: client, idempotency: pipeline.NewMemoryIdempotencyStore()}
}
func (u *serverHealthRecordUpserter) Upsert(ctx context.Context, task source.HealthRecordTask) (pipeline.Outcome, error) {
if validationErrors := mapping.ValidateHealthRecordTask(task); len(validationErrors) > 0 {
return pipeline.Outcome{
Status: pipeline.StatusFailed,
Action: pipeline.ActionNone,
Reason: "mapping validation failed: " + validationErrors[0].Field,
}, nil
}
doctors, result, err := u.client.QueryDoctors(ctx, osi.DoctorQuery{
ManaUnitID: task.Record.ManaUnitID,
OperateUser: task.Record.ManaDoctorID,
})
if err != nil || !result.Success {
return pipeline.Outcome{}, fmt.Errorf("load CHIS doctor dictionary: %w", firstRuntimeError(err, result))
}
orgs, result, err := u.client.QueryOrgs(ctx, osi.OrgQuery{
OrganizCode: task.Record.ManaUnitID,
ParentID: "",
})
if err != nil || !result.Success {
return pipeline.Outcome{}, fmt.Errorf("load CHIS organization dictionary: %w", firstRuntimeError(err, result))
}
snapshot := cache.NewDictionarySnapshot(nil, doctors, orgs)
service := pipeline.NewHealthRecordUpsertService(pipeline.Dependencies{
Converter: pipeline.ConverterFunc(func(task source.HealthRecordTask) (contract.HealthRecordCreate, []mapping.ValidationError) {
return mapping.MapHealthRecordTask(task, mapping.MapContext{Dicts: mapping.DefaultDictSnapshot(), MasterData: snapshot})
}),
Client: u.client,
Idempotency: u.idempotency,
Reports: discardUpsertReports{},
PHISStatuses: discardPHISStatuses{},
})
return service.Upsert(ctx, task)
}
func firstRuntimeError(err error, result osi.Result) error {
if err != nil {
return err
}
return fmt.Errorf("code=%s message=%s", result.Code, result.Message)
}
type discardUpsertReports struct{}
func (discardUpsertReports) Publish(context.Context, pipeline.UpsertEvent) error { return nil }
type discardPHISStatuses struct{}
func (discardPHISStatuses) WriteStatus(context.Context, pipeline.PHISStatusUpdate) error { return nil }