seubert-claims/tasks/prd-renewal-groups.md

168 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PRD: Renewal Groups — Client/Policy Onboarding Workflow
**Status:** Ready for Development
**Author:** Cascade (from user requirements)
**Date:** 2026-04-09
---
## 1. Introduction / Overview
Renewal Groups logically cluster insurance policies that share a common renewal window. They drive the scheduling of SHAPE tasks and determine the `renewalDate` displayed on client cards throughout the app.
Today, Renewal Groups can be created and managed manually. What is **missing** is a structured onboarding flow that activates when a new client or policy enters the system (via AMS360 sync). This feature adds:
- A **New Client / Policy Setup page** where a Manager or Admin reviews incoming clients/policies that have not yet been configured.
- A **system recommendation engine** that proposes Renewal Group groupings and a default `renewalDate` based on configurable rules.
- A **UI** allowing the Manager/Admin to accept, modify, or override those recommendations before finalising the client's configuration.
---
## 2. Goals
1. Ensure every new client that enters via AMS360 sync gets a `renewalDate` and a `claimsAdvocate` before tasks are generated.
2. Reduce manual configuration effort by surfacing system-generated grouping recommendations.
3. Give Managers/Admins full control to customise the grouping window, default renewal date logic, and per-client overrides.
4. Keep existing Renewal Groups untouched — this flow only applies to unconfigured clients/policies.
---
## 3. User Stories
- **As a Manager**, I want to see a list of clients that have synced from AMS360 but have not been fully configured, so I can quickly identify what needs attention.
- **As a Manager**, I want the system to recommend how to group a new client's policies into Renewal Groups based on their expiration dates, so I don't have to figure it out manually.
- **As a Manager**, I want to customise the grouping window (default 90 days) and the renewal date selection rule (default: earliest date closest to the start of the year within the group), so the defaults match our business practice but can be adjusted.
- **As a Manager**, I want to assign a `claimsAdvocate` and optionally add notes for any new client during setup, so the client is fully configured in one step.
- **As a Manager**, I want to accept, modify, or reject system recommendations for each group before saving, so I remain in control of the final configuration.
- **As an Admin**, I want to be able to reopen the setup wizard for any client at any time (e.g., after a new policy is added mid-year), so I can re-group without losing existing data.
---
## 4. Functional Requirements
### 4.1 New Client Setup Queue
1. The system **must** display a dedicated "New Client Setup" page (or prominent section in the Manager view) listing all clients that:
- Were added via AMS360 sync, **and**
- Are missing either a `renewalDate` **or** a `claimsAdvocate`.
2. Each entry in the queue **must** show: client name, number of policies, earliest and latest policy expiration dates, and how long they have been in the queue (days since sync).
3. The queue **must** be accessible only to users with the **Manager** or **Admin** role.
4. Clicking a client in the queue **must** open the Setup Wizard for that client.
### 4.2 Setup Wizard — Policy Overview
5. The wizard **must** display all policies belonging to the new client with: policy number, type, carrier, and expiration date.
6. Policies with no expiration date **must** be flagged with a visual warning and excluded from auto-grouping recommendations (but still assignable manually).
### 4.3 Recommendation Engine
7. The system **must** group policies into recommended Renewal Groups using the following default logic:
- Policies whose expiration dates fall within a **90-day window** of each other are placed in the same group.
- The window size (90 days) **must** be configurable per-run by the Manager in the wizard UI.
8. Within each recommended group, the system **must** calculate a default `renewalDate` as follows:
- Select the expiration date that is **nearest to the start of the calendar year** (i.e., earliest in JanuaryMarch if available, otherwise the earliest overall) and add **1 day** (`expirationDate + 1`).
- This rule **must** be configurable: the Manager can switch to "earliest in group" or "latest in group" or manually enter a date.
9. The recommendation engine **must** also handle **standalone policies** (policies not grouped with any other policy):
- Their `renewalDate` is `expirationDate + 1`.
- They are displayed as a single-policy "group" in the wizard.
### 4.4 Setup Wizard — Review & Customise
10. The wizard **must** display system-recommended groups as drag-and-drop cards (using `@dnd-kit`), each showing:
- Proposed group name (editable inline).
- Member policies with their expiration dates.
- Proposed `renewalDate` (editable via date picker).
- Renewal date derivation rule selector (nearest-to-year-start / earliest / latest / manual).
11. The Manager **must** be able to:
- Move a policy from one recommended group to another via drag-and-drop or a move selector.
- Split a group by removing a policy and creating a new group from it.
- Merge two groups by dragging one group's policies into another.
- Delete a group (policies revert to ungrouped / standalone).
- Create a blank group manually and add policies to it.
12. The wizard **must** show a live preview of the resulting `renewalDate` for each group as policies are moved.
13. The **90-day grouping window** input **must** be visible at the top of the wizard and re-running it **must** re-compute recommendations (with a confirmation if the Manager has already made manual changes).
### 4.5 Claims Advocate Assignment
14. The wizard **must** include a **Claims Advocate** selector (Claims-department users only) that applies to the whole client.
15. The advocate selector **must** be required before the wizard can be finalised.
### 4.6 Notes
16. The wizard **must** include a free-text notes field for client-level notes and an optional per-group notes field.
### 4.7 Finalisation
17. On "Save & Complete", the system **must**:
- Persist all Renewal Groups (new or modified) to the database.
- Set `client.renewalDate` to the `renewalDate` of the **default renewal group** — the Manager must designate exactly one group as default (radio/star selector on each group card); there is no auto-selection.
- If there is only one group, it is automatically treated as the default without requiring an explicit selection.
- Set `client.claimsAdvocate`.
- Remove the client from the setup queue.
18. The system **must** allow a Manager to **Save as Draft** — keeping the client in the queue but preserving partial work.
19. After finalisation, the wizard **must** be re-openable from the client detail page (e.g., an "Edit Setup" action) for re-grouping when new policies are added.
### 4.8 Renewal Date Display Rules (existing behaviour, confirmed)
20. A policy that belongs to a Renewal Group **must** display `renewalDate` from its group.
21. A standalone policy (no group) **must** display `expirationDate + 1` as its renewal date throughout the app.
22. A client with no policies and no groups **must** show no renewal date until one is manually assigned.
### 4.9 Global Settings (Admin Panel)
23. Admins **must** be able to set **global defaults** in the Admin Panel for:
- Grouping window (default: 90 days).
- Renewal date rule (default: nearest-to-year-start).
These defaults pre-populate the wizard but can be overridden per client per run.
24. Global settings **must not** retroactively change already-finalised Renewal Groups.
---
## 5. Non-Goals (Out of Scope)
- Automated assignment of a `claimsAdvocate` by the system — this always requires a human decision.
- Email or external notifications when new clients enter the queue (in-app only for now).
- Bulk "apply to all" finalisation without per-client review.
- Any changes to how existing, already-configured Renewal Groups behave in the rest of the app.
- Exposing this workflow to Claims Advocates or non-privileged users.
---
## 6. Design Considerations
- The Setup Queue should appear as a **badge/alert on the Manager nav item** showing count of unconfigured clients.
- The wizard should be a **full-page or large modal** flow — not a drawer — given the amount of information.
- Recommended groups should use a **card-based kanban-style layout** so policies can be visually moved between groups.
- Use existing UI conventions: shadcn/ui cards, Tailwind, lucide-react icons, existing Badge/Select/DatePicker components.
- The grouping-window control should be a **number input with a "Re-run Recommendations" button** adjacent to it.
- Drag-and-drop: use `@dnd-kit/core` (already a common pattern in the stack) or a lightweight alternative.
---
## 7. Technical Considerations
- **Database:** `RenewalGroup` model already exists with `renewalDate`, `clientId`, `policyGroupId` relations. A `setupCompletedAt` timestamp on `Client` (nullable) is the simplest way to track queue membership — `NULL` means unconfigured.
- **Queue query:** Clients where `claimsAdvocateId IS NULL OR renewalDate IS NULL` and `createdAt` is post-sync.
- **Recommendation engine:** Pure TypeScript function — accepts a list of `{ policyId, expirationDate }` and config `{ windowDays, rule }`, returns `{ groups: { policies[], proposedRenewalDate }[] }`. Can live in `src/lib/renewal-group-recommendations.ts`.
- **Global settings:** Store in the existing `sync_config` table or a new `app_settings` key-value table. Surfaced in the Admin Panel under a new "Renewal Groups" settings section.
- **Re-run safety:** Track `wizardDirty` client-side; prompt confirmation before overwriting manual changes with a fresh recommendation run.
- **Drag-and-drop:** `@dnd-kit/core` + `@dnd-kit/sortable` for policy cards within and between groups.
---
## 8. Success Metrics
- Zero new clients remain in the setup queue for more than 5 business days after sync.
- Manager setup time per client < 5 minutes for a typical 35 policy client.
- Recommendation acceptance rate (no manual changes) tracked in `shape_import_logs` or a new event log target 60%.
---
## 9. Open Questions
~~All questions resolved.~~
1. **Default group**: The Manager explicitly designates exactly one group as the default. No auto-selection.
2. **New policy on existing client**: The recommendation engine runs again and suggests a group or standalone; the Manager reviews and confirms via the wizard re-open flow.
3. **Global settings**: Managed in the Admin Panel.
4. **Drag-and-drop**: `@dnd-kit/core` + `@dnd-kit/sortable` installed as a project dependency.