fix(identity): 支持生效配置安全重验证

Active Revision 重验证成功后更新验证元数据并原子替换同配置 Runtime;验证失败时不修改数据库状态或当前运行时。\n\n验证:go test ./apps/api/internal/identityruntime ./apps/api/internal/store ./apps/api/internal/httpapi
This commit is contained in:
2026-07-17 12:12:26 +08:00
parent 1fce3a535d
commit b175d545ff
3 changed files with 54 additions and 2 deletions
+16 -2
View File
@@ -17,6 +17,7 @@ type Repository interface {
IdentityConfigurationRevision(context.Context, string) (identity.Revision, error)
ActiveIdentityConfigurationRevision(context.Context) (identity.Revision, error)
MarkIdentityRevisionValidated(context.Context, string, int64, string, string) (identity.Revision, error)
RevalidateActiveIdentityRevision(context.Context, string, int64, string, string) (identity.Revision, error)
MarkIdentityRevisionFailed(context.Context, string, int64, string, string, string) (identity.Revision, error)
ActivateIdentityRevision(context.Context, string, int64, string, string) (identity.Revision, bool, error)
DisableActiveIdentityRevision(context.Context, int64, string, string) (identity.Revision, error)
@@ -84,14 +85,27 @@ func (manager *Manager) Validate(ctx context.Context, id string, expectedVersion
if err != nil {
return identity.Revision{}, err
}
if revision.Version != expectedVersion || revision.State != identity.RevisionDraft && revision.State != identity.RevisionSuperseded {
if revision.Version != expectedVersion || revision.State != identity.RevisionDraft && revision.State != identity.RevisionSuperseded && revision.State != identity.RevisionActive {
return identity.Revision{}, identity.ErrRevisionConflict
}
candidate, buildErr := manager.builder.Build(ctx, revision)
if buildErr != nil {
_, _ = manager.repository.MarkIdentityRevisionFailed(ctx, id, expectedVersion, "validation_failed", traceID, auditID)
if revision.State != identity.RevisionActive {
_, _ = manager.repository.MarkIdentityRevisionFailed(ctx, id, expectedVersion, "validation_failed", traceID, auditID)
}
return identity.Revision{}, buildErr
}
if revision.State == identity.RevisionActive {
revalidated, err := manager.repository.RevalidateActiveIdentityRevision(ctx, id, expectedVersion, traceID, auditID)
if err != nil {
candidate.Close()
return identity.Revision{}, err
}
candidate.Revision = revalidated
old := manager.current.Swap(candidate)
retireRuntime(old)
return revalidated, nil
}
candidate.Close()
return manager.repository.MarkIdentityRevisionValidated(ctx, id, expectedVersion, traceID, auditID)
}