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

169 lines
11 KiB
Markdown
Raw Normal View History

# 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.