Skip to content

feat(tag): Reimplement tags#56

Merged
OffRange merged 21 commits into
v2from
feat/reimplement-tag
May 20, 2026
Merged

feat(tag): Reimplement tags#56
OffRange merged 21 commits into
v2from
feat/reimplement-tag

Conversation

@OffRange
Copy link
Copy Markdown
Owner

This PR reimplements the tag feature from v1. It allows all features requested by #48

OffRange and others added 20 commits May 17, 2026 13:13
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.
Copilot AI review requested due to automatic review settings May 20, 2026 23:04
@OffRange OffRange linked an issue May 20, 2026 that may be closed by this pull request
5 tasks
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Tag domain model and persist tags via new Room tag / tag_cross_ref tables and a TagDao.
  • Integrate tags into item search (matched-by-tag), list filtering UI/state, and login create/view flows (chips + suggestions/autocomplete).
  • Introduce SortUseCase and 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.

Comment thread core/item/build.gradle.kts Outdated
…t test options

The `testOptions` configurations were removed from `core/item` and `feature/autofill` build files, specifically removing `isReturnDefaultValues` and `isIncludeAndroidResources` for unit tests.
@OffRange OffRange enabled auto-merge (squash) May 20, 2026 23:17
@OffRange OffRange merged commit 4429c30 into v2 May 20, 2026
7 of 8 checks passed
@OffRange OffRange deleted the feat/reimplement-tag branch May 20, 2026 23:44
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.

Reimplement tags

2 participants