-
Notifications
You must be signed in to change notification settings - Fork 3
ADR 016 Household Items Architecture
Accepted
EPIC-04 introduces household items and furniture management as a distinct entity from work items. Requirements specify: item tracking with categories, purchase status workflow, vendor linkage, delivery date management, budget integration, work item linking for installation coordination, subsidy program support, tag organization, notes, and document links.
The key architectural question is: how should household items relate to the existing schema? Household items share many patterns with work items (tags, budgets, notes, vendor references, subsidy links) but are fundamentally different entities with different properties (purchase status vs. work status, delivery dates vs. scheduling dates, no dependencies/subtasks).
Option A: Single-table inheritance (STI) on work_items
Add a type column to work_items to distinguish construction tasks from household items. Household-specific columns (category, purchase status, delivery dates) would be nullable columns on the same table.
Pros: Simpler schema, unified queries for budget overview. Cons: Many nullable columns, confusing semantics (what does "status = in_progress" mean for a kitchen table?), existing code assumes work_items are all construction tasks, scheduling engine would need to filter them out.
Option B: Separate entity with parallel structure (chosen)
Create a dedicated household_items table with its own supporting tables (household_item_tags, household_item_notes, household_item_budgets, household_item_work_items, household_item_subsidies) that mirror the work item structure.
Pros: Clean separation of concerns, no impact on existing work item code, each entity has only relevant columns, no confusion in the scheduling engine. Cons: More tables, some structural duplication between workitem_ and householditem_ tables.
Option C: EAV (Entity-Attribute-Value) or JSON columns
Store household-item-specific properties in a JSON column or EAV table.
Pros: Maximally flexible. Cons: Loses type safety, no CHECK constraints, poor query performance, not idiomatic SQLite.
Option B: Separate entity with parallel structure.
Household items get their own table (household_items) with dedicated supporting tables. The following patterns are reused from the work items domain:
-
Shared
tagstable: Tags are a global resource. Bothwork_item_tagsandhousehold_item_tagsreference the sametagstable. -
Shared
vendorstable: Vendors serve as both contractors (work items) and suppliers (household items). -
Shared
budget_categoriesandbudget_sourcestables: Budget integration uses the same categories and financing sources. -
Shared
subsidy_programstable: Subsidy programs can apply to both work items and household items. -
Existing
document_linkstable: The polymorphic document links table already includeshousehold_itemas a validentity_type.
Household item categories are stored as a CHECK-constrained TEXT column (furniture, appliances, fixtures, decor, electronics, outdoor, storage, other) rather than a separate lookup table. Rationale:
- The category set is small (8 values) and relatively stable
- Categories are display labels, not entities with their own properties
- A separate table adds join complexity without benefit at this scale
- New categories can be added via a migration if needed
household_item_budgets mirrors work_item_budgets exactly (same columns, same FK pattern). This means:
- The budget overview endpoint (
GET /api/budget/overview) can aggregate across both tables - Budget sources track allocated amounts from both work item and household item budget lines
- Budget categories are shared across both entity types
Household item budget lines do not link to invoices (invoices are tracked through vendors, not through household items). The actualCost, actualCostPaid, and invoiceCount computed fields are always zero in the API response.
The household_item_work_items junction table is a simple M:N relationship (no scheduling dependency types like FS/SS/FF/SF). The link means "this household item is needed for this work item" (e.g., kitchen cabinets must be delivered before "Install Kitchen Cabinets" can start). The timeline visualization layer (EPIC-06) can use this information to show coordination needs, but the scheduling engine does not consume these links.
The room column is free-text rather than an enum or lookup table, because rooms vary greatly between homes and are not a finite, predictable set. Users may enter values like "Kitchen", "Master Bedroom", "Garage", "Guest Bathroom 2", etc.
- Work item code is unaffected; no risk of regression
- Scheduling engine is unaffected; no filtering needed
- Each entity has only its relevant columns; no nullable column confusion
- Budget overview can aggregate both entity types via UNION queries
- Document links already support household items (no schema change needed)
- 6 new tables add to the schema surface area
- Service layer code for budget lines, notes, tags, and subsidies is structurally similar between work items and household items (some code duplication, though service internals differ)
- Budget overview endpoint must be updated to include household item budget lines in its aggregation
- Delete of a household item requires application-level cleanup of
document_links(no FK constraint on polymorphic table)