side-notes/openspec/specs/notes-storage/spec.md

3.4 KiB

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