81 lines
2.9 KiB
Go
81 lines
2.9 KiB
Go
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 }
|