feat(handler): 暴露健康档案 upsert 接口(T-204)

This commit is contained in:
ila
2026-07-16 02:00:56 +08:00
parent 3a30ebdc45
commit 48263d8b9a
16 changed files with 852 additions and 44 deletions
+19 -8
View File
@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"strings"
"time"
"chis_osi/contract"
"chis_osi/mapping"
@@ -32,12 +33,12 @@ const (
)
type Outcome struct {
Status Status
Action Action
Reason string
ServiceID string
ResponseCode string
PHRIDHint string
Status Status `json:"status"`
Action Action `json:"action"`
Reason string `json:"reason,omitempty"`
ServiceID string `json:"serviceId,omitempty"`
ResponseCode string `json:"responseCode,omitempty"`
PHRIDHint string `json:"phrIdHint,omitempty"`
}
type UpsertEvent struct {
@@ -135,6 +136,8 @@ type HealthRecordUpsertService struct {
deps Dependencies
}
const idempotencyCleanupTimeout = 5 * time.Second
func NewHealthRecordUpsertService(deps Dependencies) *HealthRecordUpsertService {
return &HealthRecordUpsertService{deps: deps}
}
@@ -216,14 +219,22 @@ func (s *HealthRecordUpsertService) update(ctx context.Context, task source.Heal
}
func (s *HealthRecordUpsertService) complete(ctx context.Context, task source.HealthRecordTask, key, token string, outcome Outcome) (Outcome, error) {
if err := s.deps.Idempotency.Complete(ctx, key, token); err != nil {
cleanupCtx, cancel := idempotencyCleanupContext(ctx)
defer cancel()
if err := s.deps.Idempotency.Complete(cleanupCtx, key, token); err != nil {
return outcome, fmt.Errorf("persist successful CHIS write before notification: %w", err)
}
return s.finish(ctx, task, outcome)
}
func (s *HealthRecordUpsertService) finishAcquired(ctx context.Context, task source.HealthRecordTask, key, token string, outcome Outcome) (Outcome, error) {
return s.finish(ctx, task, outcome, s.deps.Idempotency.Release(ctx, key, token))
cleanupCtx, cancel := idempotencyCleanupContext(ctx)
defer cancel()
return s.finish(ctx, task, outcome, s.deps.Idempotency.Release(cleanupCtx, key, token))
}
func idempotencyCleanupContext(ctx context.Context) (context.Context, context.CancelFunc) {
return context.WithTimeout(context.WithoutCancel(ctx), idempotencyCleanupTimeout)
}
func (s *HealthRecordUpsertService) finish(ctx context.Context, task source.HealthRecordTask, outcome Outcome, prior ...error) (Outcome, error) {