feat(tag): Reimplement tags#56
Merged
Merged
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Ordering is now a use-case concern; list-screen filter labels absorb the change at the FilterMapper boundary via toSet(). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Vaults now order locale-aware/naturally, consistent with items and tags. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Routes ItemListViewModel's tag labels through a new ObserveTagLabelsUseCase so filter bottom-sheet tag chips render in natural locale-aware order, consistent with item/tag-suggestion/vault sorting. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the `Tag` string alias with an `@JvmInline` value class to handle tag normalization consistently across the app. This ensures that tag searches and filters are case-insensitive by querying against a normalized column while preserving the original user-provided casing for UI display. - Update `ItemDao` and `TagDao` to query against normalized tag values. - Refactor `ItemRepository` and its implementations to use the `Tag` domain model. - Update mappers and UI components in `feature/item` and `feature/list_screen` to support the new value class. - Enable the search text field in `ListSearchTextField`. - Adjust unit tests to validate case-insensitive matching and display-name preservation.
Closed
5 tasks
There was a problem hiding this comment.
Pull request overview
This PR reintroduces a first-class “tags” feature end-to-end (domain model → Room persistence → UI), enabling tag assignment to items, tag-based filtering, and tag-aware search, while also centralizing “natural” (numeric-aware, case-insensitive) sorting via a shared SortUseCase.
Changes:
- Add a
Tagdomain model and persist tags via new Roomtag/tag_cross_reftables and aTagDao. - Integrate tags into item search (matched-by-tag), list filtering UI/state, and login create/view flows (chips + suggestions/autocomplete).
- Introduce
SortUseCaseand reuse it for vault sorting, item sorting, and tag sorting.
Reviewed changes
Copilot reviewed 68 out of 69 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| gradle/libs.versions.toml | Adds AndroidX SQLite bundled dependency version/catalog entry. |
| feature/vault/src/main/kotlin/de/davis/keygo/feature/vault/domain/usecase/ObserveVaultsAndSelectionUseCase.kt | Switch vault sorting to shared SortUseCase (natural order). |
| feature/vault/src/test/kotlin/de/davis/keygo/feature/vault/domain/usecase/ObserveVaultsAndSelectionUseCaseTest.kt | Adds test coverage for natural numeric vault sorting. |
| feature/list_screen/src/main/kotlin/de/davis/keygo/feature/list_screen/domain/model/FilterState.kt | Replaces label filtering with selectedTags: Set<Tag>. |
| feature/list_screen/src/test/kotlin/de/davis/keygo/feature/list_screen/domain/model/FilterStateTest.kt | Updates filter-state default tests for tags. |
| feature/list_screen/src/main/kotlin/de/davis/keygo/feature/list_screen/domain/usecase/FilterUseCase.kt | Adds tag-id filtering and delegates sorting to SortUseCase. |
| feature/list_screen/src/test/kotlin/de/davis/keygo/feature/list_screen/domain/usecase/FilterUseCaseTest.kt | Adds tests for tag-id filtering behavior. |
| feature/list_screen/src/main/kotlin/de/davis/keygo/feature/list_screen/presentation/ItemListViewModel.kt | Wires tag selection to repository query + filter pipeline; exposes available tag options. |
| feature/list_screen/src/main/kotlin/de/davis/keygo/feature/list_screen/presentation/mapper/FilterMapper.kt | Maps available tags and selected tags into bottom-sheet chip state. |
| feature/list_screen/src/test/kotlin/de/davis/keygo/feature/list_screen/presentation/mapper/FilterMapperTest.kt | Adds tests ensuring only visible-item tags appear and ordering follows allTags. |
| feature/list_screen/src/main/kotlin/de/davis/keygo/feature/list_screen/presentation/model/AvailableFilterOptions.kt | Renames labels → tags in available filter options. |
| feature/list_screen/src/main/kotlin/de/davis/keygo/feature/list_screen/presentation/model/FilterAction.kt | Renames label toggle action to TagToggled(Tag). |
| feature/list_screen/src/main/kotlin/de/davis/keygo/feature/list_screen/presentation/model/FilterBottomSheetState.kt | Renames label chips to tag chips. |
| feature/list_screen/src/main/kotlin/de/davis/keygo/feature/list_screen/presentation/components/FilterBottomSheet.kt | Updates bottom sheet UI to render tag chips. |
| feature/list_screen/src/main/kotlin/de/davis/keygo/feature/list_screen/presentation/components/ItemListContent.kt | Updates preview state for tag-match + tag chips. |
| feature/list_screen/src/main/res/values/strings.xml | Renames “Labels” string to “Tags”. |
| feature/item/view/src/main/res/values/strings.xml | Adds “Add Tag” label. |
| feature/item/view/src/main/kotlin/de/davis/keygo/feature/item/view/login/model/ViewLoginState.kt | Adds tags: Set<Tag> to view state. |
| feature/item/view/src/main/kotlin/de/davis/keygo/feature/item/view/login/model/ModificationDialog.kt | Adds tagsToSuggest for tag autocomplete. |
| feature/item/view/src/main/kotlin/de/davis/keygo/feature/item/view/login/ViewLoginViewModel.kt | Adds tag suggestions and tag upsert on edit. |
| feature/item/view/src/main/kotlin/de/davis/keygo/feature/item/view/login/ViewLoginContent.kt | Displays tags as chips and adds tag suggestion field in dialog. |
| feature/item/create/src/main/res/values/strings.xml | Adds tag strings for create flow. |
| feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/login/model/LoginUiState.kt | Adds tag suggestion + assigned-tags fields. |
| feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/login/model/LoginUiEvent.kt | Adds add/remove tag events. |
| feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/login/LoginViewModel.kt | Connects all-tags suggestions and persists assigned tags in upsert. |
| feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/login/LoginContent.kt | Adds tag input handling and passes tag state into form. |
| feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/component/KeyGoItemForm.kt | Adds tag chip input group with suggestions. |
| feature/item/create/build.gradle.kts | No functional change (formatting only). |
| feature/item/core/src/main/res/values/strings.xml | Adds “Tags” label. |
| feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/login/model/FieldType.kt | Adds FieldType.Tag. |
| feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/component/KeyGoFormSuggestionField.kt | New suggestion/autocomplete form field component. |
| feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/component/ChipFormGroup.kt | Adds suggestion mode + shared delimiter splitting helpers. |
| feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/domain/model/UpsertLogin.kt | Adds tags to upsert model. |
| feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/domain/usecase/CreateNewOrUpdateLoginUseCase.kt | Writes tags into created/updated Login. |
| core/util/src/main/kotlin/de/davis/keygo/core/util/domain/usecase/SortUseCase.kt | New shared natural sort implementation (numeric-aware, locale collator). |
| core/util/src/test/kotlin/de/davis/keygo/core/util/domain/usecase/SortUseCaseTest.kt | Tests for shared natural sort behavior. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/domain/model/Tag.kt | New Tag type with normalized equality semantics. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/domain/model/Item.kt | Adds tags to base Item contract. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/domain/model/Login.kt | Adds tags to Login. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/domain/usecase/ObserveAllTagsSortedUseCase.kt | Exposes sorted list of all tags. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/domain/repository/ItemRepository.kt | Adds tag-related repository APIs. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/local/entity/TagEntity.kt | New Room entity for tags (unique normalized). |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/local/entity/TagCrossRef.kt | New cross-ref entity linking items ↔ tags. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/local/pojo/ItemTagProjection.kt | New DAO projection for item-tag rows. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/local/pojo/ItemProjection.kt | Adds tag relation to item projections. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/local/pojo/LoginProjection.kt | Switches to item projection that includes tags. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/local/pojo/LightweightItemSearchResult.kt | Adds matchedTag to search result projection. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/local/dao/TagDao.kt | New DAO for tag syncing, pruning, and observation. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/local/dao/ItemDao.kt | Extends search SQL to include tag matching. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/local/datasource/ItemDatabase.kt | Registers new tag entities/DAO in Room database. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/mapper/TagMapper.kt | Maps between Tag and TagEntity + dedup to normalized. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/mapper/LoginMapper.kt | Maps login projections including tags to domain Login. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/mapper/ItemMapper.kt | Maps matchedTag into domain search results. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/mapper/DomainInfoMapper.kt | Simplifies domain-info entity mapping using login id. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/repository/LoginRepositoryImpl.kt | Syncs tags via TagDao on upsert. |
| core/item/src/main/kotlin/de/davis/keygo/core/item/data/repository/ItemRepositoryImpl.kt | Adds tag observation/filtering APIs and tag-aware search. |
| core/item/schemas/de.davis.keygo.core.item.data.local.datasource.ItemDatabase/1.json | Updates Room schema snapshot for added tag tables. |
| core/item/build.gradle.kts | Adds SQLite bundled dependency for JVM tests and sets unit test return-default-values. |
| core/item/src/testFixtures/kotlin/de/davis/keygo/core/item/FakeItemRepository.kt | Adds in-memory implementations of new tag APIs. |
| core/item/src/test/kotlin/de/davis/keygo/core/item/domain/model/TagTest.kt | Adds tests for tag normalization/equality behavior. |
| core/item/src/test/kotlin/de/davis/keygo/core/item/domain/usecase/ObserveAllTagsSortedUseCaseTest.kt | Tests distinct + sorted tag observation. |
| core/item/src/test/kotlin/de/davis/keygo/core/item/data/repository/ItemRepositoryImplTest.kt | Tests tag pruning on delete and observeTagsByItem. |
| core/item/src/test/kotlin/de/davis/keygo/core/item/data/repository/LoginRepositoryImplTest.kt | Tests tag syncing and failure propagation. |
| core/item/src/test/kotlin/de/davis/keygo/core/item/data/local/dao/TagDaoTest.kt | Room DAO tests for dedup, pruning, and observation. |
| core/item/src/test/kotlin/de/davis/keygo/core/item/data/local/dao/ItemDaoSearchTest.kt | Tests search matching by tag. |
| core/item/src/test/kotlin/de/davis/keygo/core/item/data/mapper/LoginMapperTest.kt | Tests mapping of tags from entities and tag-entity generation. |
| core/item/src/test/kotlin/de/davis/keygo/core/item/data/mapper/ItemMapperTest.kt | Tests matchedTag mapping. |
| core/item/src/test/kotlin/de/davis/keygo/core/item/data/mapper/DomainMapperTest.kt | Updates tests for domain-info entity mapping signature change. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…t test options The `testOptions` configurations were removed from `core/item` and `feature/autofill` build files, specifically removing `isReturnDefaultValues` and `isIncludeAndroidResources` for unit tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR reimplements the tag feature from v1. It allows all features requested by #48