Includes: API (Express/TypeScript), Astro site, Python workers, document generators, FCC compliance tools, Canada CRTC formation, Ansible infrastructure, and deployment scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
79 lines
2.7 KiB
TypeScript
79 lines
2.7 KiB
TypeScript
// Safe harbor recommender — client-side wrapper around
|
|
// GET /api/v1/fcc/safe-harbor-recommendation.
|
|
//
|
|
// Consumed by RevenueStep to display a contextual recommendation next
|
|
// to the method dropdown. The server does the actual comparison against
|
|
// the customer's CDR traffic study — this is just a thin fetch wrapper.
|
|
|
|
export type Recommendation =
|
|
| "safe_harbor_okay"
|
|
| "use_actual_saves"
|
|
| "use_actual_required"
|
|
| "no_actual_data"
|
|
| "not_allowed"
|
|
| "no_safe_harbor_for_category";
|
|
|
|
export interface SafeHarborRecommendation {
|
|
recommendation: Recommendation;
|
|
category: string;
|
|
year: number;
|
|
safe_harbor_pct: number | null;
|
|
actual_interstate_pct: number | null;
|
|
delta_percentage_points?: number;
|
|
estimated_usf_delta_cents?: number;
|
|
total_revenue_cents?: number;
|
|
study_methodology?: string | null;
|
|
total_classified_calls?: number;
|
|
message: string;
|
|
}
|
|
|
|
export async function fetchSafeHarborRecommendation(opts: {
|
|
profile_id?: number | null;
|
|
year: number;
|
|
category: string;
|
|
total_revenue_cents?: number;
|
|
}): Promise<SafeHarborRecommendation | null> {
|
|
const params = new URLSearchParams({
|
|
year: String(opts.year),
|
|
category: opts.category,
|
|
});
|
|
if (opts.profile_id) params.set("profile_id", String(opts.profile_id));
|
|
if (opts.total_revenue_cents) {
|
|
params.set("total_revenue_cents", String(opts.total_revenue_cents));
|
|
}
|
|
try {
|
|
const r = await fetch(`/api/v1/fcc/safe-harbor-recommendation?${params.toString()}`);
|
|
if (!r.ok) return null;
|
|
return await r.json();
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/** UI hint: banner color + preferred method for a recommendation. */
|
|
export function recommendationBadge(rec: Recommendation): {
|
|
tone: "ok" | "info" | "warn" | "danger";
|
|
suggest: "safe_harbor" | "actual_data" | "traffic_study" | null;
|
|
headline: string;
|
|
} {
|
|
switch (rec) {
|
|
case "safe_harbor_okay":
|
|
return { tone: "ok", suggest: "safe_harbor",
|
|
headline: "Safe harbor is a good choice here." };
|
|
case "use_actual_saves":
|
|
return { tone: "info", suggest: "actual_data",
|
|
headline: "Using actual data would save you money." };
|
|
case "use_actual_required":
|
|
return { tone: "warn", suggest: "traffic_study",
|
|
headline: "Safe harbor would under-report — switch to traffic study." };
|
|
case "no_actual_data":
|
|
return { tone: "info", suggest: "safe_harbor",
|
|
headline: "No traffic study — safe harbor is the sensible default." };
|
|
case "not_allowed":
|
|
return { tone: "danger", suggest: "traffic_study",
|
|
headline: "Safe harbor not allowed for this category." };
|
|
case "no_safe_harbor_for_category":
|
|
return { tone: "danger", suggest: "actual_data",
|
|
headline: "No safe harbor defined for this category / year." };
|
|
}
|
|
}
|