---
phase: 08-task-delete
plan: 01
subsystem: database
tags: [drift, sqlite, flutter, soft-delete, schema-migration]

# Dependency graph
requires: []
provides:
  - isActive BoolColumn on Tasks table (schema v3)
  - softDeleteTask(taskId) method on TasksDao
  - getCompletionCount(taskId) method on TasksDao
  - isActive=true filter on all task queries across all 4 DAOs
  - Schema migration from v2 to v3 (addColumn)
affects: [08-02, 08-03, delete-dialog, task-providers]

# Tech tracking
tech-stack:
  added: []
  patterns:
    - "Soft delete via isActive BoolColumn with default true"
    - "All task-returning DAO queries filter by isActive=true"
    - "Schema versioning via Drift addColumn migration"
    - "TDD: RED commit before implementation GREEN commit"

key-files:
  created:
    - drift_schemas/household_keeper/drift_schema_v3.json
    - test/drift/household_keeper/generated/schema_v3.dart
  modified:
    - lib/core/database/database.dart
    - lib/features/tasks/data/tasks_dao.dart
    - lib/features/home/data/calendar_dao.dart
    - lib/features/home/data/daily_plan_dao.dart
    - lib/features/rooms/data/rooms_dao.dart
    - test/features/tasks/data/tasks_dao_test.dart
    - test/drift/household_keeper/migration_test.dart
    - test/drift/household_keeper/generated/schema.dart
    - test/core/database/database_test.dart
    - test/features/home/presentation/home_screen_test.dart
    - test/features/tasks/presentation/task_list_screen_test.dart

key-decisions:
  - "isActive column uses BoolColumn.withDefault(true) so existing rows are automatically active after migration"
  - "Migration uses from==2 (not from<3) for addColumn to avoid duplicate-column error when upgrading from v1 (where createTable already includes isActive)"
  - "Migration tests updated to only test paths ending at v3 (current schemaVersion) since AppDatabase always migrates to its schemaVersion"

patterns-established:
  - "Soft-delete pattern: isActive BoolColumn with default true, filter all queries by isActive=true"
  - "Hard-delete remains via deleteTask(id) which cascades to completions"

requirements-completed: [DEL-02, DEL-03]

# Metrics
duration: 9min
completed: 2026-03-18
---

# Phase 8 Plan 01: isActive Column and DAO Filtering Summary

**Drift schema v3 with isActive BoolColumn on Tasks, soft-delete DAO methods, and isActive=true filter applied to all 15 task queries across TasksDao, CalendarDao, DailyPlanDao, and RoomsDao**

## Performance

- **Duration:** 9 min
- **Started:** 2026-03-18T19:47:32Z
- **Completed:** 2026-03-18T19:56:39Z
- **Tasks:** 2
- **Files modified:** 11

## Accomplishments
- Added `isActive BoolColumn` (default `true`) to Tasks table with schema v3 migration
- Added `softDeleteTask(taskId)` and `getCompletionCount(taskId)` to TasksDao
- Applied `isActive=true` filter to all task-returning queries across all 4 DAOs (15 total query sites)
- 6 new tests passing (softDeleteTask, getCompletionCount, watchTasksInRoom filtering, getOverdueTaskCount filtering, hard deleteTask still works)
- All 144 tests pass, dart analyze reports zero issues

## Task Commits

Each task was committed atomically:

1. **TDD RED: Failing tests** - `a2cef91` (test)
2. **Task 1: Add isActive column, migration v3, softDeleteTask and getCompletionCount** - `4b51f5f` (feat)
3. **Task 2: Add isActive filters to CalendarDao, DailyPlanDao, RoomsDao** - `b2f14dc` (feat)

