Skip to content

Add Prototype Banner settings panel - #2644

Draft
yuechao-qin wants to merge 3 commits into
masterfrom
river-prototype-banner-panel
Draft

Add Prototype Banner settings panel#2644
yuechao-qin wants to merge 3 commits into
masterfrom
river-prototype-banner-panel

Conversation

@yuechao-qin

Copy link
Copy Markdown
Collaborator

Serves banner text from the backend instead of a frontend deploy, as a prototype: Settings → Prototype Banner saves a banner, shows the latest one, and lists the history.

Banners live in user settings under one key, system:web_ui/banners, as a newest-first list of {iso_timestamp: text}. No backend change and no migration — user_id is just a string column, so the namespace is the virtual user.

How it works

sequenceDiagram
    participant P as Prototype Banner panel
    participant H as usePrototypeBanners / useSavePrototypeBanner
    participant A as /api/users/me/settings

    P->>H: save("runs are delayed")
    H->>A: GET ?setting_names=system:web_ui/banners
    A-->>H: current list (object or JSON string)
    H->>H: parse, prepend {now: text}, sort newest-first
    H->>A: PATCH { settings: { "system:web_ui/banners": [...] } }
    H-->>P: new list → latest + history
Loading

Save is read-modify-write because the settings PATCH merges top-level keys only; a blind write would drop banners saved elsewhere. The stored value is parsed when it comes back as a JSON string, the same way tourCompletion.ts and onboardingProgress.ts do it.

Prototype scope

/api/users/me/settings keys the row by the authenticated caller, so a banner is visible only to the person who saved it. Making it global needs a server-pinned /api/system_settings route reading the same key for system:web_ui — no client change beyond the URL. The panel is intentionally ungated, so it shows for every user.

Original patch by River; tests and the JSON-string fix added on top.

shopify-river and others added 3 commits August 18, 2026 13:20
Banner content comes from the backend instead of a frontend deploy. Banners
are stored in user settings under the `system:web_ui/banners` key as a
newest-first list of `{iso_timestamp: banner_text}`.

Settings -> Prototype Banner (below AI Configuration) saves a new banner,
shows the latest one, and lists the full history. Writes go through
`PATCH /api/users/me/settings`, reads through `GET /api/users/me/settings`.

Prototype scope: `/api/users/me/settings` keys the row by the authenticated
caller, so a banner is visible only to the person who saved it. A
server-pinned route reading the same key for `system:web_ui` makes it global
without client changes beyond the URL.

Requested by Yue Chao Qin <yuechao.qin@shopify.com>

Co-authored-by: Yue Chao Qin <yuechao.qin@shopify.com>
Adds hook-level tests for the settings read/write (query params, both
payload shapes, read-modify-write) and panel tests for latest/history
rendering, save, error and refresh. Keys history rows by index too, since
two banners can share a timestamp.

Assisted-By: devx/18a6bbd2-5972-4e08-ad51-c91f9713b20c
The settings endpoint can hand a value back as a JSON string; the tour and
onboarding readers already parse before validating. Without it the panel
shows no history and, worse, the read-modify-write save overwrites the
whole history with a single entry.

Assisted-By: devx/18a6bbd2-5972-4e08-ad51-c91f9713b20c
@github-actions

Copy link
Copy Markdown

🎩 Preview

A preview build has been created at: river-prototype-banner-panel/ea76489

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants