Skip to content
sysout.dev

Technical Design: Mission-Based Checklists

Technical design for reusable blueprints, household members, and active mission checklists.

1. Overview

Mission-Based Checklists help users manage complex, recurring household events by combining pre-defined modular checklists (Blueprints) into a single active mission. This offloads the mental effort of remembering what goes where for specific life scenarios.

1.1 Core Concepts

Concept Description

Blueprint

A reusable, static template of items/tasks (e.g., "Son’s Weekend Bag", "Hospital Visit")

Blueprint Item

An individual item in a blueprint with assignee and optional inventory link

Mission

An active event combining one or more blueprints into a unified checklist

Mission Item

A concrete instance of a blueprint item within an active mission

Inventory Bridge

Auto-checks inventory stock for blueprint items linked to inventory

1.2 Key User Flows

┌─────────────────────────────────────────────────────────────────┐
│  1. CREATE BLUEPRINTS                                           │
│     "Son's Weekend Bag" → [Diapers, Milk, Clothes, Toys]        │
│     "Hospital Visit" → [Reports, ID, Water, Charger]            │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│  2. LAUNCH MISSION                                              │
│     "Trip to Hyderabad" = Son's Bag + Mounika's Bag + Car Check │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│  3. TRACK PROGRESS                                              │
│     [████████░░] Son's Bag (80%)  │  [██░░░░░░░░] Car (20%)     │
│     ✓ Diapers   ✓ Milk   ○ Clothes   ○ Toys                    │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│  4. COMPLETE & ARCHIVE                                          │
│     Mission archived. Blueprints remain for next use.           │
└─────────────────────────────────────────────────────────────────┘

2. Feature Breakdown

Phase Feature Description Priority

1

Blueprint CRUD

Create/edit/delete blueprint templates

HIGH

2

Blueprint Items

Add items with assignees and inventory links

HIGH

3

Mission Launch

Select blueprints and create active mission

HIGH

4

Mission Tracking

Check off items, view progress per blueprint

HIGH

5

Inventory Bridge

Auto-check stock for linked items

MEDIUM

6

Mission Archive

Complete and archive missions

MEDIUM

7

Person Management

Manage household members for assignment

LOW

3. Data Model

3.1 Core Entities

HouseholdMember

Represents a person in the household for task assignment.

@Entity(tableName = "household_members")
data class HouseholdMemberEntity(
    @PrimaryKey
    val id: String,                    // UUID

    val name: String,                  // "Mounika", "Son"
    val nickname: String?,             // Short display name
    val avatarColor: String,           // Hex color for avatar circle
    val avatarEmoji: String?,          // Optional emoji avatar

    val isOwner: Boolean = false,      // The primary app user
    val createdAt: Long
)

Blueprint

A reusable checklist template.

@Entity(tableName = "blueprints")
data class BlueprintEntity(
    @PrimaryKey
    val id: String,                    // UUID

    val title: String,                 // "Son's Weekend Bag"
    val description: String?,          // Optional description
    val category: String,              // BlueprintCategory enum
    val tags: String?,                 // JSON array of tags

    val iconEmoji: String?,            // Visual icon
    val color: String?,                // Theme color (hex)

    val createdBy: String?,            // FK to household_members (nullable)
    val useCount: Int = 0,             // Times used in missions
    val lastUsedAt: Long?,

    val createdAt: Long,
    val updatedAt: Long
)

enum class BlueprintCategory {
    TRAVEL,
    HEALTH,
    SOCIAL,
    WORK,
    KIDS,
    HOME,
    CUSTOM
}

BlueprintItem

An item within a blueprint template.

@Entity(
    tableName = "blueprint_items",
    foreignKeys = [
        ForeignKey(
            entity = BlueprintEntity::class,
            parentColumns = ["id"],
            childColumns = ["blueprintId"],
            onDelete = ForeignKey.CASCADE
        )
    ],
    indices = [Index("blueprintId")]
)
data class BlueprintItemEntity(
    @PrimaryKey
    val id: String,                    // UUID
    val blueprintId: String,           // FK to blueprints

    val name: String,                  // "Diapers", "Water Bottle"
    val quantity: Int = 1,             // Default quantity needed
    val notes: String?,                // "Pack extra for long trips"

    val assignedToId: String?,         // FK to household_members (nullable)

    // Inventory Link
    val isInventoryLinked: Boolean = false,
    val inventoryItemKey: String?,     // Ingredient key for matching

    val sortOrder: Int = 0,
    val createdAt: Long
)

