Implement recurring interactors #3
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Overview
Implements the
recurringfeature — 4 interactors covering list, upsert, delete, and the due-date processor. Depends on #1.Prerequisites
Issue #1 must be merged first. This gives you:
AppDatabase+RecurringExpenseDao+ExpenseDaoalready wiredRecurringInterval,RecurringExpense,RecurringExpenseWithCategorydomain models already in placeWhat to do
1. Define signatures + TODOs
Create these 4 files under
domain/recurring/interactor/:GetRecurringExpenses.kt—subscribeAll(),awaitOne(id)UpsertRecurringExpense.kt—await(recurring): LongDeleteRecurringExpense.kt—await(id)ProcessDueRecurringExpenses.kt—await(today: LocalDate = LocalDate.now()): List<Expense>2. Implement all 4 interactors (replace TODOs)
Refer to
docs/03-function-todos.mdfor exact per-method behavior. Key points:GetRecurringExpenses.subscribeAll(): userecurringExpenseDao.subscribeAll()(returnsRecurringExpenseWithCategoryRow) and map each row viatoModel()for both nested types.UpsertRecurringExpense.await: ifid == 0insert, else update.DeleteRecurringExpense.await: deletes template by id. Do NOT delete expense instances previously created from this template — they retain theirrecurringExpenseIdvalue.ProcessDueRecurringExpenses.await:recurringExpenseDao.getDue(today.toEpochDay())— returns templates whereisActive = true AND nextDueDate <= today.Expense(no id,recurringExpenseId = template.id,date = template.nextDueDate,note = template.note,categoryId = template.categoryId,amount = template.amount).expenseDao.upsert(expense)(orinsertAllin a batch — your choice).template.nextDueDate = template.interval.advance(template.nextDueDate). Upsert the updated template.Edge case (per doc 03): if the app has not been opened for multiple intervals, advance
nextDueDateby one interval per call. The next app open processes again if still overdue. This avoids flooding the expense list with back-filled entries.3. Add to
DomainModule4. Verify compilation
Run
./gradlew assembleDebug. Must succeed.Acceptance
DomainModulehas the 4 new factories./gradlew assembleDebugsucceedsImplementation rule
Per
AGENTS.md— do not start implementation without explicit user sign-off on this issue. When working, check for related issues in the remote repo first.