Commit Graph

26 Commits

Author SHA1 Message Date
Achmad Setyabudi Susilo b0a62bedf0 feat(#6): implement ExpenseListScreen, AddEditExpenseScreen, AddEditRecurringScreen 2026-06-28 19:36:20 +07:00
admin 6f7d24a303 Merge pull request 'Implement CategoryScreen, ImportBankStatementScreen, SettingsScreen, and ExportAction helper (#7)' (#17) from feat/7-implement-screens-export into main
Reviewed-on: #17
2026-06-28 12:06:47 +00:00
Achmad Setyabudi Susilo 22863bfcd6 fix(#7): emit snackbar as resource id, resolve with stringResource in UI
Drop the Context injection from the ScreenModel. Emit a sealed
ImportSnackbarMessage carrying either a @StringRes id or a dynamic
text (for the error.message case where the bank importer surfaces a
useful 'BRI import not yet implemented' string). The screen resolves
resource ids via stringResource() in Composable scope and shows the
snackbar; the original error.message info is preserved via the
Dynamic variant instead of being dropped.
2026-06-28 18:46:17 +07:00
Achmad Setyabudi Susilo 5893ffc955 fix(#7): localize import snackbar strings and drop class.simpleName fallback
The three snackbar strings in ImportBankStatementScreenModel were
hardcoded English while the rest of the app uses stringResource. Move
them to res/values/strings.xml. Also drop the
error::class.simpleName fallback in the failure branch — it surfaced
Kotlin class names like NotImplementedError to end users. Now falls
back to the localized 'Import failed' string.
2026-06-28 18:32:58 +07:00
Achmad Setyabudi Susilo 1a71c4c9e6 chore(agents): require reviewer to use COMMENT state (same-account Gitea MCP)
Gitea blocks self-approval and self-requested-changes, so the reviewer
agent (which always reviews its own work on this same-account setup)
must always submit with state: COMMENT. Verdicts go in the summary body;
blocking concerns are marked inline with **Blocking:** / **Nit:** /
**Suggestion:** prefixes so the implementor can triage them.
2026-06-28 18:32:47 +07:00
Achmad Setyabudi Susilo ce01c175df fix(#7): use UTC for DateField initial seed to match pick conversion
DateField seeded the picker with ZoneId.systemDefault() but converted
the selectedDateMillis back with ZoneId.of("UTC"). For any non-UTC
user, the field and the picker displayed different days, and
confirming without re-picking silently shifted the export range by a
day. Use UTC on both sides (the DatePickerState contract is that
selectedDateMillis is UTC midnight of the picked day).
2026-06-28 18:27:49 +07:00
Achmad Setyabudi Susilo 7782df8b36 fix(#7): move DB/IO off main thread in ScreenModels
screenModelScope is backed by PlatformMainDispatcher (Main.immediate),
so direct interactor calls run DB queries and file I/O on the UI
thread. Switch reactive flows with .flowOn(Dispatchers.IO) and wrap
suspend calls in withContext(Dispatchers.IO).
2026-06-28 18:10:35 +07:00
Achmad Setyabudi Susilo f6860544e4 feat(#7): implement CategoryScreen, ImportBankStatementScreen, SettingsScreen, and ExportAction helper 2026-06-28 17:55:22 +07:00
Achmad Setyabudi Susilo 567f6a7cee chore(agents): document local.properties resolution for worktrees 2026-06-28 17:53:17 +07:00
admin 36deb46a28 Merge pull request 'Implement bankstatement, export, and data interactors (#4)' (#16) from feat/4-implement-bankstatement-export-data into main
Reviewed-on: #16
2026-06-28 10:42:01 +00:00
Achmad Setyabudi Susilo 94d40d4216 feat(#4): implement bankstatement, export, and data interactors 2026-06-28 17:37:04 +07:00
Achmad Setyabudi Susilo 105c858d57 chore(agents): split AGENTS.md into shared + per-role agents
Move architecture, package structure, dependencies, and implementation
rules into .opencode/agent/implementor.md (default primary agent). Add
.opencode/agent/reviewer.md (read-only primary agent) with PR review
workflow that leaves inline review comments only -- no issue creation,
no edits, no commits. AGENTS.md is now the shared context both agents
load: workflow, git/PR conventions, and docs index. Set
default_agent: implementor in opencode.json.
2026-06-28 17:06:06 +07:00
admin 1bb6747610 Merge pull request 'Implement expense interactors (#2)' (#11) from feat/2-implement-expense-interactors into main
Reviewed-on: #11
2026-06-28 09:58:45 +00:00
Achmad Setyabudi Susilo ca2992fceb Merge branch 'main' of https://git.achmad.dev/admin/ledgerr into feat/2-implement-expense-interactors
# Conflicts:
#	app/src/main/java/dev/achmad/ledgerr/di/DomainModule.kt
2026-06-28 16:57:58 +07:00
admin ec21462d03 Merge pull request 'Implement recurring interactors (#3)' (#10) from feat/3-implement-recurring-interactors into main
Reviewed-on: #10
2026-06-28 09:56:38 +00:00
Achmad Setyabudi Susilo 63bfe2a6b5 fix(#2): address PR review — use row mapper, require id==0, drop ignoreCase on amount, doc drift, orphan-category note 2026-06-28 16:52:42 +07:00
Achmad Setyabudi Susilo 7bb65025a2 fix(#3): make ProcessDueRecurringExpenses atomic via withTransaction
Address review: insert + advance pair must run in one DB transaction to
prevent duplicate expenses if the process is killed mid-loop.
2026-06-28 16:52:07 +07:00
Achmad Setyabudi Susilo 6a11284212 feat(#3): implement recurring interactors 2026-06-28 16:33:41 +07:00
Achmad Setyabudi Susilo 46f882b3c3 feat(#2): implement expense interactors 2026-06-28 16:33:39 +07:00
Achmad Setyabudi Susilo 179f5fe2f8 docs + AGENTS: worktree workflow, predictable branch naming, PR body template, review iteration, scope discipline 2026-06-28 16:27:37 +07:00
admin c22c33ab7e Merge pull request 'Implement category feature and wire DI foundation (#1)' (#8) from feat/1-category-foundation into main
Reviewed-on: #8
2026-06-28 09:17:22 +00:00
Achmad Setyabudi Susilo 547343992a fix(#1): address PR review — split upsert into insert/update, add @Transaction, runBlocking seed, trailing newline
Per review on PR #8 (#8):

- Split @Upsert into @Insert(OnConflictStrategy.REPLACE) + @Update in all 3 DAOs.
  @Upsert returns -1 on the update path, so callers wanting the row ID would
  get a junk value. Interactors now call insert vs update based on id == 0.
  UpsertCategory returns category.id explicitly for the id != 0 branch.
- Add @Transaction to the 3 @Relation queries (ExpenseDao.subscribeAll,
  ExpenseDao.subscribeByDateRange, RecurringExpenseDao.subscribeAll). This
  silences the KSP warnings the PR body mentioned and makes the intent
  explicit.
- Switch MainApplication seeding from a fire-and-forget CoroutineScope to
  runBlocking(Dispatchers.IO). A fast first-tap on HomeScreen could otherwise
  call GetCategories.awaitDefault() before seeding completed and crash.
- Add documenting comment on CategoryDao.getDefault() noting that the
  'only one isDefault = 1' invariant is maintained at the interactor layer
  (partial unique index would be a v2 migration).
- Add trailing newline to app/build.gradle.kts.
- File follow-up issue #9 for flipping exportSchema to true before any v2
  migration lands.
2026-06-28 16:09:15 +07:00
Achmad Setyabudi Susilo 8e7a6cfe3f feat(#1): implement category feature and wire DI foundation
- Add Room 2.7.1, PDFBox-Android 2.0.27.0, Vico 2.0.0 dependencies
- Bump compileSdk 36 -> 37 (transitive deps require it)
- Add LocalDateConverter + 3 entities + 3 DAOs with @Relation rows + mappers + AppDatabase v1
- Add all domain models (expense, category, recurring, bankstatement, preference)
- Implement 4 category interactors: GetCategories, UpsertCategory, DeleteCategory, SeedDefaultCategories
- Add minimal ReassignExpenseCategory (full expense interactors come in #2)
- Wire CoreModule (SharedPreferences + AndroidPreferenceStore), DataModule (Room + 3 DAOs), PreferenceModule, DomainModule (category factories)
- Create MainApplication with Koin start and SeedDefaultCategories trigger
- Register MainApplication in AndroidManifest
- Add missing string resources for pre-existing copied UI components (confirm, cancel, ok, general_selected, general_not_selected, disabled)
2026-06-28 15:53:58 +07:00
admin 51c54749cb docs + AGENTS: no-implementation rule, issue-driven workflow, Vico, Uncategorized, ClearAllData, AddEditRecurringScreen
- AGENTS.md: add No-implementation rule and Issue-driven workflow section
- docs/01: rename default fallback category from 'Other' to 'Uncategorized'
- docs/02, 03: update 'Other' references to 'Uncategorized' in delete/seed/default flows
- docs/04: replace Canvas charts with Vico 2.x dep, add data feature folder, add AddEditRecurringScreen, document tab-aware FAB and shared ExportAction helper
2026-06-28 15:47:28 +07:00
Achmad Setyabudi Susilo 3e30423083 docs: add architecture docs, AGENTS.md, CLAUDE.md, and copy UI components
- Add docs/01-04 covering data model, interfaces, function TODOs, and implementation plan
- Add AGENTS.md with project conventions, architecture rules, feature workflow, and git policy
- Add CLAUDE.md pointing to AGENTS.md
- Copy UI components and utils from info-krl-android (preference widgets, scrollbars, etc.)
- Delete obsolete UiModule.kt
2026-06-28 15:08:37 +07:00
Achmad Setyabudi Susilo dfca375a9b chore: setup project 2026-06-28 13:21:57 +07:00