Mission

An active event combining blueprints.

@Entity(tableName = "missions")
data class MissionEntity(
    @PrimaryKey
    val id: String,                    // UUID

    val name: String,                  // "Trip to Hyderabad"
    val description: String?,
    val status: String,                // MissionStatus enum

    val scheduledDate: Long?,          // Optional target date
    val startedAt: Long,
    val completedAt: Long?,
    val archivedAt: Long?
)

enum class MissionStatus {
    ACTIVE,      // In progress
    COMPLETED,   // All items checked
    ARCHIVED,    // Moved to history
    CANCELLED    // Abandoned
}

MissionBlueprint

Join table linking missions to blueprints.

@Entity(
    tableName = "mission_blueprints",
    primaryKeys = ["missionId", "blueprintId"],
    foreignKeys = [
        ForeignKey(
            entity = MissionEntity::class,
            parentColumns = ["id"],
            childColumns = ["missionId"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = BlueprintEntity::class,
            parentColumns = ["id"],
            childColumns = ["blueprintId"],
            onDelete = ForeignKey.CASCADE
        )
    ],
    indices = [Index("missionId"), Index("blueprintId")]
)
data class MissionBlueprintEntity(
    val missionId: String,
    val blueprintId: String,
    val addedAt: Long
)

MissionItem

A concrete instance of a blueprint item in an active mission.

@Entity(
    tableName = "mission_items",
    foreignKeys = [
        ForeignKey(
            entity = MissionEntity::class,
            parentColumns = ["id"],
            childColumns = ["missionId"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = BlueprintEntity::class,
            parentColumns = ["id"],
            childColumns = ["sourceBlueprintId"],
            onDelete = ForeignKey.SET_NULL
        )
    ],
    indices = [Index("missionId"), Index("sourceBlueprintId")]
)
data class MissionItemEntity(
    @PrimaryKey
    val id: String,                    // UUID
    val missionId: String,             // FK to missions

    // Source tracking
    val sourceBlueprintId: String?,    // Which blueprint this came from
    val sourceBlueprintItemId: String?, // Original blueprint item

    // Item details (copied from blueprint for independence)
    val name: String,
    val quantity: Int = 1,
    val notes: String?,
    val assignedToId: String?,

    // Status
    val isChecked: Boolean = false,
    val checkedAt: Long?,
    val checkedByMemberId: String?,

    // Inventory link status
    val isInventoryLinked: Boolean = false,
    val inventoryItemKey: String?,
    val inventoryStatus: String?,      // InventoryCheckStatus enum

    val sortOrder: Int = 0
)

enum class InventoryCheckStatus {
    NOT_LINKED,      // No inventory link
    IN_STOCK,        // Sufficient quantity
    LOW_STOCK,       // Below required quantity
    OUT_OF_STOCK,    // Not in inventory
    UNKNOWN          // Couldn't check
}

3.2 Relationship Diagram

+-------------------+       +---------------------+       +-------------------+
| HouseholdMember   |<------| BlueprintItem      |------>| Blueprint         |
+-------------------+  N:1  | (assignedTo)       |  N:1  +-------------------+
                            +---------------------+              │
                                                                 │ 1:N
                                                                 ▼
+-------------------+       +---------------------+       +-------------------+
|    Mission        |<----->| MissionBlueprint   |<----->| Blueprint         |
+-------------------+  1:N  | (join table)       |  N:1  +-------------------+
        │                   +---------------------+
        │
        │ 1:N
        ▼
+-------------------+
|   MissionItem     |-----> Copied from BlueprintItem
+-------------------+       (with status tracking)

3.3 Database Migration

// Migration v6 -> v7
val MIGRATION_6_7 = object : Migration(6, 7) {
    override fun migrate(database: SupportSQLiteDatabase) {
        // Household members
        database.execSQL("""
            CREATE TABLE IF NOT EXISTS household_members (
                id TEXT PRIMARY KEY NOT NULL,
                name TEXT NOT NULL,
                nickname TEXT,
                avatarColor TEXT NOT NULL,
                avatarEmoji TEXT,
                isOwner INTEGER NOT NULL DEFAULT 0,
                createdAt INTEGER NOT NULL
            )
        """)

        // Blueprints
        database.execSQL("""
            CREATE TABLE IF NOT EXISTS blueprints (
                id TEXT PRIMARY KEY NOT NULL,
                title TEXT NOT NULL,
                description TEXT,
                category TEXT NOT NULL,
                tags TEXT,
                iconEmoji TEXT,
                color TEXT,
                createdBy TEXT,
                useCount INTEGER NOT NULL DEFAULT 0,
                lastUsedAt INTEGER,
                createdAt INTEGER NOT NULL,
                updatedAt INTEGER NOT NULL
            )
        """)

        // Blueprint items
        database.execSQL("""
            CREATE TABLE IF NOT EXISTS blueprint_items (
                id TEXT PRIMARY KEY NOT NULL,
                blueprintId TEXT NOT NULL,
                name TEXT NOT NULL,
                quantity INTEGER NOT NULL DEFAULT 1,
                notes TEXT,
                assignedToId TEXT,
                isInventoryLinked INTEGER NOT NULL DEFAULT 0,
                inventoryItemKey TEXT,
                sortOrder INTEGER NOT NULL DEFAULT 0,
                createdAt INTEGER NOT NULL,
                FOREIGN KEY(blueprintId) REFERENCES blueprints(id) ON DELETE CASCADE
            )
        """)
        database.execSQL("CREATE INDEX IF NOT EXISTS idx_blueprint_items_blueprint ON blueprint_items(blueprintId)")

        // Missions
        database.execSQL("""
            CREATE TABLE IF NOT EXISTS missions (
                id TEXT PRIMARY KEY NOT NULL,
                name TEXT NOT NULL,
                description TEXT,
                status TEXT NOT NULL,
                scheduledDate INTEGER,
                startedAt INTEGER NOT NULL,
                completedAt INTEGER,
                archivedAt INTEGER
            )
        """)

        // Mission-Blueprint join table
        database.execSQL("""
            CREATE TABLE IF NOT EXISTS mission_blueprints (
                missionId TEXT NOT NULL,
                blueprintId TEXT NOT NULL,
                addedAt INTEGER NOT NULL,
                PRIMARY KEY(missionId, blueprintId),
                FOREIGN KEY(missionId) REFERENCES missions(id) ON DELETE CASCADE,
                FOREIGN KEY(blueprintId) REFERENCES blueprints(id) ON DELETE CASCADE
            )
        """)
        database.execSQL("CREATE INDEX IF NOT EXISTS idx_mission_blueprints_mission ON mission_blueprints(missionId)")
        database.execSQL("CREATE INDEX IF NOT EXISTS idx_mission_blueprints_blueprint ON mission_blueprints(blueprintId)")

        // Mission items
        database.execSQL("""
            CREATE TABLE IF NOT EXISTS mission_items (
                id TEXT PRIMARY KEY NOT NULL,
                missionId TEXT NOT NULL,
                sourceBlueprintId TEXT,
                sourceBlueprintItemId TEXT,
                name TEXT NOT NULL,
                quantity INTEGER NOT NULL DEFAULT 1,
                notes TEXT,
                assignedToId TEXT,
                isChecked INTEGER NOT NULL DEFAULT 0,
                checkedAt INTEGER,
                checkedByMemberId TEXT,
                isInventoryLinked INTEGER NOT NULL DEFAULT 0,
                inventoryItemKey TEXT,
                inventoryStatus TEXT,
                sortOrder INTEGER NOT NULL DEFAULT 0,
                FOREIGN KEY(missionId) REFERENCES missions(id) ON DELETE CASCADE,
                FOREIGN KEY(sourceBlueprintId) REFERENCES blueprints(id) ON DELETE SET NULL
            )
        """)
        database.execSQL("CREATE INDEX IF NOT EXISTS idx_mission_items_mission ON mission_items(missionId)")
        database.execSQL("CREATE INDEX IF NOT EXISTS idx_mission_items_blueprint ON mission_items(sourceBlueprintId)")
    }
}

4. Inventory Bridge

4.1 Purpose

When a blueprint item is linked to inventory (e.g., "Diapers" links to diapers in the pantry), the system automatically checks stock levels when launching a mission.

4.2 Stock Check Flow

class InventoryBridge @Inject constructor(
    private val itemRepository: ItemRepository,
    private val ingredientMatcher: IngredientMatcher
) {

    suspend fun checkBlueprintItemStock(
        item: BlueprintItem
    ): InventoryCheckResult {
        if (!item.isInventoryLinked || item.inventoryItemKey == null) {
            return InventoryCheckResult.NotLinked
        }

        val inventory = itemRepository.getAllGroceryItems().first()
        val match = ingredientMatcher.findMatches(item.inventoryItemKey, inventory)

        return when (match) {
            is MatchResult.Found -> {
                when {
                    match.totalAvailable >= item.quantity ->
                        InventoryCheckResult.InStock(match.totalAvailable, match.unit)
                    match.totalAvailable > 0 ->
                        InventoryCheckResult.LowStock(match.totalAvailable, item.quantity, match.unit)
                    else ->
                        InventoryCheckResult.OutOfStock
                }
            }
            is MatchResult.Fuzzy ->
                InventoryCheckResult.Unknown("Possible match found, please verify")
            is MatchResult.NotFound ->
                InventoryCheckResult.OutOfStock
        }
    }

    suspend fun checkMissionItems(
        missionItems: List<MissionItem>
    ): Map<String, InventoryCheckResult> {
        return missionItems
            .filter { it.isInventoryLinked }
            .associate { item ->
                item.id to checkBlueprintItemStock(
                    BlueprintItem(
                        id = item.id,
                        name = item.name,
                        quantity = item.quantity,
                        isInventoryLinked = true,
                        inventoryItemKey = item.inventoryItemKey
                    )
                )
            }
    }
}

sealed class InventoryCheckResult {
    object NotLinked : InventoryCheckResult()
    data class InStock(val available: Double, val unit: String) : InventoryCheckResult()
    data class LowStock(val available: Double, val required: Int, val unit: String) : InventoryCheckResult()
    object OutOfStock : InventoryCheckResult()
    data class Unknown(val message: String) : InventoryCheckResult()
}

5. UI Design

5.1 Blueprint Library Screen

+------------------------------------------+
|  <- Blueprints                      [+]  |
+------------------------------------------+
|                                          |
|  [Travel] [Health] [Kids] [Work] [All]   |
|                                          |
|  --- Travel ---                          |
|                                          |
|  +------------------------------------+  |
|  | [Bag] Son's Weekend Bag       [>] |  |
|  |      5 items • Used 3 times       |  |
|  +------------------------------------+  |
|                                          |
|  +------------------------------------+  |
|  | [Car] Car Maintenance Check   [>] |  |
|  |      8 items • Never used         |  |
|  +------------------------------------+  |
|                                          |
|  --- Health ---                          |
|                                          |
|  +------------------------------------+  |
|  | [Hospital] Hospital Visit     [>] |  |
|  |      6 items • Used 1 time        |  |
|  +------------------------------------+  |
|                                          |
+------------------------------------------+

5.2 Blueprint Detail/Edit Screen

+------------------------------------------+
|  <- Son's Weekend Bag          [*] [...]  |
+------------------------------------------+
|                                          |
|  Category: Travel                        |
|  Tags: #kids #weekend                    |
|                                          |
|  --- Items (5) ---                  [+]  |
|                                          |
|  +------------------------------------+  |
|  | [ ] Diapers (x10)                  |  |
|  |     [M] Mounika  [Inv] In stock    |  |
|  +------------------------------------+  |
|                                          |
|  +------------------------------------+  |
|  | [ ] Milk Bottles (x2)              |  |
|  |     [M] Mounika  [Inv] Low stock!  |  |
|  +------------------------------------+  |
|                                          |
|  +------------------------------------+  |
|  | [ ] Extra Clothes (x2)             |  |
|  |     [O] Owner                      |  |
|  +------------------------------------+  |
|                                          |
|  +------------------------------------+  |
|  | [ ] Favorite Toy                   |  |
|  |     Note: The blue elephant        |  |
|  +------------------------------------+  |
|                                          |
|  [Start Mission with this Blueprint]     |
|                                          |
+------------------------------------------+

Legend:
[M] = Assigned to Mounika
[O] = Assigned to Owner
[Inv] = Linked to inventory

5.3 Mission Launch Screen

+------------------------------------------+
|  <- New Mission                          |
+------------------------------------------+
|                                          |
|  Mission Name:                           |
|  [Trip to Hyderabad________________]     |
|                                          |
|  Scheduled Date: [Jan 30, 2026_____]     |
|                                          |
|  --- Select Blueprints ---               |
|                                          |
|  +------------------------------------+  |
|  | [x] Son's Weekend Bag              |  |
|  |     5 items                        |  |
|  +------------------------------------+  |
|                                          |
|  +------------------------------------+  |
|  | [x] Mounika's Travel Essentials    |  |
|  |     8 items                        |  |
|  +------------------------------------+  |
|                                          |
|  +------------------------------------+  |
|  | [x] Car Maintenance Check          |  |
|  |     8 items                        |  |
|  +------------------------------------+  |
|                                          |
|  +------------------------------------+  |
|  | [ ] Hospital Visit                 |  |
|  |     6 items                        |  |
|  +------------------------------------+  |
|                                          |
|  --- Summary ---                         |
|  3 blueprints selected • 21 total items  |
|  2 items need restocking                 |
|                                          |
|  [Cancel]              [Launch Mission]  |
+------------------------------------------+

5.4 Active Mission Screen

+------------------------------------------+
|  <- Trip to Hyderabad           [...] |  |
+------------------------------------------+
|  Jan 30, 2026 • 15 of 21 complete        |
|  [████████████████████░░░░░░░░] 71%      |
+------------------------------------------+
|                                          |
|  --- Son's Weekend Bag (4/5) ---         |
|  [████████████████░░░░] 80%              |
|                                          |
|  +------------------------------------+  |
|  | [x] Diapers (x10)              [M] |  |
|  +------------------------------------+  |
|  | [x] Milk Bottles (x2)          [M] |  |
|  +------------------------------------+  |
|  | [x] Extra Clothes (x2)         [O] |  |
|  +------------------------------------+  |
|  | [x] Favorite Toy               [M] |  |
|  +------------------------------------+  |
|  | [ ] Snacks                     [O] |  |
|  |     [!] Out of stock               |  |
|  +------------------------------------+  |
|                                          |
|  --- Car Check (2/8) ---                 |
|  [████░░░░░░░░░░░░░░░░] 25%              |
|                                          |
|  +------------------------------------+  |
|  | [x] Tire pressure              [O] |  |
|  +------------------------------------+  |
|  | [x] Fuel level                 [O] |  |
|  +------------------------------------+  |
|  | [ ] First aid kit              [O] |  |
|  +------------------------------------+  |
|  ... (more items)                        |
|                                          |
+------------------------------------------+
|  [Complete Mission]                      |
+------------------------------------------+

6. Business Logic

6.1 Duplicate Handling

When the same item appears in multiple blueprints:

enum class DuplicateHandling {
    SHOW_SEPARATELY,  // Show each instance (default)
    MERGE_QUANTITIES  // Combine into single item with summed quantity
}

class MissionComposer @Inject constructor(...) {

    fun composeMission(
        blueprintIds: List<String>,
        duplicateHandling: DuplicateHandling = DuplicateHandling.SHOW_SEPARATELY
    ): List<MissionItem> {
        val allItems = blueprintIds.flatMap { getBlueprintItems(it) }

        return when (duplicateHandling) {
            DuplicateHandling.SHOW_SEPARATELY -> allItems.map { it.toMissionItem() }
            DuplicateHandling.MERGE_QUANTITIES -> mergeDuplicates(allItems)
        }
    }

    private fun mergeDuplicates(items: List<BlueprintItem>): List<MissionItem> {
        return items
            .groupBy { it.name.lowercase() }
            .map { (_, groupedItems) ->
                val first = groupedItems.first()
                MissionItem(
                    name = first.name,
                    quantity = groupedItems.sumOf { it.quantity },
                    notes = groupedItems.mapNotNull { it.notes }.joinToString("; "),
                    assignedToId = first.assignedToId,
                    isInventoryLinked = groupedItems.any { it.isInventoryLinked },
                    inventoryItemKey = groupedItems.firstNotNullOfOrNull { it.inventoryItemKey }
                )
            }
    }
}

6.2 Mission Completion

class MissionManager @Inject constructor(...) {

    fun canCompleteMission(mission: Mission, items: List<MissionItem>): Boolean {
        return items.all { it.isChecked }
    }

    suspend fun completeMission(missionId: String) {
        val mission = missionRepository.getMission(missionId) ?: return
        val items = missionRepository.getMissionItems(missionId)

        if (!canCompleteMission(mission, items)) {
            throw IllegalStateException("Cannot complete mission: not all items checked")
        }

        // Update mission status
        missionRepository.updateMissionStatus(
            missionId = missionId,
            status = MissionStatus.COMPLETED,
            completedAt = System.currentTimeMillis()
        )

        // Increment use count for all blueprints
        mission.blueprintIds.forEach { blueprintId ->
            blueprintRepository.incrementUseCount(blueprintId)
        }
    }

    suspend fun archiveMission(missionId: String) {
        missionRepository.updateMissionStatus(
            missionId = missionId,
            status = MissionStatus.ARCHIVED,
            archivedAt = System.currentTimeMillis()
        )
    }
}

7. File Structure

app/src/main/kotlin/dev/sysout/homey/app/features/
└── mission/
    ├── data/
    │   ├── HouseholdMemberEntity.kt
    │   ├── BlueprintEntity.kt
    │   ├── BlueprintItemEntity.kt
    │   ├── MissionEntity.kt
    │   ├── MissionBlueprintEntity.kt
    │   ├── MissionItemEntity.kt
    │   ├── BlueprintDao.kt
    │   ├── MissionDao.kt
    │   ├── HouseholdMemberDao.kt
    │   ├── BlueprintRepository.kt
    │   ├── MissionRepository.kt
    │   └── HouseholdMemberRepository.kt
    ├── domain/
    │   ├── Blueprint.kt
    │   ├── BlueprintItem.kt
    │   ├── Mission.kt
    │   ├── MissionItem.kt
    │   └── HouseholdMember.kt
    ├── bridge/
    │   └── InventoryBridge.kt
    ├── compose/
    │   └── MissionComposer.kt
    └── ui/
        ├── blueprints/
        │   ├── BlueprintListScreen.kt
        │   ├── BlueprintDetailScreen.kt
        │   ├── BlueprintEditScreen.kt
        │   └── BlueprintViewModel.kt
        ├── missions/
        │   ├── MissionLaunchScreen.kt
        │   ├── ActiveMissionScreen.kt
        │   ├── MissionHistoryScreen.kt
        │   └── MissionViewModel.kt
        └── components/
            ├── BlueprintCard.kt
            ├── MissionItemRow.kt
            ├── ProgressBar.kt
            └── MemberAvatar.kt

8. Navigation

// Add to Screen.kt
object Blueprints : Screen("mission/blueprints", "Blueprints", Icons.Default.Checklist)
object BlueprintDetail : Screen("mission/blueprints/{blueprintId}", "Blueprint", Icons.Default.Checklist) {
    fun createRoute(blueprintId: String) = "mission/blueprints/$blueprintId"
}
object BlueprintEdit : Screen("mission/blueprints/{blueprintId}/edit", "Edit Blueprint", Icons.Default.Edit) {
    fun createRoute(blueprintId: String) = "mission/blueprints/$blueprintId/edit"
}
object BlueprintCreate : Screen("mission/blueprints/new", "New Blueprint", Icons.Default.Add)
object MissionLaunch : Screen("mission/launch", "New Mission", Icons.Default.RocketLaunch)
object ActiveMission : Screen("mission/active/{missionId}", "Mission", Icons.Default.PlayArrow) {
    fun createRoute(missionId: String) = "mission/active/$missionId"
}
object MissionHistory : Screen("mission/history", "History", Icons.Default.History)

9. Implementation Order

Phase Deliverable Dependencies

1

Entities + DAOs + Migration

Database setup

2

Blueprint CRUD UI

Phase 1

3

Blueprint Items with assignees

Phase 2, HouseholdMember

4

Mission Launch flow

Phases 2-3

5

Active Mission tracking

Phase 4

6

Inventory Bridge integration

Phase 5, existing IngredientMatcher

7

Mission archive & history

Phase 5

10. Open Questions

  1. Recurring Missions: Should missions be schedulable to auto-launch weekly/monthly?

  2. Sharing: Share blueprints between households?

  3. Notifications: Remind user of upcoming scheduled missions?

  4. Quick Actions: "One-tap" launch for frequently used single-blueprint missions?

  5. Templates Gallery: Pre-built blueprints (e.g., "Baby Travel Kit", "Camping Trip")?


Document Version: 1.0 Created: 2026-01-25 Status: Ready for Review