- Extends GET /api/v1/tags with sort=count_desc and min_count query params - New TagsComponent at /tags (public, no auth guard) shows all tags sorted by image count - Clicking a tag navigates to /?tags=<name> for a pre-filtered library view - LibraryComponent reads ?tags= query param on init to support deep-linking from tag browser - Library header gains a "Browse tags" link to /tags for discoverability - All 15 TDD tasks complete; ruff, ng lint, and ng build clean Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.5 KiB
Feature Specification: Tag Browser
Feature Branch: 007-tag-browser
Created: 2026-05-06
Status: Draft
Input: User description: "A page that lists all tags with their image counts so that users don't have to guess at searches to find image categories/tags"
User Scenarios & Testing (mandatory)
User Story 1 — Browse All Tags (Priority: P1)
The owner (or any visitor) wants to know what categories of images exist in the library without having to type guesses into a search box. They navigate to the tag browser page and see every tag in the library alongside the number of images associated with it, sorted so the most-used tags appear first.
Why this priority: This is the entire purpose of the feature. A visitor who doesn't know what tags exist has no way to discover them otherwise — the tag filter on the library page only helps when you already know what to type.
Independent Test: Navigate to the tag browser page without being logged in. Confirm every tag in the library is shown with its image count, ordered from highest to lowest count.
Acceptance Scenarios:
- Given the library contains images with various tags, When a visitor opens the tag browser page, Then every tag in the library is listed with the number of images that carry that tag.
- Given the tag list is displayed, When the visitor looks at the ordering, Then tags with more images appear before tags with fewer images.
- Given the visitor is not logged in, When they open the tag browser page, Then the page loads and displays tags without requiring authentication.
User Story 2 — Navigate from Tag to Library (Priority: P1)
A visitor sees a tag they are interested in and wants to view the images in that category. Clicking a tag on the tag browser page takes them directly to the library filtered to that tag, without requiring them to retype it.
Why this priority: The tag browser page has no value as a dead end. Each tag must be a link to the filtered library view — that is the core action the page enables. Treated as P1 because the browse and navigate actions together form the minimum useful feature.
Independent Test: Click any tag on the tag browser page. Confirm the library view opens showing only images carrying that tag.
Acceptance Scenarios:
- Given the tag browser is showing a list of tags, When the visitor clicks a tag, Then they are taken to the library view filtered to show only images with that tag.
- Given the visitor clicks a tag with a count of one, When the library loads, Then exactly one image is shown.
User Story 3 — Reach the Tag Browser from the Library (Priority: P2)
The owner is browsing the image library and wants to switch to the tag browser to explore by category. A navigation element on the library page makes the tag browser discoverable without requiring the visitor to type the URL directly.
Why this priority: The tag browser is only useful if visitors can find it. A direct entry point from the library is the most natural discovery path; however, the core value of browsing and navigating tags is independently deliverable without it.
Independent Test: Load the library page. Confirm a visible link or button leads to the tag browser and navigates correctly when clicked.
Acceptance Scenarios:
- Given the visitor is on the library page, When they look for a way to browse by tag, Then a visible link or button leads them to the tag browser.
- Given the visitor clicks that link, When the tag browser loads, Then all tags and counts are shown as expected.
Edge Cases
- What if there are no tags in the library at all? The page displays an appropriate empty state message rather than a blank page or error.
- What if a tag has been removed from all images (count reaches zero)? Tags with a count of zero are not shown on the tag browser page.
- What if the library contains a very large number of distinct tags? The page renders all of them without truncation; pagination is not required at personal library scale.
- What if two tags share the same count? An alphabetical secondary sort is acceptable — no specific tie-breaking order was requested.
Requirements (mandatory)
Functional Requirements
- FR-001: The application MUST provide a dedicated tag browser page accessible at a stable URL.
- FR-002: The tag browser page MUST display every tag that exists in the library with at least one associated image, each shown with its current image count.
- FR-003: Tags with an image count of zero MUST NOT appear on the tag browser page.
- FR-004: Tags MUST be ordered from highest image count to lowest image count.
- FR-005: Each tag on the tag browser page MUST be a navigable link that takes the visitor to the library view filtered to that tag.
- FR-006: The tag browser page MUST be publicly accessible without authentication.
- FR-007: The library page MUST include a discoverable navigation element leading to the tag browser page.
Key Entities
- Tag with count: A tag label paired with the number of images currently carrying that tag. No new stored data — counts are derived from existing image–tag relationships at read time.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: Every tag present in the library with at least one image appears on the tag browser page — 0% omission rate.
- SC-002: The image count displayed next to each tag matches the actual number of images with that tag — 100% accuracy.
- SC-003: Clicking any tag on the tag browser navigates to the correctly filtered library view in 100% of cases.
- SC-004: The tag browser page loads successfully without authentication — verified by opening it while logged out.
- SC-005: A visitor can go from the library page to the tag browser and on to a filtered library view in three interactions or fewer.
Assumptions
- Tags are already a first-class concept in the library — images can have multiple tags and the data needed to derive counts already exists. No schema changes are required.
- The library page already supports filtering by tag (via the existing search/filter mechanism); the tag browser links into that existing behaviour.
- Alphabetical secondary sort for equal-count tags is acceptable.
- Pagination of the tag list is out of scope for a personal image library.
- Creating, renaming, or deleting tags from the tag browser page is out of scope; it is a read-only view.