Skip to content

feat: 데일리 루틴 (반복 할 일) 지원#68

Open
sjin4861 wants to merge 7 commits into
mainfrom
feat/recurring-todos
Open

feat: 데일리 루틴 (반복 할 일) 지원#68
sjin4861 wants to merge 7 commits into
mainfrom
feat/recurring-todos

Conversation

@sjin4861
Copy link
Copy Markdown
Owner

@sjin4861 sjin4861 commented Jun 6, 2026

Summary

  • 도메인에 RecurrenceRule (daily/weekly/monthly/yearly + interval + 요일/일자 + 종료조건) 추가
  • Hive에 신규 typeId 5–8 + TodoModel HiveField 10–12 (nullable) → 기존 박스 호환 (마이그레이션 불필요)
  • 홈/투두관리 화면에서 시리즈를 lazy expand해서 날짜별 가상 인스턴스 합성, 체크 시 자동 머터리얼라이즈
  • 반복 입력 BottomSheet (주기/간격/요일/일자/종료조건), 반복 todo 행에 repeat 아이콘
  • 반복 삭제는 시리즈 전체 삭제 확인 다이얼로그 (완료 이력은 보존)

Commits (단계별 리뷰 권장)

  1. feat(domain): 엔티티 + UseCase + expand 알고리즘
  2. feat(data): Hive 모델/어댑터/매퍼/등록 + 라운드트립 테스트
  3. feat(data): Repository/Datasource 구현 + 단위 테스트
  4. feat(presentation): TodoInputView 반복 BottomSheet
  5. feat(presentation): 홈/관리 화면 lazy expansion + 아이콘
  6. feat(presentation): 시리즈 삭제 확인 다이얼로그
  7. test(data): 통합 테스트 (생성→expand→완료→삭제)

Test plan

  • domain/data/presentation 단위 테스트 통과
  • flutter analyze 0 errors
  • 매일/격일 생성 → 다음 날 홈 표시 확인
  • 매주 월/수/금 → 요일별 표시/비표시 확인
  • 매달 N일 → 다음 달 같은 날 표시 확인
  • EndOnDate / EndAfterCount 이후 미표시 확인
  • 한 회차 체크 → 다음 회차는 미체크 확인
  • 시리즈 삭제 → 완료 인스턴스 보존, 미래 occurrence 사라지는지 확인
  • 기존 단일 todo 회귀 없음

Jun Seo and others added 7 commits June 6, 2026 13:36
Introduces RecurrenceRule with daily/weekly/monthly/yearly frequency,
interval, weekday selection, and a sealed RecurrenceEnd type
(never/onDate/afterCount). Todo gains nullable recurrence, seriesId,
and occurrenceDate so a single entity can represent both a series
template and a materialized occurrence.

Adds four usecases (create/update/delete/expand) and extends the
TodoRepository contract with series + occurrence lookups. Repository
impl uses stubs that throw UnimplementedError; full persistence lands
in step 2/3.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
RecurrenceRuleModel (typeId 8), RecurrenceEndModel (7),
RecurrenceEndKind (6), and RecurrenceFrequencyModel (5) provide
Hive-backed persistence for the new domain types. TodoModel adds three
nullable fields (recurrence/seriesId/occurrenceDate) at HiveField 10-12,
so existing boxes remain readable without migration.

Adapters are registered in main.dart, and a round-trip test confirms
non-recurring todos persist with null recurrence, weekly rules with
EndAfterCount survive the round-trip, materialized occurrences keep
their seriesId, and EndOnDate/EndNever both deserialize correctly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
TodoLocalDatasource gains getRecurringSeries (filters
non-occurrence todos with a recurrence rule), findOccurrence (matches
seriesId + day-normalized occurrenceDate), and
deleteSeriesAndUnfinishedOccurrences (drops the series and any
unfinished materialized occurrences, preserving completed history).

TodoRepositoryImpl delegates the four new contract methods to the
datasource. materializeOccurrence persists the entity as-is so the
virtual id assigned by ExpandRecurringTodosForDate becomes the stable
Hive key for that day's instance.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
TodoInputViewModel now carries a nullable RecurrenceRule, populates
it from the editing todo, and routes save through the recurring
usecases when a rule is set. describeRecurrence() formats the rule for
display ("매주 월, 수, 금", "매 2달 15일", etc.).

A new RecurrenceBottomSheet lets users choose frequency
(none/daily/weekly/monthly/yearly), interval, weekdays (multi-select
chips when weekly), month day (when monthly), and end condition
(never / on date / after N times). Defaults seed the start weekday for
weekly and the start day-of-month for monthly so common cases are
one-tap.

The input body surfaces a "반복" row beneath the existing options;
it is shown only for daily todos since a date-range todo already
defines a single span.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
HomeViewModel.loadTodos now drops series templates from the raw list,
asks ExpandRecurringTodosForDate for today's occurrences, and merges
them by id so an already-materialized instance wins over the virtual
copy. The home row shows a small repeat icon for any todo that carries
a recurrence rule (series or occurrence).

TodoManageViewModel applies the same drop+expand+merge for the
currently selected date; updateSelectedDate is now async so the
expansion refresh completes before filter/categorize. The status
update path in TodoRepositoryImpl preserves recurrence/seriesId/
occurrenceDate so toggling a virtual occurrence materializes it as a
proper occurrence record rather than wiping the recurrence metadata.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
TodoManageViewModel gains deleteRecurringSeries (delegates to
DeleteRecurringTodoUseCase) and deleteTodoById now falls back to the
day's expanded occurrences so virtual instances can also be targeted.

todo_list_section routes onDelete through a shared handler: a
non-recurring todo deletes immediately as before, while a recurring
one (series or any occurrence) raises a confirmation dialog explaining
that future occurrences will be removed and completed history is
preserved.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Drives a real TodoLocalDatasource (Hive) via a thin in-process
TodoRepository so create → expand → materialize-on-complete → delete
runs through the actual persistence layer, not mocks. Confirms a
weekly Mon/Wed/Fri series surfaces on Mon and Wed but not Tue, that
checking the Mon occurrence materializes a status=1.0 record, and that
deleting the series drops future occurrences while preserving the
completed Mon record.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant