Skip to content

Commit 0894cd2

Browse files
committed
Generalize notifier: drop "Called" + state-verb copy (rename-resistant)
Reverses the previous "Number → name" / "is ready" decision once it became clear that any state-verb baked into the substrate's notifier title or class name fights the agent's domain-adapt step. The agent extends/renames the AASM state machine per spec (idled/completed → e.g. waiting/seated for restaurant, pending/seen for vet clinic), but its rename plan only handles the four model-level tokens (Shop / Shopkeeper / ItemTag / NativeAppTemplate). State names cascading into notifier file/class/locale-key/title are out of scope for the rename-safety contract (#57). So the substrate's notifier ships state-verb-free: - File: item_tag_called_notifier.rb → item_tag_notifier.rb - Class: ItemTagCalledNotifier → ItemTagNotifier - Locale key: notifiers.item_tag_called → notifiers.item_tag - Title: "%{name} is ready" → "%{name}" - Body: "Please proceed to %{shop}." → "%{shop}" `ItemTag` itself IS in the rename plan, so file/class/locale-key cascade through `item_tag → patient/reservation/todo` cleanly. `%{name}` and `%{shop}` are interpolation keys, not renameable tokens. Result: substrate copy survives any state-verb rewrite the agent's adapt step does, at the cost of vague substrate copy. The adapt step can rewrite richer per-domain copy when it wants. Tests + rubocop clean.
1 parent 4907552 commit 0894cd2

4 files changed

Lines changed: 14 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
- Add push notifications scaffolding via `noticed` v2 (#58)
88
- New `Device` model + migration (UUID primary key, unique on `[platform, token]`, `last_active_at` for staleness scope)
99
- New `Api::V1::Shopkeeper::DevicesController` — POST `/devices` is idempotent upsert (rebinds token to current shopkeeper); DELETE `/devices/:id` unregisters
10-
- Add `ApplicationNotifier` base class + example `ItemTagCalledNotifier` with `deliver_by :action_push_native` wiring (Apple + Google push via Rails-native `action_push_native` 0.3.x)
10+
- Add `ApplicationNotifier` base class + example `ItemTagNotifier` with `deliver_by :action_push_native` wiring (Apple + Google push via Rails-native `action_push_native` 0.3.x)
1111
- Generate `ApplicationPushNotification` / `ApplicationPushDevice` / `ApplicationPushNotificationJob` and `config/push.yml` (APNs/FCM credentials still placeholders — provision via `bin/rails credentials:edit` before enabling delivery; ItemTag AASM trigger lands in a follow-up)
1212
- Note: the existing `Device` registration API (`POST /api/v1/shopkeeper/devices`) writes to the custom `Device` model, not `ApplicationPushDevice` — bridging the two (so registered tokens flow into Action Push Native delivery) is a follow-up
13-
- `Shopkeeper has_many :devices, :notifications`; new locale entries under `notifiers.item_tag_called`
13+
- `Shopkeeper has_many :devices, :notifications`; new locale entries under `notifiers.item_tag` — title/body deliberately kept generic (`%{name}` / `%{shop}` only, no state-verbs like "completed" or "ready") so the agent's domain-adapt step can rewrite richer per-domain copy without fighting baked-in queue semantics
1414
- 21 new test runs (Device model + DevicesController + notifier); full suite still 0 failures
1515

1616
## 2026-05-02
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
class ItemTagCalledNotifier < ApplicationNotifier
1+
class ItemTagNotifier < ApplicationNotifier
22
deliver_by :action_push_native do |config|
33
config.devices = -> { ApplicationPushDevice.where(owner: recipient) }
44
config.format = -> {
@@ -12,11 +12,11 @@ class ItemTagCalledNotifier < ApplicationNotifier
1212

1313
notification_methods do
1414
def title
15-
I18n.t("notifiers.item_tag_called.title", name: record.name)
15+
I18n.t("notifiers.item_tag.title", name: record.name)
1616
end
1717

1818
def body
19-
I18n.t("notifiers.item_tag_called.body", shop: record.shop.name)
19+
I18n.t("notifiers.item_tag.body", shop: record.shop.name)
2020
end
2121

2222
def url

config/locales/en.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ en:
4141
default_shop_description: "This is a sample shop.\nYou can update or remove this shop."
4242

4343
notifiers:
44-
item_tag_called:
45-
title: "%{name} is ready"
46-
body: "Please proceed to %{shop}."
44+
item_tag:
45+
title: "%{name}"
46+
body: "%{shop}"
4747

4848
api:
4949
shopkeeper:
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require "test_helper"
22

3-
class ItemTagCalledNotifierTest < ActiveSupport::TestCase
3+
class ItemTagNotifierTest < ActiveSupport::TestCase
44
setup do
55
@shopkeeper = shopkeepers(:one)
66
@shopkeeper.create_default_account
@@ -10,24 +10,24 @@ class ItemTagCalledNotifierTest < ActiveSupport::TestCase
1010

1111
test "delivering creates a Noticed::Event" do
1212
assert_difference -> { Noticed::Event.count }, 1 do
13-
ItemTagCalledNotifier.with(record: @item_tag).deliver(@shopkeeper)
13+
ItemTagNotifier.with(record: @item_tag).deliver(@shopkeeper)
1414
end
1515
end
1616

1717
test "delivering creates a Noticed::Notification for the recipient" do
1818
assert_difference -> { Noticed::Notification.count }, 1 do
19-
ItemTagCalledNotifier.with(record: @item_tag).deliver(@shopkeeper)
19+
ItemTagNotifier.with(record: @item_tag).deliver(@shopkeeper)
2020
end
2121
notification = @shopkeeper.notifications.last
2222
assert_not_nil notification
2323
assert_equal @item_tag, notification.record
2424
end
2525

2626
test "title and body resolve from i18n on the notification" do
27-
ItemTagCalledNotifier.with(record: @item_tag).deliver(@shopkeeper)
27+
ItemTagNotifier.with(record: @item_tag).deliver(@shopkeeper)
2828
notification = @shopkeeper.notifications.last
2929

30-
assert_equal I18n.t("notifiers.item_tag_called.title", name: @item_tag.name), notification.title
31-
assert_equal I18n.t("notifiers.item_tag_called.body", shop: @shop.name), notification.body
30+
assert_equal I18n.t("notifiers.item_tag.title", name: @item_tag.name), notification.title
31+
assert_equal I18n.t("notifiers.item_tag.body", shop: @shop.name), notification.body
3232
end
3333
end

0 commit comments

Comments
 (0)