7 KiB
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:
CLIENTtasks — create once per client; skip if one already exists for this renewal cycleGROUPtasks — create once per PolicyGroupPOLICYtasks — 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-12345Group: 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
- 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?
- 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.)
- For the group suggestion flow: what is the right date proximity threshold? ±30 days? Should it also consider policy type/line of business?
- Should parent-level tasks (created on the parent entity) be visible on subsidiary pages? Or does information only flow upward (subsidiaries visible at parent)?
- 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.