# Meklēšanas vēsture — Functional Specification

**Status:** Approved v1.1 · 2026-07-16
**Scope of this document:** User-visible behavior for quickly returning to recently searched part numbers. Technical design and implementation are deliberately out of scope and follow only after this specification is approved.

---

## 1. Purpose

`Meklēšanas vēsture` lets the user repeat a recent part-number search without retyping or remembering the number.

The feature is a short list of recent searches, not a collection the user must organize. It helps answer:

- What part numbers did I search for recently?
- Can I run one of those searches again with one action?
- Can I remove entries I no longer want to see?

## 2. Terminology

| Term | Meaning |
|---|---|
| **Search history** | The user's automatically maintained list of recent valid search queries. Latvian UI wording: `Meklēšanas vēsture`. |
| **History entry** | One distinct canonical part number, together with the latest text entered by the user and the time it was last searched. |
| **Canonical part number** | The existing comparator form used to treat differences in spaces, dots, dashes, slashes, and letter case as the same search. |
| **Repeat search** | Starting a normal live comparison from a history entry. It is not a stored result snapshot. |

## 3. What Is Recorded

- A history entry is created when the user submits a query that passes the app's existing part-number validation and the app accepts it for searching.
- A valid search is recorded even when no store finds an offer, some stores fail, or the search is queued while connectivity recovers. These searches may still be useful to repeat or correct later.
- Invalid or rejected input is never added.
- History stores the query and its latest search time. It does not store offer results, prices, availability, filters, scroll position, or unresolved store challenges.
- The app keeps no separate product-analytics or measurement record of searches, store results, or outbound clicks. Search queries persist only as search history under this specification.

## 4. Duplicate Handling and Ordering

- Queries that canonicalize to the same part number are one history entry. For example, `W 712/52`, `w-712-52`, and `W71252` do not create three rows.
- Repeating an existing query moves it to the top and updates its last-searched time.
- The entry displays the most recently submitted valid formatting, so the history reflects how the user last typed the number.
- Entries are ordered by most recently searched first.
- The first version keeps at most **20** distinct entries. When a new distinct entry exceeds the limit, the least recently searched entry is removed automatically.

## 5. Entry Point and Presentation

- Focusing the empty search field opens search history when history is not empty. No separate history button or icon is shown.
- The history opens as a lightweight list anchored directly below the search field rather than navigating away from the current page or opening a full management screen.
- Typing a non-empty query closes the list. Clearing the search field while it remains focused opens the history again.
- The search field is not focused automatically when the page loads, so history appears in response to deliberate pointer or keyboard focus rather than opening on every visit.
- The list appears above other page content and does not discard the current results.
- On a narrow mobile screen, the list may use the available screen width, but it remains a lightweight search-field interaction rather than a separate destination.
- Each entry shows:
  - the last-entered part-number text;
  - when it was last searched, with an exact date/time available when a relative label such as `today` is used;
  - an action to remove that entry.
- A `Clear history` action is visible within the list.
- The list closes when the user chooses an entry, presses Escape, activates the explicit close action when one is shown, or interacts outside it.

Final Latvian wording remains in the app's centralized translation strings.

## 6. Repeating a Search

- Clicking or tapping a history entry immediately starts a normal search for that query; it does not merely copy the value into the field and require a second submission.
- With the keyboard, pressing Enter on the highlighted entry immediately starts the search. Pressing Tab on the highlighted entry instead copies the value into the search field without starting a search and continues normal keyboard focus movement.
- The chosen text is placed in the search field so the field and results describe the same active query.
- A repeated search follows all current search behavior: it clears result filters, supersedes any search already in progress, contacts the covered stores, and may require the existing human-check flow.
- History never presents stored results as current. Prices and availability come from the normal search flow and its ordinary cache/freshness rules.
- Repeating an entry moves it to the top and updates its last-searched time just like submitting the same value manually.

## 7. Removing History

- The user can remove one entry without starting it.
- Removing an entry takes effect immediately and does not require confirmation.
- `Clear history` requires confirmation because it removes every visible entry.
- Removing or clearing history does not alter current search results, the current search-field value, `Pirkumu plāns`, or store data.
- Clearing history removes all persisted search-history entries from both the shared backend history and the browser fallback. No separate analytics copy remains.
- Once removed, an entry returns only if the user searches for that part number again.

