fix: extract date prefix from ad-hoc task text for correct dueDate/completedAt

This commit is contained in:
lorentz 2026-04-08 12:06:41 +00:00
parent ca2c9c701d
commit ce84a5435e
2 changed files with 174 additions and 2 deletions

View file

@ -0,0 +1,161 @@
# Task Generation & Parent-Child Relationships — Design Review
**Date:** 2026-04-08
**App:** OnDeck — Insurance Broker Claims Management
**Status:** Under Review
---
## Current State Summary
Tasks always carry `clientId` (required) and optionally `policyId` or `policyGroupId`. Generation is triggered per-PolicyGroup or per-standalone-policy, matched to clients by designation. The core gap is that **templates have no concept of what level they belong to** — so the same template is generated for every policy or group, creating the redundancy and noise problems described below.
---
## Scenario Analysis
### 1. New Policy + New Client
**Status: Straightforward — no issues.**
Auto-generate cron picks it up after 20 days. Client gets their designation, policies are created, PolicyGroup optionally assigned, tasks generate from matching templates. Clean path, no design changes needed.
---
### 2. New Policy + Existing Client
#### Is there more than one claims review?
Yes, currently — and this is the primary bug. If a client has 3 ungrouped policies, they receive 3 claims reviews. A claims review is a *client-level* concern (one per renewal cycle), not a per-policy concern.
**Fix:** Introduce a `taskLevel` field on `TaskTemplate`:
| Level | Meaning | Example Tasks |
|---|---|---|
| `CLIENT` | Generate once per client per renewal cycle | Claims Review |
| `GROUP` | Generate once per PolicyGroup | Renewal prep, aggregate tasks |
| `POLICY` | Generate once per policy | Loss Run |
Without this distinction, smart task generation is not achievable.
#### Should a renewal group automatically be created?
**Recommendation: Suggest, don't auto-create.**
When a new policy is added to an existing client, check if any existing policies share a renewal date within ±30 days. If so, surface a prompt:
> *"This policy has a similar renewal date to [Group X] — add it to that group?"*
Auto-creation can produce wrong groups silently. A suggestion keeps the user in control and avoids unintended data structures.
---
## Task Assignment Level
| Task Type | Should Live At | Rationale |
|---|---|---|
| Claims Review | Client (or Group if grouped) | One per renewal cycle, not per policy |
| Loss Run | Policy | Specific to a single policy's claim history |
| Renewal Prep | Group (or Client if ungrouped) | Group anchors the renewal date |
| Ad-hoc | User's choice | Manually assigned at creation |
The schema already supports all three levels via `clientId`, `policyId`, and `policyGroupId`. The missing piece is the template knowing which level to generate at.
---
## Data Already Exists: Scenarios
### Client — Single Policy
Works correctly today. No changes needed.
### Client — Multiple Policies
**Currently broken without `taskLevel`.** Each ungrouped policy spawns a full task set, including redundant client-level tasks (e.g. multiple claims reviews for the same client). Generation logic needs to respect task level before this scenario works correctly.
### Renewal Group — Automatic
Not yet implemented. Requires the group suggestion flow described above. Once a group is created:
- Tasks should regenerate anchored to the group's `renewalDate`
- Duplicate policy-level tasks that are now covered by the group should be cleaned up
### Group Suggested from Existing Data
Should exist as a UI affordance when:
- A new policy is added with a renewal date close to an existing policy
- Multiple ungrouped policies are discovered with similar dates during review
---
## Smart Task Generation vs. Per-Policy Generation
### The Fix (Two Parts)
**1. Add `taskLevel` to `TaskTemplate`** (`CLIENT | GROUP | POLICY`)
**2. Update generation logic:**
- `CLIENT` tasks — create once per client; skip if one already exists for this renewal cycle
- `GROUP` tasks — create once per PolicyGroup
- `POLICY` tasks — create once per policy (loss run per policy is correct and intended)
This handles the single claims review cleanly: even if a client has 5 policies across 2 groups, they receive exactly one claims review because the template is marked `CLIENT`.
### Task Inheritance
Policy- and group-level tasks already carry `clientId`, so they naturally appear in client-level task views. The gap is the UI — the policy/group context isn't clearly surfaced on task cards within the client view.
**Recommendation:** Add a context badge to task cards:
- `Policy: GL-12345`
- `Group: 2025 Renewal`
This makes it clear what a task belongs to without requiring navigation away from the client view.
---
## Parent-Child Relationships
### Current State
Parent-child is organizational only (`parentClientId` on Client). Tasks never cascade to subsidiaries, which is correct. However, the UI currently ignores the hierarchy entirely.
### Recommended UI Behavior
**Client detail page — default view**
Show only the direct client's tasks. A parent client manager should not wade through subsidiary tasks by default. This keeps the view focused and fast.
**"Include subsidiaries" toggle**
Add an expandable section or filter toggle that pulls in subsidiary tasks. Power users managing a parent + multiple subsidiaries need this, but it should be opt-in.
**Parent client summary card**
Surface aggregate metrics on the parent client header:
> `4 subsidiaries | 12 tasks (3 overdue)`
Clicking opens a filtered rollup view. Gives visibility without cluttering the default view.
**Task creation at parent level**
When creating a task on a parent client, prompt:
> *"Is this task for [Parent Co.] specifically, or should it apply to all subsidiaries?"*
Cascading to subsidiaries is likely rare but should be a conscious choice when it happens.
---
## Open Questions
1. **What defines a "renewal cycle" for deduplication of CLIENT-level tasks?** Is it calendar year, policy year, or keyed to the group/policy renewal date?
2. **If a client has two groups with different renewal dates, do they get two claims reviews?** (Probably yes — one per renewal event — but needs confirmation.)
3. **For the group suggestion flow: what is the right date proximity threshold?** ±30 days? Should it also consider policy type/line of business?
4. **Should parent-level tasks (created on the parent entity) be visible on subsidiary pages?** Or does information only flow upward (subsidiaries visible at parent)?
5. **When a PolicyGroup is created from previously ungrouped policies, what happens to existing tasks?** Archive them? Regenerate? Show a conflict resolution UI?
---
## Implementation Priority
| Priority | Item | Schema Change? |
|---|---|---|
| 1 | Add `taskLevel` enum to `TaskTemplate` | Yes — small |
| 2 | Update generation logic to respect task level | No |
| 3 | Single claims review deduplication | No |
| 4 | Per-policy loss run generation | No |
| 5 | PolicyGroup suggestion when adding policies | No |
| 6 | Task card context badges (policy/group label) | No |
| 7 | Parent-child UI rollup with toggle | No |
| 8 | Parent client aggregate metrics | No |
The schema change in item 1 is minimal — one new enum and field on `TaskTemplate`. Everything downstream is logic and UI work.