All benefits

Plan Facts Parsing Analysis · v1

Short-Term Disability

One plan with three per-class variables (benefit %, max benefit, tax treatment). The parser captures exactly those for each class and stores everything else as plan-level — matching Plansight's domain model.

Endpoint
POST /std
Parse method
parseQuoteStDisability()
Source range
PlanfactService.php:3061–3447 (~387 lines)
Source pull
plansight - Bit Bucket Pull 4.26

Bottom line

Implements the domain model correctly.

An ST disability plan in Plansight is treated as one plan with three per-class variables: benefit percentage, maximum weekly benefit, and tax treatment. The parser captures exactly those for each class. Everything else is plan-level — taken from class 1 — which is intentional. The parser even comments this in line 3134: "Use the first class for the rest of the quote."

Per-class handling

The three variables that differ per class.

VariableQuote fieldPlan Facts source
Benefit percentage paidstDisabilityBenefitPercentage-NBenefit Schedule.[Class].Benefit Amount
Maximum weekly benefitstDisabilityMaxWeeklyBenefit-NBenefit Schedule.[Class].Benefit Maximum
Tax treatmentstDisabilityTaxFreeBenefit-NContributions.[Class].Tax Treatment

Class label format observed: 1 - FTE, 2 - MGMT. Loop: PlanfactService.php:3094–3132.

What's mapped

All Plan Facts fields the ST parser captures into the Quote (per-class above; rest are plan-level via class 1).

Plan Facts fieldQuote fieldNotes
Plan NamenameDirect
Benefit Schedule.[Class].Benefit AmountstDisabilityBenefitPercentage-NPer-class
Benefit Schedule.[Class].Benefit MaximumstDisabilityMaxWeeklyBenefit-NPer-class; regex strips $
Benefit Schedule.[Class].Benefit MinimumstDisabilityMinimumWeeklyBenefitPlan-level (class 1)
Benefit Schedule.[Class].Injury Elimination PeriodstDisabilityInjuryEliminationPeriodPlan-level
Benefit Schedule.[Class].Sickness Elimination PeriodstDisabilityMaximumBenefitDurationPlan-level
Benefit Schedule.[Class].Earnings DefinitionstDisabilityEarningsDefinitionPlan-level
Contributions.[Class].Contribution TypecontributionVoluntaryPlan-level enum
Contributions.[Class].Tax TreatmentstDisabilityTaxFreeBenefit-NPer-class
Participation.[Class].Minimum Enrolled LivesstDisabilityParticipationRequirementsLivesPlan-level
Participation.[Class].Minimum Participation %stDisabilityParticipationRequirementsPercentagePlan-level
Definition of Disability.[Class].Definition of DisabilitystDisabilityDefinitionOfDisabilityPlan-level enum (Duties AND/OR/Only Income)
Definition of Disability.[Class].Earnings TeststDisabilityEarningsTest + stDisabilityEarningTestElimPerPlan-level
Definition of Disability.[Class].First Day HospitalstDisabilityFirstDayHospitalPlan-level
Definition of Disability.[Class].Routine PregnancystDisabilityRoutinePregnancyPlan-level
Definition of Disability.[Class].Zero Day ResidualstDisabilityZeroDayResidualPlan-level
Definition of Disability.[Class].Partial Disability FormulastDisabilityPartialDisabilityPlan-level (inverted: "total only" → "Yes")
Pre-existing Conditions.[Class].Look-back PeriodstDisabilityPreExistingLimitationsMonthsLookbackPlan-level
Pre-existing Conditions.[Class].Exclusion PeriodstDisabilityPreExistingLimitationsMonthsExclusionPlan-level
Portability.[Class].PortabilitystDisabilityPortabilityPlan-level (implied)
FICA MatchstDisabilityFicaMatchGlobal
W-2 PrepstDisabilityW2PrepGlobal
Rates.[Class].Composite Rate.RateY19_Under + rateStructure = "Composite"Plan-level (class 1 rates only)
Rates.[Class].Step-ratesY19_Under, Y20_24, … Y70_AbovePlan-level (class 1 rates only)

