# notes-storage Specification ## 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. ## 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