diff --git a/AGENTS.md b/AGENTS.md index 8b1027c..7dae5f1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -103,7 +103,7 @@ Cross-platform push via the `noticed` (v3) and `action_push_native` gems. APNs f - `json_response` for parsing JSON API responses - `create_new_auth_token` for generating auth headers (Devise Token Auth) - Fixtures in test/fixtures/ and seed data in db/fixtures/test/ -- Run tests: `bin/rails test` (583 tests, 1454 assertions) +- Run tests: `bin/rails test` (584 tests, 1458 assertions) ### Internationalization - Responses are in English (default) or Japanese, picked by the `SetLocale` concern (included in `ApplicationController` and `NonApiApplicationController`). It wraps `process_action`, not `around_action`, so `rescue_from` handlers and `rate_limit` responses are localized too. diff --git a/CHANGELOG.md b/CHANGELOG.md index 782d24f..b2a964a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [Unreleased] +- Call a shop 店舗 rather than ショップ in the Japanese messages (model name, item tag's shop attribute, the shop limit error, the sample shop description), matching 店舗名 - API change: add a Japanese locale. A signed-in shopkeeper gets the language in `shopkeepers.locale`, which sign-up now sets from a `locale` param (falling back to `Accept-Language`) and `PATCH /shopkeeper_auth` can change (`en` or `ja`, else 422). Other requests follow the `Accept-Language` header (English by default) via the new `SetLocale` concern. Mails to a shopkeeper use their `locale`; an invitation to an email with no account uses the inviter's. Translations are in `config/locales/ja.yml`, `rails.ja.yml` and `devise.ja.yml`, with no extra gems. Hard-coded English in the error pages, `ErrorsController`, the sample item tag and the mail greetings moved to locale keys. `test/i18n/locale_files_test.rb` fails on any untranslated key. Two English messages changed: an unknown `current_platform` now gets the same "Your input data is wrong." as a blank one, and a duplicate member gets "User is already a member of this organization" instead of "has already been taken". Fix `PATCH /shopkeeper_auth` returning 422 unless `email` was sent: devise_token_auth checked the params before `name`, `time_zone` and `locale` were permitted (#150) - Fix a failed sign-in saving the `source` header as `current_platform`: anyone knowing an email could set it to any string, after which that shopkeeper's profile updates returned 422. Only successful sign-ins write it, and only `ios` or `android`. Fix resending an invitation whose inviter was deleted (the mail job raised on `nil.name`); the mail names the app instead. Rename `.erb-lint.yml` to `.erb_lint.yml` and drop a removed RuboCop cop from `.rubocop.yml` (#149) - Deploy with Kamal 2 to GitHub Container Registry instead of Render: add `Dockerfile`, `.dockerignore`, `config/deploy.yml` (kamal-proxy serving a Cloudflare Origin Certificate with `forward_headers: true` and `ssl_redirect: false`, Postgres 18 as the `db` accessory on the private Docker network, Solid Queue in Puma, Active Storage volume, amd64 builder), `.kamal/secrets`, `bin/kamal` and `bin/thrust`. Add the missing `GET /up` health check route and `assume_ssl = true` so kamal-proxy's health check passes. Add Cloudflare's ranges to `trusted_proxies` (`config/cloudflare_ips.yml`) so `rate_limit` keys on the caller rather than the edge. Remove `render.yaml`, `bin/render-*.sh` and the staging environment, which only served Render PR previews. New tests: `test/config/deploy_config_test.rb`, `test/integration/health_check_test.rb`, `test/integration/trusted_proxies_test.rb` (#144) diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 59128d5..ff7d193 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -20,7 +20,7 @@ ja: something_went_wrong: "問題が発生しました。" internal_server_error: "サーバーでエラーが発生しました。" unauthorized: "この操作を行う権限がありません。" - default_shop_description: "これはサンプルのショップです。\n編集や削除ができます。" + default_shop_description: "これはサンプルの店舗です。\n編集や削除ができます。" sample_item_tag: name: "サンプル" @@ -121,7 +121,7 @@ ja: accounts_shopkeeper: "メンバー" application_push_device: "デバイス" item_tag: "アイテムタグ" - shop: "ショップ" + shop: "店舗" shopkeeper: "ユーザー" attributes: @@ -150,7 +150,7 @@ ja: name: "名前" description: "説明" position: "表示順" - shop: "ショップ" + shop: "店舗" shop: created_by: "作成者" description: "説明" @@ -204,7 +204,7 @@ ja: validate_sign_up_params: "リクエストボディに正しい新規登録データを指定してください。" validate_account_update_params: "リクエストボディに正しいアカウント更新データを指定してください。" limit_count_account: "組織は%{limit_count}件まで作成できます。" - limit_count_shop: "ショップはすべての組織で合わせて%{limit_count}件まで作成できます。" + limit_count_shop: "店舗はすべての組織で合わせて%{limit_count}件まで作成できます。" limit_count_accounts_shopkeeper: "組織のメンバーは%{limit_count}人まで追加できます。組織の管理者またはオーナーにお問い合わせください。" limit_count_item_tag: "アイテムタグは%{limit_count}件まで作成できます。" too_many_signups: "新規登録の試行回数が多すぎます。しばらくしてからもう一度お試しください。" diff --git a/test/i18n/japanese_messages_test.rb b/test/i18n/japanese_messages_test.rb index 5ed7049..8204845 100644 --- a/test/i18n/japanese_messages_test.rb +++ b/test/i18n/japanese_messages_test.rb @@ -54,4 +54,14 @@ def ja(&) = I18n.with_locale(:ja, &) ja { invitation.valid? } assert_equal ["権限を選択してください"], ja { invitation.errors.full_messages_for(:roles) } end + + # The shop's name attribute is 店舗名, so the model and the messages that + # name a shop say 店舗 too, as in MyTurnTag + test "a shop is called 店舗, never ショップ" do + ja_values = I18n.backend.send(:translations).fetch(:ja).to_s + assert_not_includes ja_values, "ショップ" + assert_equal "店舗", I18n.t("activerecord.models.shop", locale: :ja) + assert_equal "店舗はすべての組織で合わせて3件まで作成できます。", + I18n.t("errors.messages.limit_count_shop", limit_count: 3, locale: :ja) + end end