-
-
Notifications
You must be signed in to change notification settings - Fork 89
RG-T135 Bug Fixes, First pass at Admin Assist, brining back the Setup… #528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| using System; | ||
| using System.Linq; | ||
| using Resgrid.Model.AdminAssist; | ||
|
|
||
| namespace Resgrid.AdminAssist | ||
| { | ||
| /// <summary>Learning, purchase, recorded configuration and supported verification remain separate dimensions.</summary> | ||
| public static class CapabilitySetupEvaluator | ||
| { | ||
| public static CapabilitySetupAssessment Evaluate(ProductCapability capability, CapabilityAccess access, ConfigurationReport report, DateTime now, TimeSpan freshness) | ||
| { | ||
| var state = CapabilitySetupState.NotAssessed; | ||
| var definition = capability.Setup; | ||
| var accessFresh = access != null && access.AsOfUtc <= now && now - access.AsOfUtc <= freshness; | ||
| if (definition != null && accessFresh && access.State == EvidenceState.Known && report.Snapshot.Consistent) | ||
| { | ||
| var fact = report.Snapshot.Find(definition.EvidenceId); | ||
| if (fact.IsFresh(now, freshness) && fact.Number.HasValue && fact.Number >= 0) | ||
| { | ||
| state = fact.Number < definition.Minimum ? CapabilitySetupState.NotConfigured : CapabilitySetupState.ConfigurationPresent; | ||
| if (state == CapabilitySetupState.ConfigurationPresent && definition.RuleIds.Count > 0) | ||
| { | ||
| var checks = definition.RuleIds.Select(id => report.Findings.SingleOrDefault(f => f.RuleId == id)).ToArray(); | ||
| bool current(ConfigurationFinding check) => check != null && check.SnapshotRevision == report.Snapshot.Revision && | ||
| check.EvaluatedOnUtc <= now && now - check.EvaluatedOnUtc <= freshness; | ||
| if (checks.Any(check => current(check) && check.Result == RuleResult.Fail)) state = CapabilitySetupState.NeedsAttention; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Blocking async operations across CapabilitySetupEvaluator.cs, ConfigurationImpactEvaluator.cs, FindingLifecycle.cs, ConfigurationEvidence.cs, AdminAssistWorklistService.cs, AdminAssistRepository.cs, the listed AdminAssist tests, MCP tests, service tests, and PrintReport.cshtml can cause deadlocks and prevent efficient asynchronous execution. Replace Kody rule violation: Await async operations properly Prompt for LLMTalk to Kody by mentioning @kody Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction. |
||
| // N/A, missing or stale checks do not verify a capability. No data-usage or delivery claim. | ||
| else if (checks.All(check => current(check) && check.Result == RuleResult.Pass)) state = CapabilitySetupState.ChecksPassed; | ||
| } | ||
| } | ||
| } | ||
| var addon = capability.Requirements.Any(r => r.Kind == "addon"); | ||
| var opportunity = capability.ReleaseStatus is not ("available" or "preview") ? "Ui.OpportunityPlanned" : | ||
| !accessFresh || addon && (access.CommercialState == null || access.CommercialState == EvidenceState.Unknown || access.CommercialState == EvidenceState.Redacted) ? "Ui.OpportunityUnknown" : | ||
| addon && access.CommercialState == EvidenceState.Unavailable ? "Ui.OpportunityNotOwned" : | ||
| state == CapabilitySetupState.NotConfigured ? addon ? "Ui.OpportunitySubscribedNotConfigured" : "Ui.OpportunityIncludedNotConfigured" : | ||
| addon ? "Ui.OpportunitySubscribed" : "Ui.OpportunityNoAddon"; | ||
| return new(capability.Id, state, opportunity, definition?.GuidanceKey ?? "Ui.ConfigurationNotAssessed", | ||
| definition?.RuleIds ?? Array.Empty<string>(), report.Snapshot.Revision, report.Snapshot.AsOfUtc); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using Resgrid.Model.AdminAssist; | ||
|
|
||
| namespace Resgrid.AdminAssist | ||
| { | ||
| /// <summary>Headroom for proposed total personnel/unit counts; no provisioning, price estimate or entitlement change.</summary> | ||
| public static class CapacityImpactEvaluator | ||
| { | ||
| public static ConfigurationImpactReport Evaluate(ConfigurationSnapshot snapshot, CapacityImpactRequest request, DateTime now, TimeSpan maximumAge) | ||
| { | ||
| if (request == null || request.ProposedPersonnelCount < 0 || request.ProposedPersonnelCount > 1000000 || request.ProposedUnitCount < 0 || request.ProposedUnitCount > 1000000) | ||
| throw new ArgumentException("Proposed total counts must be between zero and one million."); | ||
| if (!snapshot.Consistent || snapshot.Revision != request.ExpectedRevision) throw new AdminAssistConcurrencyException(); | ||
| decimal? Value(string id) { var value = snapshot.Find(id); return value.IsFresh(now, maximumAge) && value.Number >= 0 ? value.Number : null; } | ||
| var personnel = Value("capacityPersonnelCount"); var units = Value("capacityUnitCount"); | ||
| var metrics = new List<ConfigurationImpactMetric>(); | ||
| void Add(string label, decimal? before, decimal? after) => metrics.Add(new(label, before.HasValue && after.HasValue ? EvidenceState.Known : EvidenceState.Unknown, before, after)); | ||
| Add("Impact.PersonnelTotal", personnel, request.ProposedPersonnelCount); | ||
| Add("Impact.UnitTotal", units, request.ProposedUnitCount); | ||
| var kind = snapshot.Find("capacityKind"); | ||
| if (kind.IsFresh(now, maximumAge) && kind.Code == "entities") | ||
| { | ||
| var cap = Value("capacityEntityLimit"); | ||
| // Zero is not a verified entity allowance; the owning limit service changes behavior at zero. | ||
| if (cap == 0) cap = null; | ||
| Add("Impact.SharedHeadroom", cap - personnel - units, cap - request.ProposedPersonnelCount - request.ProposedUnitCount); | ||
| } | ||
| else if (kind.IsFresh(now, maximumAge) && kind.Code == "separate") | ||
| { | ||
| Add("Impact.PersonnelHeadroom", Value("capacityPersonnelLimit") - personnel, Value("capacityPersonnelLimit") - request.ProposedPersonnelCount); | ||
| Add("Impact.UnitHeadroom", Value("capacityUnitLimit") - units, Value("capacityUnitLimit") - request.ProposedUnitCount); | ||
| } | ||
| else Add("Impact.CapacityHeadroom", null, null); | ||
| return new("plan.capacity", snapshot.Revision, snapshot.AsOfUtc, "capacity-v1", | ||
| new SettingImpact("Medium", "Impact.Audience", "Area.plans", "Impact.Timing", "Impact.CapacityReversal", "Impact.Verify"), | ||
| metrics.AsReadOnly(), Array.Empty<ConfigurationImpactRule>(), new[] { "Impact.NoMutation", "Impact.CapacityScope", "Impact.CapacityTiming" }, "/User/Subscription/Index"); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CapabilitySetupEvaluator.cs, ConfigurationImpactEvaluator.cs, FindingLifecycle.cs, ConfigurationEvidence.cs, AdminAssistWorklistService.cs, AdminAssistRepository.cs, the listed AdminAssist tests, MCP tests, service tests, and PrintReport.cshtml synchronously block on asynchronous operations with
.Resultor.Wait(), which can cause deadlocks and reduce asynchronous efficiency. Convert the call chains toawait.Kody rule violation: Avoid Blocking Calls to Async Methods
Prompt for LLM
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.