# 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 January–March 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 3–5 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.