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 }