@paro.io/expert-shared-components 1.14.71 → 1.14.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/tax-axis/components/clientReport/ExecutiveSummary.d.ts +4 -2
- package/lib/tax-axis/components/clientReport/ExecutiveSummary.js +8 -6
- package/lib/tax-axis/components/clientReport/ImplementationRoadmap.d.ts +4 -3
- package/lib/tax-axis/components/clientReport/ImplementationRoadmap.js +2 -2
- package/lib/tax-axis/components/clientReport/TaxAxisClientReport.js +14 -5
- package/lib/tax-axis/lib/adapters/useEngineOutput.js +39 -3
- package/package.json +1 -1
|
@@ -7,12 +7,14 @@ interface ExecutiveSummaryProps {
|
|
|
7
7
|
computed: ComputedMap;
|
|
8
8
|
totalLo: number;
|
|
9
9
|
totalHi: number;
|
|
10
|
-
|
|
10
|
+
leadCount: number;
|
|
11
|
+
leadMidK: number;
|
|
12
|
+
leadLabel: string;
|
|
11
13
|
top3: Strategy[];
|
|
12
14
|
palette: Palette;
|
|
13
15
|
effectiveTaxRate?: number;
|
|
14
16
|
confidenceTier?: string;
|
|
15
17
|
dataYears?: number;
|
|
16
18
|
}
|
|
17
|
-
export declare function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi,
|
|
19
|
+
export declare function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi, leadCount, leadMidK, leadLabel, top3, palette, effectiveTaxRate, confidenceTier, dataYears }: ExecutiveSummaryProps): React.JSX.Element;
|
|
18
20
|
export {};
|
|
@@ -10,16 +10,18 @@ const SectionOpener_1 = require("./SectionOpener");
|
|
|
10
10
|
const ETRChart_1 = require("./ETRChart");
|
|
11
11
|
// Format K values: >= 1000K -> "$X.XM", otherwise "$XK"
|
|
12
12
|
const fmtKRange = (k) => k >= 1000 ? "$" + (k / 1000).toFixed(1) + "M" : "$" + k + "K";
|
|
13
|
-
function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi,
|
|
13
|
+
function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi, leadCount, leadMidK, leadLabel, top3, palette, effectiveTaxRate, confidenceTier, dataYears }) {
|
|
14
|
+
const actionLabel = leadLabel === "this week" ? "Immediate Actions"
|
|
15
|
+
: leadLabel === "within 30 days" ? "30-Day Actions"
|
|
16
|
+
: leadLabel === "within 90 days" ? "90-Day Actions"
|
|
17
|
+
: "Planned Actions";
|
|
14
18
|
const bizName = profile.bizName || "Client";
|
|
15
19
|
const rev = parseInt((profile.revenue || "0").replace(/,/g, "")) || 500000;
|
|
16
20
|
const dataYearsLabel = dataYears ? `${dataYears} year${dataYears > 1 ? "s" : ""}` : (profile.taxDataYears || "1 year");
|
|
17
21
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
18
22
|
react_1.default.createElement(SectionOpener_1.SectionOpener, { number: "01", eyebrow: "EXECUTIVE SUMMARY", headline: "Where " + bizName + "'s tax dollars are going \u2014 and where they don't have to.", bullets: [
|
|
19
23
|
eligible.length + " strategies apply to your current profile, with combined estimated savings of " + fmtKRange(totalLo) + "\u2013" + fmtKRange(totalHi) + " annually.",
|
|
20
|
-
|
|
21
|
-
? nowCount + " can be initiated this week without any structural changes to your business."
|
|
22
|
-
: "Implementation timeline spans the current tax year with no structural changes required.",
|
|
24
|
+
leadCount + " " + (leadCount === 1 ? "strategy" : "strategies") + " can be initiated " + leadLabel + ", representing roughly $" + leadMidK + "K of the midpoint savings estimate.",
|
|
23
25
|
"Analysis is based on " + dataYearsLabel + " of financial data and current law as of April 2026, including OBBBA provisions.",
|
|
24
26
|
], palette: palette }),
|
|
25
27
|
react_1.default.createElement("div", { style: { marginBottom: 28 } },
|
|
@@ -28,7 +30,7 @@ function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi, nowCo
|
|
|
28
30
|
react_1.default.createElement("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr", gap: 16 } }, [
|
|
29
31
|
{ v: fmtKRange(totalLo) + "\u2013" + fmtKRange(totalHi), l: "Est. Annual Savings" },
|
|
30
32
|
{ v: String(eligible.length), l: "Strategies Identified" },
|
|
31
|
-
{ v: String(
|
|
33
|
+
{ v: String(leadCount), l: actionLabel },
|
|
32
34
|
{ v: String(top3.length), l: "Priority Recommendations" },
|
|
33
35
|
].map(({ v, l }) => (react_1.default.createElement("div", { key: l },
|
|
34
36
|
react_1.default.createElement("div", { style: { fontSize: 22, fontWeight: 800, color: palette.teal, fontFamily: palette.head, lineHeight: 1.2, marginBottom: 4 } }, v),
|
|
@@ -46,7 +48,7 @@ function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi, nowCo
|
|
|
46
48
|
react_1.default.createElement("div", { style: { fontSize: 14, color: palette.gray700, lineHeight: 1.8, fontFamily: palette.body, marginBottom: 16 } },
|
|
47
49
|
top3.length,
|
|
48
50
|
" strategies represent the highest-impact opportunities and are detailed below. ",
|
|
49
|
-
|
|
51
|
+
"Of these and the broader eligible set, " + leadCount + " can be initiated " + leadLabel + ".",
|
|
50
52
|
" Savings estimates reflect your current revenue of ",
|
|
51
53
|
rev >= 1000000 ? "$" + (rev / 1000000).toFixed(1) + "M" : "$" + Math.round(rev / 1000) + "K",
|
|
52
54
|
", an effective tax rate of ",
|
|
@@ -15,13 +15,14 @@ interface ImplementationRoadmapProps {
|
|
|
15
15
|
eligible: Strategy[];
|
|
16
16
|
computed: ComputedMap;
|
|
17
17
|
top3: Strategy[];
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
leadCount: number;
|
|
19
|
+
leadMidK: number;
|
|
20
|
+
leadLabel: string;
|
|
20
21
|
bucketDefs: BucketDef[];
|
|
21
22
|
bucketTotals: Record<string, BucketTotal>;
|
|
22
23
|
activeBuckets: BucketDef[];
|
|
23
24
|
palette: Palette;
|
|
24
25
|
taxYear?: string;
|
|
25
26
|
}
|
|
26
|
-
export declare function ImplementationRoadmap({ eligible, computed, top3,
|
|
27
|
+
export declare function ImplementationRoadmap({ eligible, computed, top3, leadCount, leadMidK, leadLabel, bucketDefs, bucketTotals, activeBuckets, palette, taxYear, }: ImplementationRoadmapProps): React.JSX.Element;
|
|
27
28
|
export {};
|
|
@@ -9,7 +9,7 @@ const data_1 = require("../../lib/data");
|
|
|
9
9
|
const SectionOpener_1 = require("./SectionOpener");
|
|
10
10
|
const QuarterlyCashChart_1 = require("./QuarterlyCashChart");
|
|
11
11
|
const ImplementationTimelineChart_1 = require("./ImplementationTimelineChart");
|
|
12
|
-
function ImplementationRoadmap({ eligible, computed, top3,
|
|
12
|
+
function ImplementationRoadmap({ eligible, computed, top3, leadCount, leadMidK, leadLabel, bucketDefs, bucketTotals, activeBuckets, palette, taxYear, }) {
|
|
13
13
|
const card = {
|
|
14
14
|
background: palette.white,
|
|
15
15
|
border: "1px solid " + palette.gray200,
|
|
@@ -27,7 +27,7 @@ function ImplementationRoadmap({ eligible, computed, top3, nowCount, nowMidK, bu
|
|
|
27
27
|
};
|
|
28
28
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
29
29
|
react_1.default.createElement(SectionOpener_1.SectionOpener, { number: "03", eyebrow: "IMPLEMENTATION ROADMAP", headline: "Most savings can be locked in within the current quarter.", bullets: [
|
|
30
|
-
|
|
30
|
+
leadCount + " eligible " + (leadCount === 1 ? "strategy" : "strategies") + " can be initiated " + leadLabel + ", representing roughly $" + leadMidK + "K of the midpoint savings estimate.",
|
|
31
31
|
"Time-sensitive elections and filings have firm deadlines noted in each strategy detail above.",
|
|
32
32
|
"Year-end planning items will be reviewed in a coordinated session before December 31.",
|
|
33
33
|
], palette: palette }),
|
|
@@ -35,7 +35,7 @@ const RecommendedStrategies_1 = require("./RecommendedStrategies");
|
|
|
35
35
|
const ImplementationRoadmap_1 = require("./ImplementationRoadmap");
|
|
36
36
|
const Methodology_1 = require("./Methodology");
|
|
37
37
|
function TaxAxisClientReport({ profile, onBack, onNavigatePreparer, liveStrategies, liveComputedMap, engineRawOutput }) {
|
|
38
|
-
var _a, _b, _c
|
|
38
|
+
var _a, _b, _c;
|
|
39
39
|
const [view, setView] = (0, react_1.useState)("client");
|
|
40
40
|
const staticEligible = (0, react_1.useMemo)(() => (0, compute_1.filterEligibleStrategies)(profile), [profile]);
|
|
41
41
|
const staticComputed = (0, react_1.useMemo)(() => (0, compute_1.computeAllStrategies)(profile), [profile]);
|
|
@@ -68,8 +68,17 @@ function TaxAxisClientReport({ profile, onBack, onNavigatePreparer, liveStrategi
|
|
|
68
68
|
bucketTotals[b.key] = { strategies, lo, hi };
|
|
69
69
|
});
|
|
70
70
|
const activeBuckets = bucketDefs.filter(b => bucketTotals[b.key].strategies.length > 0);
|
|
71
|
-
|
|
72
|
-
const
|
|
71
|
+
// Lead bucket: first non-empty bucket for AT A GLANCE summaries
|
|
72
|
+
const leadBucket = activeBuckets[0];
|
|
73
|
+
const leadBt = leadBucket ? bucketTotals[leadBucket.key] : undefined;
|
|
74
|
+
const leadCount = (leadBt === null || leadBt === void 0 ? void 0 : leadBt.strategies.length) || 0;
|
|
75
|
+
const leadMidK = Math.round((((leadBt === null || leadBt === void 0 ? void 0 : leadBt.lo) || 0) + ((leadBt === null || leadBt === void 0 ? void 0 : leadBt.hi) || 0)) / 2 / 1000);
|
|
76
|
+
const leadLabel = leadBucket
|
|
77
|
+
? leadBucket.key === "now" ? "this week"
|
|
78
|
+
: leadBucket.key === "30d" ? "within 30 days"
|
|
79
|
+
: leadBucket.key === "90d" ? "within 90 days"
|
|
80
|
+
: "before year-end"
|
|
81
|
+
: "this quarter";
|
|
73
82
|
const handleToggle = (v) => {
|
|
74
83
|
if (v === "preparer" && onNavigatePreparer) {
|
|
75
84
|
onNavigatePreparer();
|
|
@@ -117,12 +126,12 @@ function TaxAxisClientReport({ profile, onBack, onNavigatePreparer, liveStrategi
|
|
|
117
126
|
react_1.default.createElement("div", { style: { maxWidth: 680, margin: "0 auto", padding: "32px 20px 60px" } },
|
|
118
127
|
react_1.default.createElement(ClientReportCover_1.ClientReportCover, { profile: profile, palette: palette_1.P }),
|
|
119
128
|
react_1.default.createElement(ClientReportTOC_1.ClientReportTOC, { bizName: bizName, palette: palette_1.P }),
|
|
120
|
-
react_1.default.createElement(ExecutiveSummary_1.ExecutiveSummary, { profile: profile, eligible: eligible, computed: computed, totalLo: totalLo, totalHi: totalHi,
|
|
129
|
+
react_1.default.createElement(ExecutiveSummary_1.ExecutiveSummary, { profile: profile, eligible: eligible, computed: computed, totalLo: totalLo, totalHi: totalHi, leadCount: leadCount, leadMidK: leadMidK, leadLabel: leadLabel, top3: top3, palette: palette_1.P, effectiveTaxRate: (_a = engineRawOutput === null || engineRawOutput === void 0 ? void 0 : engineRawOutput.business_profile) === null || _a === void 0 ? void 0 : _a.effective_tax_rate, confidenceTier: (_b = engineRawOutput === null || engineRawOutput === void 0 ? void 0 : engineRawOutput.business_profile) === null || _b === void 0 ? void 0 : _b.confidence_tier, dataYears: (_c = engineRawOutput === null || engineRawOutput === void 0 ? void 0 : engineRawOutput.business_profile) === null || _c === void 0 ? void 0 : _c.data_years }),
|
|
121
130
|
react_1.default.createElement("div", { style: { background: palette_1.P.gray50, borderLeft: "3px solid " + palette_1.P.gray300, borderRadius: "0 8px 8px 0", padding: "14px 20px", marginBottom: 20, fontSize: 11, color: palette_1.P.gray500, lineHeight: 1.7, fontFamily: palette_1.P.body } },
|
|
122
131
|
"This summary was prepared using TaxAxis, Paro's AI-powered tax analysis engine. Savings estimates are based on financial data provided for tax year " + profile.year + " (" + (profile.taxDataYears || "1 year") + " of data). All figures are estimates. Your tax preparer has reviewed these recommendations.",
|
|
123
132
|
hasOBBBA && " Some strategies reference provisions from the One Big Beautiful Bill Act (OBBBA), signed July 4, 2025, with limited IRS guidance."),
|
|
124
133
|
react_1.default.createElement(RecommendedStrategies_1.RecommendedStrategies, { profile: profile, eligible: eligible, computed: computed, top3: top3, hasOBBBA: hasOBBBA, palette: palette_1.P, interactionWarnings: engineRawOutput === null || engineRawOutput === void 0 ? void 0 : engineRawOutput.strategy_interaction_warnings }),
|
|
125
|
-
react_1.default.createElement(ImplementationRoadmap_1.ImplementationRoadmap, { eligible: eligible, computed: computed, top3: top3,
|
|
134
|
+
react_1.default.createElement(ImplementationRoadmap_1.ImplementationRoadmap, { eligible: eligible, computed: computed, top3: top3, leadCount: leadCount, leadMidK: leadMidK, leadLabel: leadLabel, bucketDefs: bucketDefs, bucketTotals: bucketTotals, activeBuckets: activeBuckets, palette: palette_1.P, taxYear: profile.year }),
|
|
126
135
|
react_1.default.createElement(Methodology_1.Methodology, { profile: profile, eligible: eligible, palette: palette_1.P }),
|
|
127
136
|
react_1.default.createElement("div", { style: { padding: "16px 20px", marginBottom: 16, fontSize: 10, color: palette_1.P.gray400, lineHeight: 1.7, fontFamily: palette_1.P.body } }, "This summary was generated by TaxAxis, an AI-powered analysis tool by Paro. Recommendations are based on financial data provided and current tax law as of April 2026, including OBBBA provisions. These are estimates, not guarantees. Consult your tax preparer before implementing any strategy. This is not legal or financial advice."),
|
|
128
137
|
react_1.default.createElement("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "12px 0", borderTop: "1px solid " + palette_1.P.gray200, fontSize: 10, color: palette_1.P.gray400, fontFamily: palette_1.P.mono } },
|
|
@@ -25,6 +25,42 @@ for (const s of data_1.STRATEGIES) {
|
|
|
25
25
|
CATEGORY_BY_RANK.set(s.rank, s.cat);
|
|
26
26
|
CODE_BY_RANK.set(s.rank, s.code);
|
|
27
27
|
}
|
|
28
|
+
// Deterministic timeline bucket assignment by strategy number.
|
|
29
|
+
// Overrides LLM-assigned buckets to ensure consistent reports across runs.
|
|
30
|
+
// Bucket assignment logic:
|
|
31
|
+
// now: CPA can action in <2 hours, no external coordination needed
|
|
32
|
+
// 30d: Requires professional setup, plan changes, or payroll adjustments
|
|
33
|
+
// 90d: Requires specialist studies, amended returns, or multi-party coordination
|
|
34
|
+
const TIMELINE_BUCKET_BY_STRATEGY = {
|
|
35
|
+
// --- THIS WEEK: Documentation, reclassification, simple calculations ---
|
|
36
|
+
10: "now", // S10 Business Meals §274 — reclassify existing expenses
|
|
37
|
+
11: "now", // S11 Home Office §280A — calculate deduction, measure space
|
|
38
|
+
13: "now", // S13 Augusta Rule §280A(g) — document rental days
|
|
39
|
+
17: "now", // S17 Vehicle Expense §274 — review mileage logs, elect method
|
|
40
|
+
// --- WITHIN 30 DAYS: Professional action, plan setup, payroll changes ---
|
|
41
|
+
1: "30d", // S1 S-Corp Salary §3121 — BLS benchmarking memo, payroll adjustment
|
|
42
|
+
2: "30d", // S2 Section 179 — asset purchase timing, election
|
|
43
|
+
3: "30d", // S3 Bonus Depreciation §168(k) — election decision
|
|
44
|
+
7: "30d", // S7 Retirement §401(k) — plan design review, contribution change
|
|
45
|
+
9: "30d", // S9 HSA §223 — enrollment, contribution adjustment
|
|
46
|
+
12: "30d", // S12 Accountable Plan §62 — establish/update plan document
|
|
47
|
+
14: "30d", // S14 Family Employment §73 — payroll onboarding, age verification
|
|
48
|
+
21: "30d", // S21 Tips Deduction (OBBBA) — payroll system update
|
|
49
|
+
22: "30d", // S22 Overtime Deduction (OBBBA) — payroll system update
|
|
50
|
+
25: "30d", // S25 Trump Accounts (OBBBA) — account establishment
|
|
51
|
+
// --- WITHIN 90 DAYS: Specialist study, amended returns, multi-party coordination ---
|
|
52
|
+
4: "90d", // S4 QBI §199A — SSTB analysis, entity structure review
|
|
53
|
+
5: "90d", // S5 R&D Credit §41 — specialist study, Form 6765 prep
|
|
54
|
+
6: "90d", // S6 WOTC §51 — certification process, hiring program setup
|
|
55
|
+
8: "90d", // S8 Cost Segregation §168 — engineering study required
|
|
56
|
+
15: "90d", // S15 PTE/SALT — state election filing, deadline coordination
|
|
57
|
+
16: "90d", // S16 §179D Energy — energy efficiency certification required
|
|
58
|
+
18: "90d", // S18 Insurance §79/§264 — carrier coordination, policy restructuring
|
|
59
|
+
19: "90d", // S19 §1031 Like-Kind — qualified intermediary, identification periods
|
|
60
|
+
20: "90d", // S20 QSBS §1202 — stock qualification analysis, holding period review
|
|
61
|
+
23: "90d", // S23 §174A R&E Catch-Up — amended returns for 2022-2024
|
|
62
|
+
24: "90d", // S24 Childcare §45F — facility/program establishment
|
|
63
|
+
};
|
|
28
64
|
// ---------------------------------------------------------------------------
|
|
29
65
|
// Core mapping — engine strategy_analysis entry -> canonical Strategy
|
|
30
66
|
// ---------------------------------------------------------------------------
|
|
@@ -48,9 +84,9 @@ function mapAnalysisToStrategy(sa, idx, pc) {
|
|
|
48
84
|
const formsFromTrace = Array.isArray(ct.forms_required)
|
|
49
85
|
? ct.forms_required.join(", ")
|
|
50
86
|
: undefined;
|
|
51
|
-
// Timeline bucket: derive from priority as a reasonable default
|
|
52
87
|
const priority = (sa.priority_tier || "MEDIUM").toUpperCase();
|
|
53
|
-
|
|
88
|
+
// Deterministic bucket from static map; falls back to "30d" for unknown strategies.
|
|
89
|
+
const timelineBucket = TIMELINE_BUCKET_BY_STRATEGY[strategyNumber !== null && strategyNumber !== void 0 ? strategyNumber : 0] || "30d";
|
|
54
90
|
return {
|
|
55
91
|
rank: idx + 1,
|
|
56
92
|
strategyNumber: strategyNumber !== null && strategyNumber !== void 0 ? strategyNumber : undefined,
|
|
@@ -64,7 +100,7 @@ function mapAnalysisToStrategy(sa, idx, pc) {
|
|
|
64
100
|
entities: [],
|
|
65
101
|
lo,
|
|
66
102
|
hi,
|
|
67
|
-
timeline: timelineBucket === "now" ? "
|
|
103
|
+
timeline: timelineBucket === "now" ? "This week" : timelineBucket === "30d" ? "Within 30 days" : timelineBucket === "filing" ? "At filing" : "Within 90 days",
|
|
68
104
|
timelineBucket,
|
|
69
105
|
abstract: sa.engagement_recommendation || "",
|
|
70
106
|
warning: (_j = sa.risk_disclosure) !== null && _j !== void 0 ? _j : null,
|