side-notes/openspec/changes/add-notes-extension/specs/notes-storage/spec.md

51 lines
3.4 KiB
Markdown

## Purpose
Persists exactly one markdown note per page, keyed by a normalized form of the page's URL, in local storage that survives restarts and is shaped to support multi-device sync in a future change.
## ADDED Requirements
### Requirement: Note identified by normalized URL key
The system SHALL derive a storage key for a page from its URL using a normalization rule that, by default, includes the scheme, domain, path, and query string, and excludes the fragment/hash.
#### Scenario: Two URLs differing only by hash resolve to the same note
- **WHEN** a user visits `https://example.com/article#section1` and later `https://example.com/article#section2`
- **THEN** both pages resolve to the same note key and show the same note content
#### Scenario: Two URLs differing by query string resolve to different notes
- **WHEN** a user visits `https://example.com/search?q=cats` and `https://example.com/search?q=dogs`
- **THEN** each URL resolves to a distinct note key with independent content
### Requirement: Key derivation rule is configurable
The system SHALL allow the URL normalization rule used for key derivation to be changed at the code level, without requiring a UI for end users in this change.
#### Scenario: Key builder is swapped
- **WHEN** a developer changes the configured key-derivation rule (e.g., to include the hash)
- **THEN** notes saved after the change use keys produced by the new rule
### Requirement: In-page navigation is detected
The system SHALL detect URL changes that occur without a full page load within a tab (e.g., History API `pushState`/`replaceState` navigation used by single-page applications) and re-resolve the note key for that tab accordingly.
#### Scenario: In-page navigation changes the resolved note
- **WHEN** a single-page application changes the browser URL via the History API without a full page load
- **THEN** the note associated with the new URL is resolved for that tab without requiring a manual reload
### Requirement: Note content persists across restarts
The system SHALL persist each note's content in local storage that survives browser restarts and computer restarts, without requiring network access.
#### Scenario: Note survives a browser restart
- **WHEN** a user writes content in a note and later restarts the browser
- **THEN** reopening the side panel on the same page shows the previously written content
### Requirement: Note record data model
Each stored note record SHALL include: a stable unique identifier, the derived URL key, the page title and favicon URL captured at save time, the markdown content, a creation timestamp, a last-updated timestamp, and an optional deletion timestamp.
#### Scenario: Metadata captured on first save
- **WHEN** a user's edits to a page's note are saved for the first time
- **THEN** the stored record includes a unique id, the derived key, the page's title, its favicon URL, the content, and matching creation and last-updated timestamps
### Requirement: Soft deletion is honored by retrieval
A note record marked with a deletion timestamp SHALL be excluded from normal retrieval (opening a note for a page) and from any listing of notes, while remaining present in storage.
#### Scenario: Deleted note is hidden but not erased
- **WHEN** a note record has a deletion timestamp set
- **THEN** it is not returned when its page's note is requested or when notes are listed, and its record still exists in storage