Feat: Add tag browser page at /tags with count-sorted tag list and library deep-link
- 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>
This commit is contained in:
95
specs/007-tag-browser/spec.md
Normal file
95
specs/007-tag-browser/spec.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# 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**:
|
||||
|
||||
1. **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.
|
||||
2. **Given** the tag list is displayed, **When** the visitor looks at the ordering, **Then** tags with more images appear before tags with fewer images.
|
||||
3. **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**:
|
||||
|
||||
1. **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.
|
||||
2. **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**:
|
||||
|
||||
1. **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.
|
||||
2. **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.
|
||||
Reference in New Issue
Block a user