feat(awooop): show source flow in work items
This commit is contained in:
@@ -2167,6 +2167,18 @@
|
||||
"stage": "Stage: {stage}",
|
||||
"sourceEvent": "Source event: {event}",
|
||||
"sourceRefs": "Source refs: {refs} (Sentry {sentry} / SignOz {signoz})",
|
||||
"sourceFlow": {
|
||||
"label": "Source flow: {status}",
|
||||
"detail": "refs={refs}; Sentry={sentry}; SignOz={signoz}; event={event}",
|
||||
"statuses": {
|
||||
"applied": "Applied",
|
||||
"reviewed": "Review recorded",
|
||||
"review": "Awaiting match review",
|
||||
"evidence": "Source evidence found",
|
||||
"provider": "Provider received",
|
||||
"waiting": "Waiting for source"
|
||||
}
|
||||
},
|
||||
"workItem": "Work item: {id}",
|
||||
"repair": "Repair status: {status}",
|
||||
"reason": "Reason: {reason}",
|
||||
|
||||
@@ -2168,6 +2168,18 @@
|
||||
"stage": "階段:{stage}",
|
||||
"sourceEvent": "來源事件:{event}",
|
||||
"sourceRefs": "來源 refs:{refs}(Sentry {sentry} / SignOz {signoz})",
|
||||
"sourceFlow": {
|
||||
"label": "來源流程:{status}",
|
||||
"detail": "refs={refs}; Sentry={sentry}; SignOz={signoz}; event={event}",
|
||||
"statuses": {
|
||||
"applied": "已套用",
|
||||
"reviewed": "審核已記錄",
|
||||
"review": "待審核配對",
|
||||
"evidence": "來源證據已到",
|
||||
"provider": "Provider 已接收",
|
||||
"waiting": "等待來源"
|
||||
}
|
||||
},
|
||||
"workItem": "Work item:{id}",
|
||||
"repair": "修復狀態:{status}",
|
||||
"reason": "原因:{reason}",
|
||||
|
||||
@@ -247,6 +247,14 @@ type RecurrenceWorkItemActionState = {
|
||||
error?: string | null;
|
||||
};
|
||||
|
||||
type RecurrenceSourceFlowStatus =
|
||||
| "applied"
|
||||
| "reviewed"
|
||||
| "review"
|
||||
| "evidence"
|
||||
| "provider"
|
||||
| "waiting";
|
||||
|
||||
type SloResponse = {
|
||||
adr100?: {
|
||||
verification_coverage?: {
|
||||
@@ -936,6 +944,67 @@ function sourceApplyStatusKey(status?: string | null) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
function recurrenceSourceFlowStatus({
|
||||
item,
|
||||
actionResult,
|
||||
sourceApplyStatus,
|
||||
sourceDecision,
|
||||
reviewStatus,
|
||||
}: {
|
||||
item: RecurrenceItem;
|
||||
actionResult?: RecurrenceWorkItemActionResult | null;
|
||||
sourceApplyStatus: string;
|
||||
sourceDecision: string;
|
||||
reviewStatus: string;
|
||||
}): RecurrenceSourceFlowStatus {
|
||||
const hasAppliedLink =
|
||||
sourceApplyStatus === "applied" ||
|
||||
sourceApplyStatus === "partial" ||
|
||||
Boolean(
|
||||
actionResult?.source_event_provider_event_id ||
|
||||
item.source_correlation_apply?.source_event_provider_event_id
|
||||
);
|
||||
if (hasAppliedLink) return "applied";
|
||||
|
||||
const hasRecordedReview =
|
||||
sourceDecision !== "unknown" ||
|
||||
reviewStatus === "recorded" ||
|
||||
reviewStatus === "accepted" ||
|
||||
reviewStatus === "rejected" ||
|
||||
reviewStatus === "needs_more_evidence";
|
||||
if (hasRecordedReview) return "reviewed";
|
||||
|
||||
if (item.work_item?.kind === "source_correlation_review" || item.source_correlation_review) {
|
||||
return "review";
|
||||
}
|
||||
|
||||
const sourceRefTotal =
|
||||
(item.source_ref_total ?? 0) +
|
||||
(item.sentry_ref_total ?? 0) +
|
||||
(item.signoz_ref_total ?? 0);
|
||||
if (sourceRefTotal > 0) return "evidence";
|
||||
if (item.latest_provider_event_id) return "provider";
|
||||
return "waiting";
|
||||
}
|
||||
|
||||
function recurrenceSourceFlowClass(status: RecurrenceSourceFlowStatus) {
|
||||
if (status === "applied") return "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]";
|
||||
if (status === "reviewed") return "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]";
|
||||
if (status === "review" || status === "evidence") {
|
||||
return "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]";
|
||||
}
|
||||
if (status === "provider") return "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]";
|
||||
return "border-[#e0ddd4] bg-white text-[#77736a]";
|
||||
}
|
||||
|
||||
function recurrenceSourceFlowIcon(status: RecurrenceSourceFlowStatus) {
|
||||
if (status === "applied") return ShieldCheck;
|
||||
if (status === "reviewed") return GitBranch;
|
||||
if (status === "review" || status === "evidence") return SearchCheck;
|
||||
if (status === "provider") return Network;
|
||||
return Database;
|
||||
}
|
||||
|
||||
function formatStaleRatio(value: number) {
|
||||
return `${(value * 100).toFixed(1)}%`;
|
||||
}
|
||||
@@ -1556,6 +1625,19 @@ function RecurrenceWorkQueuePanel({
|
||||
);
|
||||
const sourceApplyStatus = actionResult?.apply_status ?? sourceApply?.apply_status;
|
||||
const sourceApplyStatusKeyValue = sourceApplyStatusKey(sourceApplyStatus);
|
||||
const sourceFlowStatus = recurrenceSourceFlowStatus({
|
||||
item,
|
||||
actionResult,
|
||||
sourceApplyStatus: sourceApplyStatusKeyValue,
|
||||
sourceDecision: sourceDecisionKey,
|
||||
reviewStatus: reviewRecordStatusKey,
|
||||
});
|
||||
const SourceFlowIcon = recurrenceSourceFlowIcon(sourceFlowStatus);
|
||||
const sourceFlowEvent =
|
||||
actionResult?.source_event_provider_event_id ??
|
||||
sourceApply?.source_event_provider_event_id ??
|
||||
item.latest_provider_event_id ??
|
||||
"--";
|
||||
const canApplySource =
|
||||
isSourceReview &&
|
||||
sourceReview?.decision === "accepted" &&
|
||||
@@ -1605,6 +1687,35 @@ function RecurrenceWorkQueuePanel({
|
||||
signoz: item.signoz_ref_total ?? 0,
|
||||
})}
|
||||
</p>
|
||||
<div className="grid gap-1">
|
||||
<span
|
||||
className={cn(
|
||||
"inline-flex w-fit items-center gap-1.5 border px-2 py-1 font-semibold",
|
||||
recurrenceSourceFlowClass(sourceFlowStatus)
|
||||
)}
|
||||
>
|
||||
<SourceFlowIcon className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
{t("sourceFlow.label", {
|
||||
status: t(`sourceFlow.statuses.${sourceFlowStatus}` as never),
|
||||
})}
|
||||
</span>
|
||||
<p
|
||||
className="truncate font-mono text-xs text-[#77736a]"
|
||||
title={t("sourceFlow.detail", {
|
||||
refs: item.source_ref_total ?? 0,
|
||||
sentry: item.sentry_ref_total ?? 0,
|
||||
signoz: item.signoz_ref_total ?? 0,
|
||||
event: sourceFlowEvent,
|
||||
})}
|
||||
>
|
||||
{t("sourceFlow.detail", {
|
||||
refs: item.source_ref_total ?? 0,
|
||||
sentry: item.sentry_ref_total ?? 0,
|
||||
signoz: item.signoz_ref_total ?? 0,
|
||||
event: sourceFlowEvent,
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
<p>{t("workItem", { id: workItem?.work_item_id ?? "--" })}</p>
|
||||
<p>
|
||||
{t("repair", {
|
||||
|
||||
Reference in New Issue
Block a user