diff --git a/docs/multi-household-architecture-plan.md b/docs/multi-household-architecture-plan.md new file mode 100644 index 0000000..0a0f887 --- /dev/null +++ b/docs/multi-household-architecture-plan.md @@ -0,0 +1,865 @@ +# Multi-Household & Multi-Store Architecture Plan + +## Executive Summary + +This document outlines the architecture and implementation strategy for extending the application to support: +1. **Multiple Households** - Users can belong to multiple households (families, roommates, etc.) +2. **Multiple Stores** - Households can manage lists for different store types (Costco, Target, Walmart, etc.) + +## Current Architecture Analysis + +### Existing Schema +```sql +users (id, username, password, name, role, display_name) +grocery_list (id, item_name, quantity, bought, item_image, image_mime_type, added_by, modified_on) +grocery_history (id, list_item_id, quantity, added_by, added_on) +item_classification (id, item_type, item_group, zone, confidence, source) +``` + +### Current Limitations +- **Single global list** - All users share one grocery list +- **No household concept** - Cannot separate different families' items +- **Store-specific zones** - Classification system assumes Costco layout +- **Single-level roles** - User has same role everywhere (cannot be admin in one household, viewer in another) + +--- + +## Design Considerations & Trade-offs + +### Key Questions to Resolve + +#### 1. Item Management Strategy + +**Option A: Shared Item Master (Recommended)** +- ✅ **Pro**: Single source of truth for item definitions (name, default image, common classification) +- ✅ **Pro**: Consistent item naming across households +- ✅ **Pro**: Can build item recommendation system across all households +- ✅ **Pro**: Easier to implement smart features (price tracking, common items) +- ❌ **Con**: Requires careful privacy controls (who can see which items) +- ❌ **Con**: Different households may classify items differently + +**Option B: Per-Household Items** +- ✅ **Pro**: Complete household isolation +- ✅ **Pro**: Each household fully controls item definitions +- ✅ **Pro**: No privacy concerns about item names +- ❌ **Con**: Duplicate data across households +- ❌ **Con**: Cannot leverage cross-household intelligence +- ❌ **Con**: More complex to implement suggestions + +**Option C: Hybrid Approach (RECOMMENDED)** +- ✅ **Pro**: Best of both worlds +- ✅ **Pro**: Shared item catalog with household-specific classifications +- ✅ **Pro**: Privacy-preserving (only households share item usage, not personal data) +- **How it works**: + - Global `items` table (id, name, default_image, created_at) + - Household-specific `household_list` table references item + household + - Each household can override classifications per store + +--- + +## Proposed Schema Design + +### New Tables + +```sql +-- Households (e.g., "Smith Family", "Apartment 5B") +CREATE TABLE households ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL, + created_at TIMESTAMP DEFAULT NOW(), + created_by INTEGER REFERENCES users(id), + invite_code VARCHAR(20) UNIQUE NOT NULL, -- Random code for inviting users + code_expires_at TIMESTAMP -- Optional expiration +); + +-- Store Types (e.g., "Costco", "Target", "Walmart") +CREATE TABLE stores ( + id SERIAL PRIMARY KEY, + name VARCHAR(50) NOT NULL UNIQUE, + default_zones JSONB, -- Store-specific zone layout + created_at TIMESTAMP DEFAULT NOW() +); + +-- User-Household Membership with per-household roles +CREATE TABLE household_members ( + id SERIAL PRIMARY KEY, + household_id INTEGER REFERENCES households(id) ON DELETE CASCADE, + user_id INTEGER REFERENCES users(id) ON DELETE CASCADE, + role VARCHAR(20) NOT NULL CHECK (role IN ('admin', 'user')), + joined_at TIMESTAMP DEFAULT NOW(), + UNIQUE(household_id, user_id) +); + +-- Household-Store Relationship (which stores does this household shop at?) +CREATE TABLE household_stores ( + id SERIAL PRIMARY KEY, + household_id INTEGER REFERENCES households(id) ON DELETE CASCADE, + store_id INTEGER REFERENCES stores(id) ON DELETE CASCADE, + is_default BOOLEAN DEFAULT FALSE, -- Default store for this household + UNIQUE(household_id, store_id) +); + +-- Master Item Catalog (shared across all households) +CREATE TABLE items ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL UNIQUE, + default_image BYTEA, + default_image_mime_type VARCHAR(50), + created_at TIMESTAMP DEFAULT NOW(), + usage_count INTEGER DEFAULT 0 -- For popularity tracking +); + +-- Household-specific grocery lists (per store) +CREATE TABLE household_lists ( + id SERIAL PRIMARY KEY, + household_id INTEGER REFERENCES households(id) ON DELETE CASCADE, + store_id INTEGER REFERENCES stores(id) ON DELETE CASCADE, + item_id INTEGER REFERENCES items(id) ON DELETE CASCADE, + quantity INTEGER NOT NULL DEFAULT 1, + bought BOOLEAN DEFAULT FALSE, + custom_image BYTEA, -- Household can override item image + custom_image_mime_type VARCHAR(50), + added_by INTEGER REFERENCES users(id), + modified_on TIMESTAMP DEFAULT NOW(), + UNIQUE(household_id, store_id, item_id) -- One item per household+store combo +); + +-- Household-specific item classifications (per store) +CREATE TABLE household_item_classifications ( + id SERIAL PRIMARY KEY, + household_id INTEGER REFERENCES households(id) ON DELETE CASCADE, + store_id INTEGER REFERENCES stores(id) ON DELETE CASCADE, + item_id INTEGER REFERENCES items(id) ON DELETE CASCADE, + item_type VARCHAR(50), + item_group VARCHAR(100), + zone VARCHAR(100), + confidence DECIMAL(3,2) DEFAULT 1.0, + source VARCHAR(20) DEFAULT 'user', + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW(), + UNIQUE(household_id, store_id, item_id) +); + +-- History tracking (who added what, when, to which household+store list) +CREATE TABLE household_list_history ( + id SERIAL PRIMARY KEY, + household_list_id INTEGER REFERENCES household_lists(id) ON DELETE CASCADE, + quantity INTEGER NOT NULL, + added_by INTEGER REFERENCES users(id), + added_on TIMESTAMP DEFAULT NOW() +); +``` + +### Indexes for Performance + +```sql +-- Household member lookups +CREATE INDEX idx_household_members_user ON household_members(user_id); +CREATE INDEX idx_household_members_household ON household_members(household_id); + +-- List queries (most common operations) +CREATE INDEX idx_household_lists_household_store ON household_lists(household_id, store_id); +CREATE INDEX idx_household_lists_bought ON household_lists(household_id, store_id, bought); + +-- Item search +CREATE INDEX idx_items_name ON items(name); +CREATE INDEX idx_items_usage_count ON items(usage_count DESC); + +-- Classification lookups +CREATE INDEX idx_household_classifications ON household_item_classifications(household_id, store_id); +``` + +--- + +## Role System Redesign + +### Dual-Role Hierarchy: System-Wide + Household-Scoped + +```typescript +// System-wide roles (app administration) +users { + id, username, password, name, display_name, + role: 'system_admin' | 'user' // Kept for app-wide controls +} + +// Household-scoped roles (per-household permissions) +household_members { + household_id, user_id, + role: 'admin' | 'user' +} +``` + +### System-Wide Role Definitions + +| Role | Permissions | +|------|-------------| +| **system_admin** | Create/delete stores globally, view all households (moderation), manage global item catalog, access system metrics, promote users to system_admin | +| **user** | Standard user - can create households, join households via invite, manage own profile | + +### Household-Scoped Role Definitions + +| Role | Permissions | +|------|-------------| +| **admin** | Full household control: delete household, invite/remove members, change member roles, manage stores, add/edit/delete items, mark bought, upload images, update classifications | +| **user** | Standard member: add/edit/delete items, mark bought, upload images, update classifications, view all lists | + +### Role Transition Plan + +**Migration Strategy:** +1. Create default household "Main Household" +2. Migrate all existing users → household_members (old admins become household admins, others become users) +3. Keep existing `users.role` column, update values: + - `admin` → `system_admin` (app-wide admin) + - `editor` → `user` (standard user) + - `viewer` → `user` (standard user) +4. Migrate grocery_list → household_lists (all to default household + default store) +5. Migrate item_classification → household_item_classifications + +--- +, systemRole } // System-wide role +req.household = { id, name, role } // Household-scoped role +req.store = { id, name } // Active store context +### Authentication Context + +**Before:** +```javascript +req.user = { id, username, role } +``` + +**After:** +```javascript +req.user = { id, username } +req.household = { id, name, role } // Set by household middleware +req.store = { id, name } // Set by store middleware +``` + +### Middleware Chain with systemRole) +router.use(auth); + +// 2. Household middleware (validates household access, sets req.household with householdRole) +router.use('/households/:householdId', householdAccess); + +// 3. Household role middleware (checks household-scoped permissions) +router.post('/add', requireHouseholdRole(['user', 'admin']), controller.addItem); + +// 4. Admin-only household operations +router.delete('/:id', requireHouseholdRole(['admin']), controller.deleteHousehold); + +// 5. System admin middleware (for app-wide operations) +router.post('/stores', requireSystemRole('system_admin'), controller.createStore + +// 3. Role middleware (checks household-specific role) +rouSystem Administration (system_admin only) +GET /api/admin/stores // Manage all stores +POST /api/admin/stores // Create new store type +PATCH /api/admin/stores/:id // Update store +DELETE /api/admin/stores/:id // Delete store (if unused) +GET /api/admin/households // View all households (moderation) +GET /api/admin/items // Manage global item catalog +GET /api/admin/metrics // System-wide analytics + +// Household Management (any user can create) +GET /api/households // Get all households user belongs to +POST /api/households // Create new household (any user) +GET /api/households/:id // Get household details +PATCH /api/households/:id // Update household (admin only) +DELETE /api/households/:id // Delete household (admin only) + +// Household Members +GET /api/households/:id/members // List members (all roles) +POST /api/households/:id/invite // Generate/refresh invite code (admin only) +POST /api/households/join/:inviteCode // Join household via invite code (joins as 'user') +PATCH /api/households/:id/members/:userId // Update member role (admin only) +DELETE /api/households/:id/members/:userId // Remove member (admin only, or self) + +// Store Management +GET /api/stores // Get all available store types +GET /api/households/:id/stores // Get stores for household +POST /api/households/:id/stores // Add store to household (admin only) +DELETE /api/households/:id/stores/:storeId // Remove store from household (admin only) +// Store Management +GET /api/stores // Get all available stores +POST /api/stores // Create custom store (system admin) +GET /api/households/:id/stores // Get stores for household +POST /api/households/:id/stores // Add store to household (admin+) +DELETE /api/households/:id/stores/:storeId // Remove store (admin+) + +// List Operations (now scoped to household + store) +GET /api/households/:hId/stores/:sId/list // Get list +POST /api/households/:hId/stores/:sId/list/add // Add item +PATCH /api/households/:hId/stores/:sId/list/:itemId // Update item +DELETE /api/households/:hId/stores/:sId/list/:itemId // Delete item +POST /api/households/:hId/stores/:sId/list/:itemId/buy // Mark bought + +// Item Suggestions (across user's households) +GET /api/items/suggestions?q=milk // Search master catalog + +// Classifications (per household + store) +GET /api/households/:hId/stores/:sId/classifications/:itemId +POST /api/households/:hId/stores/:sId/classifications/:itemId +``` + +--- + +## React Context Refactoring Pattern + +### Current Pattern (To Be Replaced) + +```jsx +// Bad: Context is exported, consumers use it directly +export const AuthContext = createContext(null); + +export function AuthProvider({ children }) { + const [user, setUser] = useState(null); + + return ( + + {children} + + ); +} + +// Consumer must import context and useContext +import { useContext } from 'react'; +import { AuthContext } from '../context/AuthContext'; + +function MyComponent() { + const { user, setUser } = useContext(AuthContext); + // ... +} +``` + +### New Pattern (Best Practice) + +```jsx +// Good: Context is internal, custom hook is exported +const AuthContext = createContext(null); // Not exported! + +export function AuthProvider({ children }) { + const [user, setUser] = useState(null); + const [token, setToken] = useState(null); + + const login = (userData, authToken) => { + setUser(userData); + setToken(authToken); + }; + + const logout = () => { + setUser(null); + setToken(null); + }; + + return ( + + {children} + + ); +} + +// Export custom hook instead +export function useAuth() { + const context = useContext(AuthContext); + if (!context) { + throw new Error('useAuth must be used within AuthProvider'); + } + return context; +} + +// Consumer usage - clean and simple +import { useAuth } from '../context/AuthContext'; + +function MyComponent() { + const { user, login, logout } = useAuth(); + // ... +} +``` + +### Benefits + +1. **Encapsulation** - Context implementation is hidden, only the hook is public API +2. **Type Safety** - Can add TypeScript types to the hook return value +3. **Validation** - Hook can check if used within provider (prevents null errors) +4. **Cleaner Imports** - One import instead of two (`useContext` + `Context`) +5. **Easier Refactoring** - Can change context internals without affecting consumers +6. **Standard Pattern** - Aligns with React best practices and popular libraries + +### Implementation Plan + +**Existing Contexts to Refactor:** +- `AuthContext` → `useAuth()` +- `SettingsContext` → `useSettings()` +- `ConfigContext` → `useConfig()` (if still used) + +**New Contexts to Create:** +- `HouseholdContext` → `useHousehold()` +- `StoreContext` → `useStore()` + +**Migration Steps:** +1. Keep old context export temporarily +2. Add custom hook export +3. Update all components to use hook +4. Remove old context export +5. Make context `const` internal to file + +--- + +## Frontend Architecture Changes + +### Context Structure + +```typescript +// AuthContext - User identity +{ + user: { id, username, display_name, systemRole }, + token: string, + login, logout, + isSystemAdmin: boolean // Computed from systemRole +} + +// HouseholdContext - Active household + household role +{ + activeHousehold: { id, name, role }, // role is 'admin' or 'user' + households: Household[], + switchHousehold: (id) => void, + createHousehold: (name) => void, + joinHousehold: (code) => void, + isAdmin: boolean // Computed helper: role === 'admin' +} + +// StoreContext - Active store +{ + activeStore: { id, name }, + householdStores: Store[], + allStores: Store[], // Available store types (for adding) + switchStore: (id) => void, + addStore: (storeId) => void // Admin+ onlyme, role }, + households: Household[], + switchHousehold: (id) => void, + createHousehold: (name) => void, + joinHousehold: (code) => void +} + +// StoreContext - Active store +{ +/admin → System admin panel (system_admin only) +/admin/stores → Manage store types +/admin/households → View all households +/admin/items → Global item catalog + activeStore: { id, name }, + householdStores: Store[], + switchStore: (id) => void +} (Owner) + + + + {user.systemRole === 'system_admin' && ( + + )} + +``` + +**Store Tabs** (Within Household) +```tsx + + Costco + Target + Walmart + {(isAdmin || isOwner) && + Add Store} → User settings (personal) +``` + +### UI Components + +**Household Switcher** (Navbar) +```tsx + + + + + + +``` + +**Store Tabs** (Within Household) +```tsx + + Costco + Target + Walmart + + Add Store + +``` + +--- + +## Migration Strategy + +### Phase 1: Database Schema (Breaking Change) + +**Step 1: Backup** +```bash +pg_dump grocery_list > backup_$(date +%Y%m%d).sql +``` + +**Step 2: Run Migrations** +```sql +-- 1. Create new tables +CREATE TABLE households (...); +CREATE TABLE household_members (...); +-- ... (all new tables) + +-- 2. Create default household +INSERT INTO households (name, created_by, invite_code) +VALUES ('Main Household', 1, 'DEFAULT123'); + +-- 3. Migrate users → household_members +INSERT INTO household_members (household_id, user_id, role) +SELECT 1, id, + CASE + WHEN role = 'admin' THEN 'admin' -- Old admins become household admins + ELSE 'user' -- Everyone else becomes standard user + END +FROM users; + +-- 4. Create default store +INSERT INTO stores (name, default_zones) +VALUES ('Costco', '{"zones": [...]}'); + +-- 5. Link household to store +INSERT INTO household_stores (household_id, store_id, is_default) +VALUES (1, 1, TRUE); + +-- 6. Migrate items +INSERT INTO items (name, default_image, default_image_mime_type) +SELECT DISTINCT item_name, item_image, image_mime_type +FROM grocery_list; + +-- 7. Migrate grocery_list → household_lists +INSERT INTO household_lists (household_id, store_id, item_id, quantity, bought, added_by, modified_on) +SELECT + 1, -- default household + 1, -- default store + i.id, + gl.quantity, + gl.bought, + gl.added_by, + gl.modified_on +FROM grocery_list gl +JOIN items i ON LOWER(i.name) = LOWER(gl.item_name); + +-- 8. Migrate classifications +INSERT INTO household_item_classifications + (household_id, store_id, item_id, item_type, item_group, zone, confidence, source) +SELECT + 1, 1, i.id, + ic.item_type, ic.item_group, ic.zone, ic.confidence, ic.source +FROM item_classification ic +JOIN grUpdate system roles (keep role column) +UPDATE users SET role = 'system_admin' WHERE role = 'admin'; +UPDATE users SET role = 'user' WHERE role IN ('editor', 'viewer'); + +-- 11. Drop old tables (after verification!) +-- DROP TABLE grocery_history; +-- DROP TABLE item_classification; +-- DROP TABLE grocery_listousehold_list_id, quantity, added_by, added_on) +SELECT hl.id, gh.quantity, gh.added_by, gh.added_on +FROM grocery_history gh +JOIN grocery_list gl ON gh.list_item_id = gl.id +JOIN items i ON LOWER(i.name) = LOWER(gl.item_name) +JOIN household_lists hl ON hl.item_id = i.id AND hl.household_id = 1 AND hl.store_id = 1; + +-- 10. Drop old tables (after verification!) +-- DROP TABLE grocery_history; +-- DROP TABLE item_classification; +-- DROP TABLE grocery_list; +-- ALTER TABLE users DROP COLUMN role; +``` + +### Phase 2: Backend API (Incremental) + +1. ✅ Create new models (households, stores, household_lists) +2. ✅ Create new middleware (householdAccess, storeAccess) +3. ✅ Create new controllers (households, stores) +4. ✅ Add new routes alongside old ones +5. ✅ Update list controllers to be household+store aware +6. ✅ Deprecate old routes (return 410 Gone) + +### Phase 3: Frontend UI (Incremental) + +1. ✅ **Refactor Context Pattern** (applies to all contexts) + - Move `createContext` inside component files (not exported) + - Export custom hooks instead: `useAuth()`, `useHousehold()`, `useStore()`, `useSettings()` + - Consumers use hooks directly instead of `useContext(ExportedContext)` +2. ✅ Create HouseholdContext with `useHousehold()` hook +3. ✅ Create StoreContext with `useStore()` hook +4. ✅ Refactor existing AuthContext to use custom `useAuth()` hook +5. ✅ Refactor existing SettingsContext to use custom `useSettings()` hook +6. ✅ Add household switcher to navbar +7. ✅ Create household management pages +8. ✅ Add store tabs to list view +9. ✅ Update all API calls to use household + store IDs +7. ✅ Add invite system UI +8. ✅ Update settings page to show household-specific settings + +--- + +## Advanced Features (Future) + +### 1. Item Sharing & Privacy + +**Levels:** +- **Private**: Only visible to your household +- **Public**: Available in global item catalog +- **Suggested**: Anonymously contribute to shared catalog + +### 2. Smart Features + +**Cross-Household Intelligence:** +- "10,000 households buy milk at Costco" → suggest classification +- "Items commonly bought together" +- Price tracking across stores +- Store-specific suggestions + +**Household Patterns:** +- "You usually buy milk every 5 days" +- "Bananas are typically added by [User]" +- Auto-add recurring items + +### 3. Multi-Store Optimization + +**Store Comparison:** +- Track which items each household buys at which store +- "This item is 20% cheaper at Target" +- Generate shopping lists across stores + +**Route Optimization:** +- Sort list by store zone +- "You can save 15 minutes by shopping in this order" + +### 4. Enhanced Collaboration + +**Shopping Mode:** +- Real-time collaboration (one person shops, another adds from home) +- Live updates via WebSockets +- "John is currently at Costco (aisle 12)" + +**Shopping Lists:** +- Pre-planned lists (weekly meal prep) +- Recurring lists (monthly bulk buy) +- Shared templates between households + +--- + +## Implementation Timeline + +### Sprint 1: Foundation (2-3 weeks) +- [ ] Design finalization & review +- [ ] Create migration scripts +- [ ] Implement new database tables +- [ ] Test migration on staging data +- [ ] Create new models (household, store, household_list) + +### Sprint 2: Backend API (2-3 weeks) +- [ ] Implement household management endpoints +- [ ] Implement store management endpoints +- [ ] Update list endpoints for household+store scope +- [ ] Create new middleware (householdAccess, storeAccess) +- [ ] Update authentication to remove global role + +### Sprint 3: Frontend Core (2-3 weeks) +- [ ] **Refactor Context Pattern** (foundational change): + - [ ] Refactor AuthContext to internal context + `useAuth()` hook + - [ ] Refactor SettingsContext to internal context + `useSettings()` hook + - [ ] Update all components using old context pattern +- [ ] Create HouseholdContext with `useHousehold()` hook +- [ ] Create StoreContext with `useStore()` hook +- [ ] Build household switcher UI +- [ ] Build store tabs UI +- [ ] Update GroceryList page for new API +- [ ] Create household management pages + +### Sprint 4: Member Management (1-2 weeks) +- [ ] Implement invite code system +- [ ] Build member management UI +- [ ] Implement role updates +- [ ] Add join household flow + +### Sprint 5: Polish & Testing (1-2 weeks) +- [ ] End-to-end testing +- [ ] Performance optimization +- [ ] Mobile responsiveness +- [ ] Documentation updates +- [ ] Migration dry-run on production backup + +### Sprint 6: Production Migration (1 week) +- [ ] Announce maintenance window +- [ ] Run migration on production +- [ ] Verify data integrity +- [ ] Deploy new frontend +- [ ] Monitor for issues + +**Total: 9-14 weeks** + +--- + +## Risk Assessment & Mitigation + +### High Risk Areas + +1. **Data Loss During Migration** + - **Mitigation**: Full backup, dry-run on production copy, rollback plan + +2. **Breaking Existing Users** + - **Mitigation**: Default household preserves current behavior, phased rollout + +3. **Performance Degradation** + - **Mitigation**: Proper indexing, query optimization, caching strategy + +4. **Complexity Creep** + - **Mitigation**: MVP first (basic households), iterate based on feedback + +### Testing Strategy + +1. **Unit Tests**: All new models and controllers +2. **Integration Tests**: API endpoint flows +3. **Migration Tests**: Verify data integrity post-migration +4. **Load Tests**: Multi-household concurrent access +5. **User Acceptance**: Beta test with small group before full rollout + +--- + +## Open Questions & Decisions Needed + +### 1. Item Naming Strategy +- **Question**: Should "milk" from Household A and "Milk" from Household B be the same item? +- **Options**: + - Case-insensitive merge (current behavior, recommended) + - Exact match only + - User prompt for merge confirmation +- **Recommendation**: Case-insensitive with optional household override + +### 2. Store Management +- **Question**: Should all stores be predefined, or can users create custom stores? +- **Options**: + - Admin-only store creation (controlled list) + - Users can create custom stores (flexible but messy) + - Hybrid: predefined + custom +- **Recommendation**: Start with predefined stores, add custom later + +### 3. Historical Data +- **Question**: When a user leaves a household, what happens to their history? +- **Options**: + - Keep history, anonymize user + - Keep history with user name (allows recovery if re-added) + - Delete history +- **Recommendation**: Keep history with actual user name preserved + - **Rationale**: If user is accidentally removed, their contributions remain attributed correctly when re-added + - History queries should JOIN with users table but handle missing users gracefully + - Display format: Show user name if still exists, otherwise show "User [id]" or handle as deleted account + +### 4. Invite System +- **Question**: Should invite codes expire? +- **Options**: + - Never expire (simpler) + - 7-day expiration (more secure) + - Configurable per household +- **Recommendation**: Optional expiration, default to never + +### 5. Default Household +- **Question**: When user logs in, which household/store do they see? +- **Options**: + - Last used (remember preference) + - Most recently modified list + - User-configured default +- **Recommendation**: Remember last used in localStorage + +--- + +## Summary & Next Steps + +### Recommended Approach: **Hybrid Multi-Tenant Architecture** + +**Core Principles:** +1. ✅ Shared item catalog with household-specific lists +2. ✅ Per-household roles (not global) +3. ✅ Store-specific classifications +4. ✅ Invite-based household joining +5. ✅ Backward-compatible migration + +### Immediate Actions + +1. **Review & Approve**: Get stakeholder buy-in on this architecture +2. **Validate Assumptions**: Confirm design decisions (item sharing, store management) +3. **Create Detailed Tickets**: Break down sprints into individual tasks +4. **Set Up Staging**: Create test environment with production data copy +5. **Begin Sprint 1**: Start with database design and migration scripts + +### Success Metrics + +- ✅ Zero data loss during migration +- ✅ 100% existing users migrated to default household +- ✅ Performance within 20% of current (queries < 200ms) +- ✅ Users can create households and invite others +- ✅ Lists properly isolated between households +- ✅ Mobile UI remains responsive + +--- + +## Appendix A: Example User Flows + +### Creating a Household +1. User clicks "Create Household" +2. Enters name "Smith Family" +3. System generates invite code "SMITH2026" +4. User is set as "admin" role (creator is always admin) +5. User can share code with family members + +### Joining a Household +1. User receives invite code "SMITH2026" +2. Navigates to /join/SMITH2026 +3. Sees "Join Smith Family?" +4. Confirms, added as "user" role by default +5. Admin can promote to "admin" role if needed + +### Managing Multiple Households +1. User belongs to "Smith Family" and "Work Team" +2. Navbar shows dropdown: [Smith Family ▼] +3. Clicks dropdown, sees both households +4. Switches to "Work Team" +5. List updates to show Work Team's items +6. Store tabs show Work Team's configured stores + +### Adding Item to Store +1. User in "Smith Family" household +2. Sees store tabs: [Costco] [Target] +3. Clicks "Costco" tab +4. Adds "Milk" - goes to Costco list +5. Switches to "Target" tab +6. Adds "Bread" - goes to Target list +7. Milk and Bread are separate list entries (same item, different stores) + +--- + +## Appendix B: Database Size Estimates + +**Current Single List:** +- Users: 10 +- Items: 200 +- History records: 5,000 + +**After Multi-Household (10 households, 5 stores each):** +- Users: 10 +- Households: 10 +- Household_members: 30 (avg 3 users per household) +- Stores: 5 +- Household_stores: 50 +- Items: 500 (some shared, some unique) +- Household_lists: 2,500 (500 items × 5 stores) +- History: 25,000 + +**Storage Impact:** ~5x increase in list records, but items are deduplicated. + +**Query Performance:** +- Without indexes: O(n) → O(10n) = 10x slower +- With indexes: O(log n) → O(log 10n) = minimal impact + +**Conclusion:** With proper indexing, performance should remain acceptable even at 100+ households.