Plan-level by design

Plan Facts returns these per-class; Plansight stores them as plan-level (class 1's value is the plan value).

This is intentional, not a gap.

Plansight collapses disability plans into one plan with three per-class variables. Other fields — including rates, elimination periods, participation, definition of disability, etc. — are stored once per plan. Plan Facts returning per-class variation on these is information richer than the broker model needs.

Potentially mapped incorrectly

Two small items worth a verify.

Verify the cross-write at line 3676 (LT parse) PlanfactService.php:3676

Inside the LT Disability parse method, the assignment for "Definition of Disability" appears to target stDisabilityDefinitionOfDisability (the ST field). It may be intentional shared usage — or it may be a copy-paste from the ST parser. Worth a quick check; if it isn't intentional, it's a one-line edit. (Listed here because it affects the ST field value during LT parsing.)

Cursor prompt
In app/Services/PlanfactService.php at around line 3676, inside parseQuoteLtDisability(), there's an assignment that writes to stDisabilityDefinitionOfDisability (the ST field) instead of ltDisabilityDefinitionOfDisability (the LT field).

Please:
1. Open that line and confirm the field name being assigned.
2. If it's writing to the ST field, change it to the LT field name.
3. Then grep this file for any other places where the LT parser writes to an ST-prefixed field, or vice versa, in case there are similar copy-paste artifacts.
Vestigial Quote form fields Quote form / parser unaffected

The Quote form asks for two more per-class fields beyond the canonical three: Benefit Change (Decrease / No Decrease) and Min Benefit Percentage. Confirmed by the team as effectively unused in practice. Candidates for removal in any future cleanup of the disability quote workflow.

Cursor prompt
I'd like to remove two unused per-class fields from the Short-Term Disability Quote form:
- "Benefit Change" (Decrease / No Decrease)
- "Min Benefit Percentage"

Please:
1. Find the Blade template (or Vue/JS component) that renders the ST Disability quote form per-class inputs.
2. Find the Quote model field definitions for stDisabilityBenefitChange-N and stDisabilityMinBenefitPercentage-N (or similar names).
3. Show me what removing both would touch — form template, validation, parser logic, any Excel export, any presentation rendering — before making changes. Don't change anything yet, just produce the list.

Manual-entry-only fields

Quote fields the form expects but Plan Facts doesn't return.

Reference: app/Console/Commands/QuoteUpdateForStDisabilityPS3190.php:127 describes the schema migration that introduced these fields.

Recommendations

  1. Verify line 3676 cross-write 5 minutes

    Confirm whether the LT parser writing to stDisabilityDefinitionOfDisability is intentional. If not, one-line fix.

  2. Decide on the vestigial form fields Product call

    Steve confirmed Benefit Change and Min Benefit Percentage are effectively unused. If removed, the form gets simpler and the parse stays the same.

  3. Optional: UI note for class-2+ differences on plan-level fields Small

    If Plan Facts returns differing elimination periods (or any plan-level field) per class, surface a small note: "Class 1 used as the plan value — review if needed." No data-model change.

Code references

FileLinesPurpose
app/Services/PlanfactService.php185–199, 230classes_override request; /std endpoint
app/Services/PlanfactService.php454parseQuote() dispatch to ST parser
app/Services/PlanfactService.php3061–3447parseQuoteStDisability() — full parser
app/Services/PlanfactService.php3094–3132Per-class loop
app/Services/PlanfactService.php3134–3137"Use the first class for the rest of the quote"
app/Http/Controllers/PlanfactsController.php165Stage parsed result on QuoteAi->aiResponseParsed
app/Http/Controllers/Rest/App/QuoteController.php501$model->fill($aiQuote->aiResponseParsed[$index])