# Rempla — Domain Model > Living document. Updated as the domain evolves. --- ## Entities ### Account Any registered user on the platform. A single person, one account. - **DisplayName**, **Email**, **ExternalId** (Descope OIDC subject identifier) - **Status** (Active, Paused, Closed, Deceased) - Every Account links to a **Person** — the Person is the universal node; the Account is the login/auth layer - Has one or more **AccountUserTypes** — tracks how the user arrived and what experiences they've unlocked ### UserType The pool of user experiences available on the platform. Drives UX, onboarding, and navigation — not access control. - **Benefactor** — building their own legacy (planning gifts, managing tree) - **GiftRecipient** — receiving gifts from someone else's plan - **PlanProtector** — trusted person who triggers plan execution after a benefactor's passing - **Beneficiary** — named in someone's digital legacy or estate plan ### AccountUserType Join table tracking which user types an account holds and when each was acquired. - **AccountId** (FK → Account) - **UserTypeId** (FK → UserType) - **AcquiredAt** (timestamp — when this user type was added) - The earliest AcquiredAt record is the account's **origin** — what brought them to the platform - An account accumulates user types over time as they engage with different parts of the platform ### AdminRole Access control for the admin site (Rempla.Admin). Separate from UserType — these are operational roles, not user experiences. - **Support** — read access, exception handling - **Ops** — support + manual interventions - **Admin** — full access ### Person A person in the system, whether or not they have an account. The universal node for the relationship graph. - **FirstName**, **LastName**, **DateOfBirth** (optional), **Notes** (optional) - **CreatedByAccountId** — the benefactor account that added this person - Every Account links to a Person (the person node representing them) - A benefactor's Person node is the root of their relationship tree - Other Persons may have no Account (added by the benefactor, not yet invited/signed up) - Can have one or more **Addresses** ### Relationship A directional, structural connection between two Persons. Defines how they're related and drives occasion suggestions. Purely structural — says nothing about plan roles. - Links a **Person** (source) to a **related Person** - Has a **RelationshipTypeId** (optional) — if null, uses **CustomRelationshipType** (free-text label entered by user) - RelationshipType seeds relevant occasions (child → birthday, graduation; spouse → anniversary, Valentine's Day) ### RemembrancePlanRole A functional role one Person plays in another Person's remembrance plan. Independent of Relationship — a separate edge between two Persons. - **PersonId** (FK → Person) — the plan owner (benefactor) - **RelatedPersonId** (FK → Person) — the person playing the role - **RemembrancePlanRoleTypeId** (FK → RemembrancePlanRoleType) - A person can hold multiple RemembrancePlanRoles for the same plan owner (e.g., GiftRecipient + PlanProtector) - A person can hold RemembrancePlanRoles across multiple plan owners ### RemembrancePlanRoleType Defines the functional roles a person can play in someone's remembrance plan. Seeded values. - **GiftRecipient** — receiving gifts from this plan - **PlanProtector** — triggers plan execution after the benefactor's passing - **DigitalLegacyBeneficiary** — named to receive digital account access ### EstateDesignation A legal/fiduciary designation one Person holds in another Person's estate plan. Independent of both Relationship and RemembrancePlanRole — a third edge between two Persons. - **PersonId** (FK → Person) — the estate plan owner - **RelatedPersonId** (FK → Person) — the designated person - **EstateDesignationTypeId** (FK → EstateDesignationType) - A person can hold multiple EstateDesignations for the same plan owner (e.g., Executor + Trust Beneficiary) - A person can hold EstateDesignations across multiple plan owners ### EstateDesignationType Defines the legal/fiduciary designations a person can hold in someone's estate plan. Seeded values. - **Executor** — personal representative; manages estate administration after passing - **Trustee** — manages trust assets on behalf of beneficiaries - **TrustBeneficiary** — named beneficiary of a trust (may include conditions — age, milestone) - **BequestRecipient** — receives a specific bequest (asset, share, item) - **Fiduciary** — general fiduciary responsibility (power of attorney, healthcare proxy, etc.) ### RelationshipType Defines the nature of a connection and its generational level. Seeded with standard types; users can bypass by entering a custom relationship type on the Relationship instead. - **Label** (Wife, Husband, Son, Daughter, Brother, Sister, Grandson, Granddaughter, Son-in-Law, Daughter-in-Law, Cousin, Nephew, Niece, Father, Mother, Grandfather, Grandmother, Friend, Colleague, Godchild) - **Level** (integer) — generational offset relative to source (+1 = child, +2 = grandchild, -1 = parent, -2 = grandparent, 0 = spouse/sibling/friend) - **IsFamily** (boolean) — determines whether the person appears in the tree view or the separate non-family area of the UI - **SortIndex** (integer) — sub-level sort order within the same Level for display consistency - **RelationshipTypeGroupId** (FK → RelationshipTypeGroup) — groups types for UI display (e.g., dropdown grouping in Add Member modal) ### RelationshipTypeGroup Groups relationship types for UI display purposes (e.g., grouped dropdown in the Add Member modal). - **Name** — group label - **SortIndex** — display order - Seeded values: **Immediate Family** (0), **Extended Family** (1), **Other** (2) ### DateType Defines occasion types for important dates associated with relationships. Used to suggest relevant date chips when adding a member. - **Name** — occasion label - **IsSystem** (boolean) — system-defined types cannot be removed by users - **SortIndex** — display order - Seeded values: **Birthday**, **Anniversary**, **Wedding**, **Baptism**, **Graduation**, **Retirement**, **Ordination** ### RelationshipTypeDateType Junction table linking which date types are relevant for each relationship type. Drives the date chip suggestions in the Add Member modal based on the selected relationship. - **RelationshipTypeId** (FK → RelationshipType) - **DateTypeId** (FK → DateType) ### PersonDate An important date associated with a Person. Created when adding/editing a member — populated from date type chips or custom entries. - **PersonId** (FK → Person) - **DateTypeId** (FK → DateType) — null for custom dates - **Date** (DateOnly) ### EmailAddress An email address associated with a Person. Used for gift notifications and communications. - **PersonId** (FK → Person) - **Email** — the email address - **IsDefault** (boolean) — one default per person ### PhoneNumber A phone number associated with a Person. - **PersonId** (FK → Person) - **Number** — the phone number - **IsDefault** (boolean) — one default per person ### Document An estate document uploaded by the user. Stored as file metadata with a reference to blob/file storage. - **PersonId** (FK → Person) — the estate plan owner - **DocumentTypeId** (FK → DocumentType) - **FileName** — original file name - **ContentType** — MIME type - **FileSize** — size in bytes - **StoragePath** — path or URL to the stored file - **Notes** (optional) — user-provided description ### DocumentType Defines the categories of estate documents. Seeded values. - **Last Will & Testament** — the primary will document - **Revocable Living Trust** — trust instrument - **Power of Attorney** — legal authority delegation - **Healthcare Directive** — living will / advance directive - **Beneficiary Designation** — beneficiary forms for accounts, policies - **Insurance Policy** — life insurance or other relevant policies - **Other** — catch-all for unlisted document types ### Product A specific item available for selection — sourced from a vendor catalog or custom. - Flowers (roses, sunflowers, tulips, etc.) - Handwritten letters - Video messages - Photo cards - Keepsake items ### Package A pre-configured template in the catalog used to quickly populate an Order. A sales and UX tool — not an ordering entity. - Defines a set of **default products**, **occasion patterns**, and **cron schedules** - Has a **number of deliveries** and a **price** - When selected, pre-fills an Order with suggested OrderItems — user can then customize - The Order may reference which Package seeded it, but is fully independent once created - Examples: "Eternal Love Package" (10 annual rose deliveries, $499.99), "Comfort & Grace" (12 monthly bouquets, $599.99) ### Order A purchase made by a benefactor. The commercial transaction that captures what was bought and for whom. - Belongs to a **benefactor account** - Contains one or more **OrderItems** - May reference a **Package** (if seeded from one — for tracking only) - Linked to a **Fund** for payment - Has an order status ### OrderItem A line item within an Order. Each defines a specific product delivery to a specific beneficiary on a recurring schedule. - Links to a **product** - Links to a **beneficiary account** (recipient) - Links to a **message** (optional) - Has an **occasion** - Has a **cron expression** defining the delivery schedule (e.g. `0 0 14 3 *` for March 14th annually) - Each cron trigger produces a **Delivery** when the order is activated ### Message Personal content composed by a benefactor, attached to an order item. - Text content (letter body) - Media attachments (photos, videos) - Can be reused across multiple order items or unique per delivery ### Occasion The event type that triggers a delivery. Seeded by relationship type but can also be custom. - **Standard:** Birthday, Anniversary, Wedding Anniversary, Valentine's Day, Mother's Day, Father's Day, Christmas, Graduation, Memorial - **Custom:** User-defined with a label and date ### Delivery The actual fulfillment event when an order item's cron triggers. Created by the system, not the user. - Links back to the **OrderItem** it came from - Tracks **vendor order** details - Has a **delivery address** (snapshot at time of creation) - Status lifecycle (see State Machines below) ### Address A structured address associated with a Person. Benefactors can set addresses on behalf of people in their tree; people with linked accounts can maintain their own. - **PersonId** (FK → Person) - **Line1** — street address - **Line2** (optional) — apt, suite, unit - **City**, **State**, **ZipCode** - **IsDefault** (boolean) — one default per person - A person can have multiple addresses - Subject to **contact maintenance** (annual refresh requests) ### Fund Pre-paid balance backing an account's orders. - Tracks **deposits** and **spend** - Has a **fallback threshold** — if costs spike beyond threshold, pause deliveries and payout remaining balance - Supports the "pre-funded guarantee" promise ### Vendor An external fulfillment partner who provides products. - Florists, gift providers, letter/print services, video hosting - Accessed via **provider adapters** behind stable internal interfaces - Treated as unreliable — all interactions are async, idempotent, retryable ### ActivityLog Audit trail of significant actions on the platform. - Who did what, when, to what entity - Feeds the dashboard "Recent Activity" view - Supports compliance and ops visibility ### Notification System communications sent to accounts. - Delivery confirmations - Contact refresh requests (annual "update your address" outreach) - Reminders (upcoming deliveries, plan protector action needed) - Channel: email, SMS, in-app --- ## Relationships ``` Account ──> Person (every account links to a person) Account ──< AccountUserType ──> UserType (timestamped; accumulates over time) Account ──< AdminRole (admin site only — optional) Account ──< Fund (a benefactor has a fund) Account ──< Order (as benefactor — places orders) Account ──< Message (a benefactor creates messages) Account ──< ActivityLog (actions taken by or on an account) Account ──< Notification (notifications sent to an account) Person ──< Address (a person has addresses) Person ──< Document ──> DocumentType (estate documents uploaded by person) Person ──< EmailAddress (a person has email addresses) Person ──< PersonDate ──> DateType (important dates for a person) Person ──< PhoneNumber (a person has phone numbers) Person ──< Relationship >── Person (directional: source → related; structural) Person ──< RemembrancePlanRole >── Person (directional: plan owner → role holder; functional) Person ──< EstateDesignation >── Person (directional: estate owner → designated person; legal/fiduciary) Relationship ──> RelationshipType (optional — type determines level and family/non-family; null if custom) RemembrancePlanRole ──> RemembrancePlanRoleType (GiftRecipient, PlanProtector, DigitalLegacyBeneficiary) EstateDesignation ──> EstateDesignationType (Executor, Trustee, TrustBeneficiary, BequestRecipient, Fiduciary) RelationshipType ──> RelationshipTypeGroup (groups types for UI display: Immediate Family, Extended Family, Other) RelationshipType ──< RelationshipTypeDateType ──> DateType (which date types are relevant per relationship type) RelationshipType ──> Occasion (relationship type seeds relevant occasions) Package ──< Product (a package template includes default products) Package ..> Order (a package can seed an order — soft reference) Order ──< OrderItem (an order contains line items) Order ──> Account (benefactor) Order ──> Fund Order ──> Package (optional — seeded from) OrderItem ──> Product OrderItem ──> Account (beneficiary) OrderItem ──> Message (optional) OrderItem ──> Occasion OrderItem has: cron expression OrderItem ──< Delivery (each cron trigger produces a delivery) Delivery ──> OrderItem Delivery ──> Address (snapshot) Delivery ──> Vendor Delivery ──> Product Product ──> Vendor (optional) ``` --- ## State Machines ### Order Status ``` Draft → Confirmed → Activated → Completed → Cancelled ``` - **Draft** — being configured, not yet purchased/finalized - **Confirmed** — purchased and funded, waiting for activation - **Activated** — plan protector has confirmed passing; deliveries begin executing on cron schedules - **Completed** — all order items have fulfilled all deliveries - **Cancelled** — permanently stopped ### Delivery Status ``` Pending → Processing → Shipped → Delivered → Confirmed → Failed → Retry → Processing → Escalated (manual review) ``` - **Pending** — created from order item cron trigger, awaiting processing window - **Processing** — vendor order placed - **Shipped** — vendor confirms shipment - **Delivered** — vendor confirms delivery - **Confirmed** — delivery verified (tracking, photo, etc.) - **Failed** — vendor or delivery failure - **Retry** — automatic retry queued - **Escalated** — requires manual ops intervention ### Account Status ``` Active → Paused → Active (resume) → Closed → Deceased (plan protector-confirmed) ``` --- ## Business Rules 1. **Activation requires plan protector confirmation.** Deliveries do not begin until a plan protector confirms the benefactor's passing through the verification workflow. 2. **Pre-funded guarantee.** All orders must be fully funded before confirmation. The fund balance must cover the full order at time of purchase. 3. **Fallback provision.** If fulfillment costs exceed the fallback threshold (e.g. inflation spike), pause deliveries and distribute remaining balance to beneficiaries. 4. **Contact maintenance.** Beneficiary addresses are refreshed annually via automated outreach. Unresponsive addresses are flagged for ops review. 5. **Beneficiary opt-out.** A beneficiary can opt out of future deliveries at any time. Remaining funds for their order items follow the fallback provision. 6. **One account, many user types.** A person accumulates user types over time — they may start as a GiftRecipient and later become a Benefactor building their own legacy. The platform guides this transition without forcing it. 7. **RelationshipType drives occasions.** When a relationship is created, the system suggests relevant occasions based on RelationshipType. Users can accept, modify, or add custom occasions. 8. **Package as template.** Selecting a package pre-fills an Order with default OrderItems. Once created, the Order and its items are independent and fully customizable. 9. **Vendor abstraction.** Core domain logic never depends on vendor-specific details. Products reference vendors but ordering and delivery orchestration is vendor-agnostic. 10. **All external interactions are async.** Vendor orders, payment processing, and notifications are handled by the background worker — never synchronous in user flows. 11. **Cron-driven delivery.** Each OrderItem defines its delivery schedule via cron expression. The system evaluates cron schedules against activated orders to generate Delivery records. 12. **Plan protector or linked account required.** Before any gift purchases, the benefactor must have designated at least one PlanProtector (via RemembrancePlanRole) OR have at least one Person with a linked Account in their tree. --- ## Bounded Contexts | Context | Owns | Description | |---------|------|-------------| | **Identity** | Account, UserType, AccountUserType, AdminRole, Person, Address, EmailAddress, PhoneNumber, PersonDate, DateType, Relationship, RelationshipType, RelationshipTypeGroup, RelationshipTypeDateType, RemembrancePlanRole, RemembrancePlanRoleType, EstateDesignation, EstateDesignationType, Document, DocumentType | Who people are, how they're connected, what roles they play, and their estate documents | | **Catalog** | Product, Package, Vendor | What's available to buy — packages are templates here | | **Ordering** | Order, OrderItem, Occasion, Message | What was purchased, for whom, on what schedule | | **Fulfillment** | Delivery | Executing and tracking deliveries | | **Funding** | Fund | Money in, money out, fallback provisions | | **Platform** | ActivityLog, Notification | Cross-cutting: audit, comms, ops | --- ## Planned Changes (Future Increments) - OrderItem currently references "beneficiary Account" — will reference **Person** in a future increment - Occasion will become a first-class entity owned by a Relationship (beneficiary), not just a type enum - GiftPlan entity will be introduced as the planning-phase counterpart to OrderItem - EstateDesignation may need additional fields as estate features mature (e.g., conditions on TrustBeneficiary, specific asset descriptions on BequestRecipient)