get_gotify_extras() previously only ever surfaced the *resolved* click_url,
never the action_code that produced it -- so the frontend had no way to
know which action_code a notification carried, and got nothing at all for
a code that hasn't been configured in NotificationLink yet. Now
action_code rides along under client::notification.action_code whenever
it's set, independent of whether it resolved to a click_url. Verified live
against a running Gotify container, both resolved and unresolved.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
`code` was ambiguous next to Python's own use of "code"; `action_code` names
its actual role (a click-action lookup key). click_object_id_value pairs it
consistently with action_code. Renamed on both PushMessage and
NotificationLink via a data-preserving RenameField migration, threaded
through the serializer, admin, bulk-push path, and docs.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reflects the switch from hard-coded FRONTEND_BASE_URL/utils.deep_links to
admin-managed NotificationLink rows: implementation.md documents the
resolution logic and the new migration, frontend-notification-click-actions.md
replaces the "confirm your URL scheme" ask with the actual code catalog
(now that the scheme itself is an admin panel concern, not something the
frontend team needs to weigh in on for us to ship), and
notification-click-actions.md gets a pointer at the top so it reads as the
historical first pass it now is, not the current mechanism.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Three docs for three audiences: service-overview.md for anyone integrating
with or operating the service, implementation.md for engineers maintaining
this codebase, and frontend-notification-click-actions.md as a self-contained
handoff for the client team to start building tap-to-navigate against — it
flags the click_url URL format as an unconfirmed placeholder needing their
input, and catalogs every notification type currently sending one.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Not every notification is clickable, so click_url is optional end to end
(null/blank on the model, required=False on the serializer). When set, it's
merged into Gotify's own client::notification.click.url extras convention
without disturbing any other extras a producer already sends, so official
Gotify clients can open it on tap. Wired through both message-creation
paths: the single-push REST API and the bulk Excel upload. Also fixes a
pre-existing NameError in the bulk path (json.loads(extras) referenced an
undefined name instead of extras_str).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>