# Planning Tree — Relationship Model ## Overview The Planning Tree is the central visualization in Rempla. It shows the account holder's family and extended network, organized by generational level, with visual indicators for remembrance plans, estate designations, and special roles. Every person in the tree holds a **relationship** — either to the account holder directly, or to another member in the tree. The system resolves how each person relates to "you" and draws the tree accordingly. --- ## How Relationships Work ### Person-to-Person Relationships are defined between two people, not just from the account holder to everyone. This mirrors how families actually work: - **Robert** has **Linda** as his **Wife** - **Robert** has **David** as his **Son** - **David** has **Olivia** as his **Daughter** Olivia's relationship to Robert (Granddaughter) is **computed** by walking the chain: Olivia is David's Daughter, David is Robert's Son — therefore Olivia is Robert's Granddaughter. ### Direct vs. Computed | Type | How it works | Example | |------|-------------|---------| | **Direct** | Account holder explicitly defines the relationship | Robert → Karen = Daughter | | **Computed** | System walks the parent-child chain to determine the relationship | Robert → Olivia = Granddaughter (via David) | **Direct always takes precedence.** If Robert explicitly defines Olivia as his Granddaughter AND the chain also computes Granddaughter, the explicit one is used. This allows users to override computed labels when needed. ### Flexibility Users can build their tree however they prefer: - **Top-down**: Define each person's relationship to you, then optionally add parent-child links between members - **Bottom-up**: Define parent-child relationships between members, and the system computes everyone's relationship to you - **Mixed**: Some relationships defined directly, others computed — both work together A grandchild can be added without defining their parents. A son-in-law can be added with a custom relationship label. The system is flexible by design. --- ## Relationship Types All relationship types belong to a **RelationshipTypeGroup** that controls how they are grouped in the UI (e.g., the Add Member dropdown). Each type has a **SortIndex** for ordering within its level. ### Immediate Family (Group: Immediate Family, SortIndex 0) | Type | Level | SortIndex | Notes | |------|-------|-----------|-------| | Wife / Husband | 0 (peer) | 0 | Shown with diamond union indicator. Only one spouse allowed per person. | | Son / Daughter | 1 | 0 | Direct children | | Grandson / Granddaughter | 2 | 0 | Children of children | | Brother / Sister | 0 (peer) | 0 | Siblings | | Father / Mother | -1 | 0 | Parents (excluded from Add Member — ancestors not shown) | | Grandfather / Grandmother | -2 | 0 | Grandparents (excluded from Add Member — ancestors not shown) | ### Extended Family (Group: Extended Family, SortIndex 1) | Type | Level | SortIndex | Notes | |------|-------|-----------|-------| | Son-in-Law / Daughter-in-Law | 1 | 1 | Spouse of a child. Connected to the child, not the owner. | | Cousin | 0 (peer) | 1 | Connected to a sibling | | Nephew / Niece | 1 | 2 | Connected to a sibling | ### Other (Group: Other, SortIndex 2) | Type | Level | SortIndex | Notes | |------|-------|-----------|-------| | Friend | 0 | 0 | Non-family; appears in Extended Planning Network | | Colleague | 0 | 1 | Non-family; appears in Extended Planning Network | | Godchild | 1 | 10 | Non-family (IsFamily=false); appears in Extended Planning Network | | Custom / Other | varies | — | User-defined label; IsFamily=false; goes to Extended Planning Network | --- ## Add Member Modal ### Relationship Selection - The relationship dropdown is populated from the database, grouped by RelationshipTypeGroup - **Ancestors excluded**: Relationship types with Level < 0 (Father, Mother, Grandfather, Grandmother) are not shown — the tree is built downward from the owner - **One spouse rule**: Wife/Husband is hidden from the dropdown if the target person already has a spouse - **"Other..." option**: Appears at the bottom; reveals a free-text input for a custom relationship label. Custom relationships are saved with `RelationshipTypeId = null` and `IsFamily = false` (Extended Planning Network) ### Connected To (Smart Filtering) Extended family members are connected to **immediate family members**, not the account owner directly. The tree service computes their label relative to the owner by walking the chain. | Relationship Selected | "Connected to" Shows | |----------------------|---------------------| | Grandson / Granddaughter | Children only (Son/Daughter) | | Son-in-Law / Daughter-in-Law | Children only (Son/Daughter), skipping those who already have a spouse | | Nephew / Niece | Siblings only (Brother/Sister) | | Cousin | Siblings only (Brother/Sister) | | Son / Daughter | "Parent of" — shows unconnected grandchildren | | Brother / Sister | "Parent of" — shows unconnected nephews/nieces | ### Important Dates - Date chips are populated from the **RelationshipTypeDateType** junction table based on the selected relationship type - Birthday is a chip (suggested, not auto-added) — the user explicitly selects it - A custom date row is always present for user-defined occasions ### Modal Behavior - **Close (X button)**: Checks for dirty state before closing - **Cancel button**: Closes immediately without dirty-state warning - **Scroll reset**: A MutationObserver in site.js resets `.modal-body` scrollTop when the `.open` class is added (cross-cutting behavior for all modals) --- ## Tree Display ### Layout ``` [You ◆ Spouse] ┌────────┴────────┐ | | [Son] [Daughter ◆ Son-in-law] ┌──┴──┐ | | | [Grandson] [Grandson] [Granddaughter] ——————— EXTENDED PLANNING NETWORK ——————— [Friend] [Colleague] ``` **Key principles:** - Account holder ("You") appears at the top in ascending view - Spouses are connected with a **diamond (◆)** union indicator - Parents are **centered above their children** - Connector lines are **orthogonal** (vertical and horizontal, never diagonal) - Single children connect with a **straight vertical line** from parent - Extended network members appear below a labeled divider - The tree can be **sorted** ascending (you at top) or descending (you at bottom) ### Spouse Handling When a member has a spouse: - The spouse appears next to them with a diamond between - Connector lines to children originate from the **diamond** (the union point), not from either parent individually - The spouse who married into the family is visually attached — they don't have their own position in the tree hierarchy --- ## Data Model ### Entities Involved | Entity | Purpose | |--------|---------| | **Person** | Any individual in the system | | **Relationship** | Directional link between two Persons with a type | | **RelationshipType** | Defines the nature of the connection (Wife, Son, Friend, etc.) with Level, SortIndex, and IsFamily | | **RelationshipTypeGroup** | Groups relationship types for UI display (Immediate Family, Extended Family, Other) | | **DateType** | Occasion types for important dates (Birthday, Anniversary, etc.) | | **RelationshipTypeDateType** | Junction: which date types are relevant for each relationship type | | **RemembrancePlanRole** | Functional role in someone's remembrance plan (GiftRecipient, PlanProtector, DigitalLegacyBeneficiary) | | **EstateDesignation** | Legal/fiduciary designation in someone's estate plan (Executor, Trustee, TrustBeneficiary, BequestRecipient, Fiduciary) | ### How the Tree is Built 1. Load all relationships from the account holder to their members 2. Load all inter-member relationships (parent-child and spouse links) 3. Discover additional members reachable through parent-child chains 4. Compute relationship labels for chain-discovered members (direct labels take precedence) 5. Resolve parent-child connections for tree line drawing 6. Resolve spouse connections for diamond indicators 7. Load plan roles and estate designations for visual styling 8. Calculate tree positions (subtree widths bottom-up, positions top-down) 9. Render with connector lines from parent/diamond to children --- ## Architecture Decision See **ADR-006: Relationship Chain Computation** for the full technical decision record covering direct vs. computed relationships, discovery logic, and label computation rules.