## Files Created/Modified
- `lib/core/database/database.dart` - Added isActive BoolColumn to Tasks, bumped schemaVersion to 3, added from==2 migration
- `lib/features/tasks/data/tasks_dao.dart` - Added isActive filter to watchTasksInRoom and getOverdueTaskCount, added softDeleteTask and getCompletionCount methods
- `lib/features/home/data/calendar_dao.dart` - Added isActive=true filter to all 6 query methods
- `lib/features/home/data/daily_plan_dao.dart` - Added isActive=true filter to all 3 query methods
- `lib/features/rooms/data/rooms_dao.dart` - Added isActive=true filter to watchRoomWithStats task query
- `test/features/tasks/data/tasks_dao_test.dart` - Added 6 new tests for soft-delete behavior
- `test/drift/household_keeper/migration_test.dart` - Updated to test v1→v3 and v2→v3 migrations
- `test/drift/household_keeper/generated/schema_v3.dart` - Generated schema snapshot for v3
- `test/drift/household_keeper/generated/schema.dart` - Updated to include v3 in versions list
- `drift_schemas/household_keeper/drift_schema_v3.json` - v3 schema JSON for Drift migration tooling
- `test/core/database/database_test.dart` - Updated schemaVersion assertion from 2 to 3
- `test/features/home/presentation/home_screen_test.dart` - Added isActive: true to Task constructor helper
- `test/features/tasks/presentation/task_list_screen_test.dart` - Added isActive: true to Task constructor helper

## Decisions Made
- `isActive` column uses `BoolColumn.withDefault(const Constant(true))` so all existing rows become active after migration without explicit data backfill
- Migration uses `from == 2` (not `from < 3`) for `addColumn` to avoid duplicate-column error when upgrading from v1 where `createTable` already includes the isActive column in the current schema definition
- Migration test framework updated to only test paths that end at the current schema version (v3), since `AppDatabase.schemaVersion = 3` means all migrations go to v3

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 1 - Bug] Fixed Task constructor calls missing isActive parameter in test helpers**
- **Found during:** Task 2 (running full test suite)
- **Issue:** After adding `isActive` as a required field on the generated `Task` dataclass, two test files with manual `Task(...)` constructors (`home_screen_test.dart`, `task_list_screen_test.dart`) failed to compile
- **Fix:** Added `isActive: true` to `_makeTask` helper functions in both files
- **Files modified:** `test/features/home/presentation/home_screen_test.dart`, `test/features/tasks/presentation/task_list_screen_test.dart`
- **Verification:** flutter test passes, all 144 tests pass
- **Committed in:** `b2f14dc` (Task 2 commit)

**2. [Rule 1 - Bug] Fixed schemaVersion assertion in database_test.dart**
- **Found during:** Task 2 (running full test suite)
- **Issue:** `database_test.dart` had `expect(db.schemaVersion, equals(2))` which failed after bumping to v3
- **Fix:** Updated assertion to `equals(3)` and renamed test to "has schemaVersion 3"
- **Files modified:** `test/core/database/database_test.dart`
- **Verification:** Test passes
- **Committed in:** `b2f14dc` (Task 2 commit)

**3. [Rule 1 - Bug] Fixed Drift migration tests for v3 schema**
- **Found during:** Task 2 (running full test suite)
- **Issue:** Migration tests tested v1→v2 migration, but AppDatabase.schemaVersion=3 causes all migrations to end at v3. Also, the `from < 3` addColumn migration caused a duplicate-column error when migrating from v1 (since createTable already includes isActive)
- **Fix:** (a) Generated schema_v3.dart snapshot, (b) Updated migration_test.dart to test v1→v3 and v2→v3, (c) Changed migration to `from == 2` instead of `from < 3`
- **Files modified:** `test/drift/household_keeper/migration_test.dart`, `test/drift/household_keeper/generated/schema_v3.dart`, `test/drift/household_keeper/generated/schema.dart`, `drift_schemas/household_keeper/drift_schema_v3.json`
- **Verification:** All 3 migration tests pass
- **Committed in:** `b2f14dc` (Task 2 commit)

---

**Total deviations:** 3 auto-fixed (all Rule 1 bugs caused directly by schema change)
**Impact on plan:** All fixes necessary for correctness. No scope creep.

## Issues Encountered
- The Drift migration testing framework requires schema snapshots for each version. Adding schema v3 required regenerating schema files and fixing the migration test to only test paths to the current version.

## User Setup Required
None - no external service configuration required.

## Next Phase Readiness
- `isActive` column and `softDeleteTask`/`getCompletionCount` methods are ready for use by the UI layer (task delete dialog in plan 08-02)
- All active views (calendar, room task list, daily plan, room stats) now correctly exclude soft-deleted tasks
- Hard delete (deleteTask) remains unchanged and still cascades to completions

---
*Phase: 08-task-delete*
*Completed: 2026-03-18*
