fix: invert shoring ratio logic — higher offshore = better
The shoring indicator logic was backwards. In the business context, higher offshore = more cost-efficient = GOOD. Inverted logic: - Green: offshore >= threshold (target met, e.g. >= 55%) - Yellow: offshore close to threshold (threshold-10 to threshold) - Red: offshore below threshold (too little offshore, too expensive) Updated: - ShoringIndicator: getSeverity() inverted, badge text updated - ProjectModal: "Max Offshore" renamed to "Min Offshore" with new tooltip - AI Tool: status text reflects "target met" vs "below target" - Tool description: "higher offshore is better, threshold is minimum" Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -499,8 +499,8 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className={labelClass} htmlFor="shoringThreshold">
|
<label className={labelClass} htmlFor="shoringThreshold">
|
||||||
Max Offshore %
|
Min Offshore %
|
||||||
<InfoTooltip content="Maximum allowed offshore staffing percentage (0-100). Triggers a warning when exceeded. Default: 55%." />
|
<InfoTooltip content="Minimum offshore staffing target (0-100). Green when met, red when below. Higher offshore = more cost-efficient. Default: 55%." />
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="shoringThreshold"
|
id="shoringThreshold"
|
||||||
|
|||||||
@@ -33,9 +33,10 @@ function getCountryColor(code: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getSeverity(offshoreRatio: number, threshold: number): "green" | "yellow" | "red" {
|
function getSeverity(offshoreRatio: number, threshold: number): "green" | "yellow" | "red" {
|
||||||
if (offshoreRatio >= threshold) return "red";
|
// Higher offshore = better (cost-efficient). Threshold is the MINIMUM target.
|
||||||
if (offshoreRatio >= threshold - 10) return "yellow";
|
if (offshoreRatio >= threshold) return "green"; // Target met
|
||||||
return "green";
|
if (offshoreRatio >= threshold - 10) return "yellow"; // Close to target
|
||||||
|
return "red"; // Too little offshore
|
||||||
}
|
}
|
||||||
|
|
||||||
const SEVERITY_BADGE: Record<string, string> = {
|
const SEVERITY_BADGE: Record<string, string> = {
|
||||||
@@ -127,7 +128,7 @@ export function ShoringIndicator({ projectId }: { projectId: string }) {
|
|||||||
</h3>
|
</h3>
|
||||||
<span className={`inline-block rounded-full px-2.5 py-0.5 text-xs font-medium ${SEVERITY_BADGE[severity]}`}>
|
<span className={`inline-block rounded-full px-2.5 py-0.5 text-xs font-medium ${SEVERITY_BADGE[severity]}`}>
|
||||||
{data.offshoreRatio}% offshore
|
{data.offshoreRatio}% offshore
|
||||||
{severity === "red" ? ` — Above ${data.threshold}% limit` : ""}
|
{severity === "green" ? " — Target met" : severity === "red" ? ` — Below ${data.threshold}% target` : ""}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1389,7 +1389,7 @@ export const TOOL_DEFINITIONS: ToolDef[] = [
|
|||||||
type: "function",
|
type: "function",
|
||||||
function: {
|
function: {
|
||||||
name: "get_shoring_ratio",
|
name: "get_shoring_ratio",
|
||||||
description: "Get the onshore/offshore staffing ratio for a project. Shows the percentage of work hours allocated to each country, whether the project exceeds its nearshore threshold, and a full country breakdown.",
|
description: "Get the onshore/offshore staffing ratio for a project. Higher offshore is better (cost-efficient). The threshold is the MINIMUM offshore target. Shows country breakdown and whether the target is met.",
|
||||||
parameters: {
|
parameters: {
|
||||||
type: "object",
|
type: "object",
|
||||||
properties: {
|
properties: {
|
||||||
@@ -5576,9 +5576,13 @@ const executors = {
|
|||||||
.map(([code, info]) => `${code} ${info.pct}% (${info.resourceCount} people)`)
|
.map(([code, info]) => `${code} ${info.pct}% (${info.resourceCount} people)`)
|
||||||
.join(", ");
|
.join(", ");
|
||||||
|
|
||||||
const warning = result.isAboveThreshold ? ` -- Above ${threshold}% offshore threshold!` : "";
|
const status = result.offshoreRatio >= threshold
|
||||||
|
? `Target met (>=${threshold}% offshore)`
|
||||||
|
: result.offshoreRatio >= threshold - 10
|
||||||
|
? `Close to target (${threshold}% offshore needed)`
|
||||||
|
: `Below target — only ${result.offshoreRatio}% offshore, need ${threshold}%`;
|
||||||
|
|
||||||
return `Project "${project.name}" (${project.shortCode}): ${result.onshoreRatio}% onshore (${onshoreCode}), ${result.offshoreRatio}% offshore. Breakdown: ${countryParts}.${warning}${result.unknownCount > 0 ? ` (${result.unknownCount} resource(s) without country)` : ""}`;
|
return `Project "${project.name}" (${project.shortCode}): ${result.onshoreRatio}% onshore (${onshoreCode}), ${result.offshoreRatio}% offshore. ${status}. Breakdown: ${countryParts}.${result.unknownCount > 0 ? ` (${result.unknownCount} resource(s) without country)` : ""}`;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user