feat(handler): 暴露健康档案 upsert 接口(T-204)
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
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 }
|
||||
Reference in New Issue
Block a user