## 8. Persistence and Synchronization

- Search history is backend-persistent under the app's current single-user deployment model.
- It survives page reloads, browser restarts, application restarts, and switching between devices connected to the same app backend.
- The same shared history is available in the web, desktop, and Android surfaces.
- The browser keeps a local fallback copy for immediate startup and temporary server failures.
- When backend history is available, it is authoritative. Locally accepted searches and removals that have not yet synchronized are retained and retried rather than silently discarded.
- If history cannot be loaded, the search field and normal searching continue to work. Locally available history may still be shown.
- If a history change cannot be saved, the app gives a concise warning that history may differ on another device; it does not report the search itself as failed.
- Invalid or obsolete persisted entries are ignored without preventing valid entries from appearing.

## 9. Accessibility and Input Behavior

- The search field and history list have accessible names and expose expanded/collapsed state.
- The complete interaction is usable with a keyboard: open the list, move through entries, start a repeat search with Enter, prefill without searching with Tab, remove an entry, and close the list.
- Keyboard focus moves through the opened list predictably and returns to the search field when appropriate after the list closes.
- Removing one entry does not unexpectedly activate it.
- Browser-provided autocomplete is not treated as search history and must not conflict with the app-provided list.

## 10. Empty and Error States

- When history is empty, focusing the search field does not open an empty list; the initial search experience remains as it is today.
- If the user opens a list that becomes empty after removal, it shows a short empty message and offers no disabled or stale entries.
- A history loading or saving failure never blocks a new search.
- History entries remain usable when the backend is temporarily unavailable if a local copy exists.

## 11. Explicit Non-goals

The first version does not include:

1. Saved, pinned, named, or categorized searches.
2. Search-result snapshots or restoration of old prices and availability.
3. Price alerts, notifications, or scheduled reruns.
4. Search suggestions, popular searches, or recommendations from other users' activity.
5. Search-history filtering, sorting controls, pagination, export, or bulk selection.
6. Retaining per-search brand filters, stock filters, store challenge state, or page position.
7. Multiple-user ownership or access control. History follows the app's current single-user deployment model.

The main product specification's existing non-goal of `saved searches` continues to mean deliberately saved searches and alerts; passive recent search history is the feature defined here.

## 12. Acceptance Criteria

The feature is functionally complete when:

1. Submitting a valid part-number search creates a recent-history entry without changing normal search behavior.
2. Invalid input does not enter history, while valid zero-result and partially failed searches do.
3. Equivalent formatting of the same part number produces one entry, and repeating it moves it to the top with the latest entered formatting and time.
4. History is ordered by recency and never contains more than 20 distinct entries.
5. Focusing the empty search field opens history on web, desktop, and Android surfaces without losing the current results, with no separate history button.
6. Clicking, tapping, or pressing Enter on an entry immediately starts a normal current search and updates the search field; pressing Tab on a keyboard-highlighted entry only prefills the field.
7. The user can remove one entry and can clear all entries after confirmation.
8. Removing history does not change current results or `Pirkumu plāns`.
9. History survives reloads and app restarts and is shared between devices connected to the same backend, with a usable local fallback during temporary failures.
10. Loading or saving history failures do not prevent searching and are communicated without implying that the search itself failed.
11. The interaction is fully keyboard-operable and does not rely on browser autocomplete.
12. History stores no result snapshots and never presents old prices or availability as current.
13. No separate product-measurement record of searches, results, or outbound clicks remains, and clearing history leaves no retained analytics copy of its entries.

## 13. Approval Decisions

### 13.1 Resolved

1. History is shared through the single-user backend, with a browser fallback, rather than being private to one browser.
2. The limit is 20 distinct canonical part numbers.
3. Clicking, tapping, or pressing Enter on an entry immediately runs the search. Pressing Tab on a keyboard-highlighted entry only prefills the search field.
4. Valid zero-result, partial-failure, and connectivity-queued searches are retained because a search remains part of the user's history regardless of its outcome.
5. Individual removal is immediate; clearing all requires confirmation.
6. The separate product-measurement feature is removed. Clearing history therefore removes every retained search-history entry, with no analytics copy of the queries, store results, or outbound clicks.
7. History opens from deliberate focus of an empty search field; no separate history icon is used and the field is not automatically focused on page load.
