jp_address_complement 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. checksums.yaml +7 -0
  2. data/.agent/rules/specify-rules.md +29 -0
  3. data/.agent/workflows/speckit.analyze.md +184 -0
  4. data/.agent/workflows/speckit.checklist.md +294 -0
  5. data/.agent/workflows/speckit.clarify.md +181 -0
  6. data/.agent/workflows/speckit.constitution.md +84 -0
  7. data/.agent/workflows/speckit.implement.md +135 -0
  8. data/.agent/workflows/speckit.plan.md +90 -0
  9. data/.agent/workflows/speckit.specify.md +258 -0
  10. data/.agent/workflows/speckit.tasks.md +137 -0
  11. data/.agent/workflows/speckit.taskstoissues.md +30 -0
  12. data/.claude/commands/speckit.analyze.md +184 -0
  13. data/.claude/commands/speckit.checklist.md +294 -0
  14. data/.claude/commands/speckit.clarify.md +181 -0
  15. data/.claude/commands/speckit.constitution.md +84 -0
  16. data/.claude/commands/speckit.implement.md +135 -0
  17. data/.claude/commands/speckit.plan.md +90 -0
  18. data/.claude/commands/speckit.specify.md +258 -0
  19. data/.claude/commands/speckit.tasks.md +137 -0
  20. data/.claude/commands/speckit.taskstoissues.md +30 -0
  21. data/.cursor/commands/speckit.analyze.md +184 -0
  22. data/.cursor/commands/speckit.checklist.md +294 -0
  23. data/.cursor/commands/speckit.clarify.md +181 -0
  24. data/.cursor/commands/speckit.constitution.md +84 -0
  25. data/.cursor/commands/speckit.implement.md +135 -0
  26. data/.cursor/commands/speckit.plan.md +90 -0
  27. data/.cursor/commands/speckit.specify.md +258 -0
  28. data/.cursor/commands/speckit.tasks.md +137 -0
  29. data/.cursor/commands/speckit.taskstoissues.md +30 -0
  30. data/.cursor/rules/specify-rules.mdc +32 -0
  31. data/.rubocop.yml +118 -0
  32. data/.specify/memory/constitution.md +130 -0
  33. data/.specify/scripts/bash/check-prerequisites.sh +166 -0
  34. data/.specify/scripts/bash/common.sh +156 -0
  35. data/.specify/scripts/bash/create-new-feature.sh +297 -0
  36. data/.specify/scripts/bash/setup-plan.sh +61 -0
  37. data/.specify/scripts/bash/update-agent-context.sh +810 -0
  38. data/.specify/templates/agent-file-template.md +28 -0
  39. data/.specify/templates/checklist-template.md +40 -0
  40. data/.specify/templates/constitution-template.md +50 -0
  41. data/.specify/templates/plan-template.md +104 -0
  42. data/.specify/templates/spec-template.md +115 -0
  43. data/.specify/templates/tasks-template.md +251 -0
  44. data/CHANGELOG.md +26 -0
  45. data/LICENSE +9 -0
  46. data/README.md +274 -0
  47. data/Rakefile +19 -0
  48. data/Steepfile +9 -0
  49. data/examples/rails/jp_address_complement_demo/.gitignore +15 -0
  50. data/examples/rails/jp_address_complement_demo/.ruby-version +1 -0
  51. data/examples/rails/jp_address_complement_demo/Gemfile +22 -0
  52. data/examples/rails/jp_address_complement_demo/Gemfile.lock +252 -0
  53. data/examples/rails/jp_address_complement_demo/README.md +57 -0
  54. data/examples/rails/jp_address_complement_demo/Rakefile +6 -0
  55. data/examples/rails/jp_address_complement_demo/app/assets/images/.keep +0 -0
  56. data/examples/rails/jp_address_complement_demo/app/assets/stylesheets/application.css +1 -0
  57. data/examples/rails/jp_address_complement_demo/app/controllers/addresses_controller.rb +59 -0
  58. data/examples/rails/jp_address_complement_demo/app/controllers/application_controller.rb +4 -0
  59. data/examples/rails/jp_address_complement_demo/app/controllers/concerns/.keep +0 -0
  60. data/examples/rails/jp_address_complement_demo/app/helpers/application_helper.rb +2 -0
  61. data/examples/rails/jp_address_complement_demo/app/models/application_record.rb +3 -0
  62. data/examples/rails/jp_address_complement_demo/app/models/concerns/.keep +0 -0
  63. data/examples/rails/jp_address_complement_demo/app/views/addresses/index.html.erb +22 -0
  64. data/examples/rails/jp_address_complement_demo/app/views/addresses/prefecture.html.erb +20 -0
  65. data/examples/rails/jp_address_complement_demo/app/views/addresses/prefix.html.erb +25 -0
  66. data/examples/rails/jp_address_complement_demo/app/views/addresses/reverse.html.erb +30 -0
  67. data/examples/rails/jp_address_complement_demo/app/views/addresses/validate.html.erb +23 -0
  68. data/examples/rails/jp_address_complement_demo/app/views/layouts/application.html.erb +40 -0
  69. data/examples/rails/jp_address_complement_demo/app/views/pwa/manifest.json.erb +22 -0
  70. data/examples/rails/jp_address_complement_demo/app/views/pwa/service-worker.js +26 -0
  71. data/examples/rails/jp_address_complement_demo/bin/ci +6 -0
  72. data/examples/rails/jp_address_complement_demo/bin/dev +2 -0
  73. data/examples/rails/jp_address_complement_demo/bin/rails +4 -0
  74. data/examples/rails/jp_address_complement_demo/bin/rake +4 -0
  75. data/examples/rails/jp_address_complement_demo/bin/setup +35 -0
  76. data/examples/rails/jp_address_complement_demo/config/application.rb +42 -0
  77. data/examples/rails/jp_address_complement_demo/config/boot.rb +3 -0
  78. data/examples/rails/jp_address_complement_demo/config/ci.rb +15 -0
  79. data/examples/rails/jp_address_complement_demo/config/credentials.yml.enc +1 -0
  80. data/examples/rails/jp_address_complement_demo/config/database.yml +31 -0
  81. data/examples/rails/jp_address_complement_demo/config/environment.rb +5 -0
  82. data/examples/rails/jp_address_complement_demo/config/environments/development.rb +54 -0
  83. data/examples/rails/jp_address_complement_demo/config/environments/production.rb +67 -0
  84. data/examples/rails/jp_address_complement_demo/config/environments/test.rb +42 -0
  85. data/examples/rails/jp_address_complement_demo/config/initializers/content_security_policy.rb +29 -0
  86. data/examples/rails/jp_address_complement_demo/config/initializers/filter_parameter_logging.rb +8 -0
  87. data/examples/rails/jp_address_complement_demo/config/initializers/inflections.rb +16 -0
  88. data/examples/rails/jp_address_complement_demo/config/locales/en.yml +31 -0
  89. data/examples/rails/jp_address_complement_demo/config/puma.rb +39 -0
  90. data/examples/rails/jp_address_complement_demo/config/routes.rb +19 -0
  91. data/examples/rails/jp_address_complement_demo/config.ru +6 -0
  92. data/examples/rails/jp_address_complement_demo/db/migrate/20260228083709_create_jp_address_complement_postal_codes.rb +44 -0
  93. data/examples/rails/jp_address_complement_demo/db/schema.rb +33 -0
  94. data/examples/rails/jp_address_complement_demo/db/seeds.rb +24 -0
  95. data/examples/rails/jp_address_complement_demo/lib/tasks/.keep +0 -0
  96. data/examples/rails/jp_address_complement_demo/log/.keep +0 -0
  97. data/examples/rails/jp_address_complement_demo/public/400.html +135 -0
  98. data/examples/rails/jp_address_complement_demo/public/404.html +135 -0
  99. data/examples/rails/jp_address_complement_demo/public/406-unsupported-browser.html +135 -0
  100. data/examples/rails/jp_address_complement_demo/public/422.html +135 -0
  101. data/examples/rails/jp_address_complement_demo/public/500.html +135 -0
  102. data/examples/rails/jp_address_complement_demo/public/icon.png +0 -0
  103. data/examples/rails/jp_address_complement_demo/public/icon.svg +3 -0
  104. data/examples/rails/jp_address_complement_demo/public/robots.txt +1 -0
  105. data/examples/rails/jp_address_complement_demo/script/.keep +0 -0
  106. data/examples/rails/jp_address_complement_demo/storage/.keep +0 -0
  107. data/examples/rails/jp_address_complement_demo/vendor/.keep +0 -0
  108. data/lib/generators/jp_address_complement/install_generator.rb +34 -0
  109. data/lib/generators/jp_address_complement/templates/create_jp_address_complement_postal_codes.rb.erb +45 -0
  110. data/lib/jp_address_complement/address_record.rb +36 -0
  111. data/lib/jp_address_complement/configuration.rb +21 -0
  112. data/lib/jp_address_complement/importers/csv_importer.rb +148 -0
  113. data/lib/jp_address_complement/ken_all_downloader.rb +122 -0
  114. data/lib/jp_address_complement/models/postal_code.rb +21 -0
  115. data/lib/jp_address_complement/normalizer.rb +77 -0
  116. data/lib/jp_address_complement/prefecture.rb +105 -0
  117. data/lib/jp_address_complement/railtie.rb +27 -0
  118. data/lib/jp_address_complement/repositories/active_record_postal_code_repository.rb +78 -0
  119. data/lib/jp_address_complement/repositories/csv_postal_code_repository.rb +200 -0
  120. data/lib/jp_address_complement/repositories/postal_code_repository.rb +36 -0
  121. data/lib/jp_address_complement/searcher.rb +85 -0
  122. data/lib/jp_address_complement/validators/address_validator.rb +41 -0
  123. data/lib/jp_address_complement/version.rb +6 -0
  124. data/lib/jp_address_complement.rb +129 -0
  125. data/lib/tasks/jp_address_complement.rake +32 -0
  126. data/rbs_collection.lock.yaml +380 -0
  127. data/rbs_collection.yaml +19 -0
  128. data/sig/generated/generators/jp_address_complement/install_generator.rbs +18 -0
  129. data/sig/generated/jp_address_complement/configuration.rbs +18 -0
  130. data/sig/generated/jp_address_complement/importers/csv_importer.rbs +78 -0
  131. data/sig/generated/jp_address_complement/ken_all_downloader.rbs +49 -0
  132. data/sig/generated/jp_address_complement/normalizer.rbs +37 -0
  133. data/sig/generated/jp_address_complement/prefecture.rbs +27 -0
  134. data/sig/generated/jp_address_complement/railtie.rbs +8 -0
  135. data/sig/generated/jp_address_complement/repositories/active_record_postal_code_repository.rbs +38 -0
  136. data/sig/generated/jp_address_complement/repositories/csv_postal_code_repository.rbs +100 -0
  137. data/sig/generated/jp_address_complement/repositories/postal_code_repository.rbs +29 -0
  138. data/sig/generated/jp_address_complement/searcher.rbs +43 -0
  139. data/sig/generated/jp_address_complement/validators/address_validator.rbs +24 -0
  140. data/sig/generated/jp_address_complement/version.rbs +5 -0
  141. data/sig/generated/jp_address_complement.rbs +84 -0
  142. data/sig/manual/address_record.rbs +40 -0
  143. data/sig/manual/gem_rubyzip.rbs +17 -0
  144. data/sig/manual/postal_code.rbs +9 -0
  145. data/sig/manual/stdlib_csv_invalid_encoding_error.rbs +5 -0
  146. data/sig/manual/stdlib_net_http.rbs +33 -0
  147. data/sig/manual/stdlib_openuri.rbs +9 -0
  148. data/sig/manual/stdlib_tmpdir.rbs +4 -0
  149. data/specs/001-jp-address-complement-gem/checklists/requirements.md +36 -0
  150. data/specs/001-jp-address-complement-gem/contracts/public-api.md +209 -0
  151. data/specs/001-jp-address-complement-gem/data-model.md +207 -0
  152. data/specs/001-jp-address-complement-gem/plan.md +124 -0
  153. data/specs/001-jp-address-complement-gem/quickstart.md +151 -0
  154. data/specs/001-jp-address-complement-gem/research.md +139 -0
  155. data/specs/001-jp-address-complement-gem/spec.md +153 -0
  156. data/specs/001-jp-address-complement-gem/tasks.md +279 -0
  157. data/specs/002-rbs-type-annotations/checklists/requirements.md +37 -0
  158. data/specs/002-rbs-type-annotations/contracts/rbs-public-api.md +116 -0
  159. data/specs/002-rbs-type-annotations/data-model.md +119 -0
  160. data/specs/002-rbs-type-annotations/plan.md +116 -0
  161. data/specs/002-rbs-type-annotations/quickstart.md +105 -0
  162. data/specs/002-rbs-type-annotations/research.md +173 -0
  163. data/specs/002-rbs-type-annotations/spec.md +125 -0
  164. data/specs/002-rbs-type-annotations/tasks.md +189 -0
  165. data/specs/003-csv-remove-obsolete/checklists/requirements.md +34 -0
  166. data/specs/003-csv-remove-obsolete/contracts/csv-import.md +41 -0
  167. data/specs/003-csv-remove-obsolete/data-model.md +47 -0
  168. data/specs/003-csv-remove-obsolete/plan.md +73 -0
  169. data/specs/003-csv-remove-obsolete/quickstart.md +40 -0
  170. data/specs/003-csv-remove-obsolete/research.md +71 -0
  171. data/specs/003-csv-remove-obsolete/spec.md +85 -0
  172. data/specs/003-csv-remove-obsolete/tasks.md +167 -0
  173. data/specs/004-prefecture-code-reverse-lookup/checklists/requirements.md +34 -0
  174. data/specs/004-prefecture-code-reverse-lookup/contracts/public-api-prefecture-and-reverse.md +122 -0
  175. data/specs/004-prefecture-code-reverse-lookup/data-model.md +81 -0
  176. data/specs/004-prefecture-code-reverse-lookup/plan.md +92 -0
  177. data/specs/004-prefecture-code-reverse-lookup/quickstart.md +91 -0
  178. data/specs/004-prefecture-code-reverse-lookup/research.md +62 -0
  179. data/specs/004-prefecture-code-reverse-lookup/spec.md +120 -0
  180. data/specs/004-prefecture-code-reverse-lookup/tasks.md +190 -0
  181. metadata +451 -0
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require_relative 'normalizer'
5
+ require_relative 'repositories/postal_code_repository'
6
+
7
+ module JpAddressComplement
8
+ # コア検索ロジック
9
+ # Repository を注入して使用することで ActiveRecord への直接依存を排除する
10
+ class Searcher
11
+ # @rbs (Repositories::PostalCodeRepository repository) -> void
12
+ def initialize(repository)
13
+ @repository = repository
14
+ end
15
+
16
+ # 7桁郵便番号から住所レコードを検索する
17
+ # @rbs (String? code) -> Array[AddressRecord]
18
+ # @param code [String, nil] 郵便番号
19
+ # @return [Array<AddressRecord>]
20
+ def search_by_postal_code(code)
21
+ normalized = Normalizer.normalize_postal_code(code)
22
+ return [] if normalized.nil?
23
+
24
+ @repository.find_by_code(normalized)
25
+ end
26
+
27
+ # 郵便番号プレフィックスから住所候補を検索する(4桁以上)
28
+ # @rbs (String? prefix) -> Array[AddressRecord]
29
+ # @param prefix [String, nil] 郵便番号の先頭部分
30
+ # @return [Array<AddressRecord>]
31
+ def search_by_postal_code_prefix(prefix)
32
+ normalized = Normalizer.normalize_prefix(prefix)
33
+ return [] if normalized.nil?
34
+
35
+ @repository.find_by_prefix(normalized)
36
+ end
37
+
38
+ # 郵便番号と住所文字列の整合性を検証する
39
+ # 日本郵便の utf_ken_all.csv は町域に「字」「大字」を含まないため、
40
+ # 市区町村の直後に「字」「大字」が付いた住所(省略可能な表記)も一致とみなす。
41
+ # @rbs (String? postal_code, String? address) -> bool
42
+ # @param postal_code [String, nil] 郵便番号
43
+ # @param address [String, nil] 住所文字列
44
+ # @return [Boolean]
45
+ def valid_combination?(postal_code, address)
46
+ return false if postal_code.nil? || address.nil?
47
+
48
+ normalized = Normalizer.normalize_postal_code(postal_code)
49
+ return false if normalized.nil?
50
+
51
+ records = @repository.find_by_code(normalized)
52
+ return false if records.empty?
53
+
54
+ records.any? { |record| address_matches_record?(address, record) }
55
+ end
56
+
57
+ # 都道府県・市区町村・町域から郵便番号候補を取得する(逆引き)。町域は前方一致。
58
+ # @rbs (pref: String?, city: String?, ?town: String?) -> Array[[String, AddressRecord]]
59
+ # @param pref [String] 都道府県名(正式名称)
60
+ # @param city [String] 市区町村名
61
+ # @param town [String, nil] 町域名。省略時は都道府県+市区町村のみ。指定時は前方一致で候補を返す
62
+ # @return [Array<[String, AddressRecord]>] [郵便番号, AddressRecord] の配列。該当なし・入力不十分時は []
63
+ def search_postal_codes_by_address(pref:, city:, town: nil)
64
+ return [] if pref.nil? || pref.to_s.strip.empty?
65
+ return [] if city.nil? || city.to_s.strip.empty?
66
+
67
+ records = @repository.find_postal_codes_by_address(pref: pref, city: city, town: town)
68
+ records.map { |r| [r.postal_code, r] }
69
+ end
70
+
71
+ private
72
+
73
+ def address_matches_record?(address, record)
74
+ base = record.pref + record.city
75
+ town_part = record.normalized_town.to_s
76
+ full = base + town_part
77
+
78
+ return true if address.include?(full)
79
+ return false if town_part.empty?
80
+
81
+ # 日本郵便の CSV は町域に「字」「大字」を含まない。市区町村の直後に「字」「大字」が付いた表記は省略可能なため無視する。
82
+ address.include?("#{base}大字#{town_part}") || address.include?("#{base}字#{town_part}")
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require 'active_model'
5
+
6
+ module JpAddressComplement
7
+ # ActiveModel::Validator を継承した郵便番号・住所整合性バリデーター
8
+ #
9
+ # @example
10
+ # class User
11
+ # include ActiveModel::Validations
12
+ # validates_with JpAddressComplement::AddressValidator,
13
+ # postal_code_field: :postal_code,
14
+ # address_field: :full_address
15
+ # end
16
+ # @rbs inherits ActiveModel::Validator
17
+ class AddressValidator < ActiveModel::Validator
18
+ # @rbs (untyped record) -> void
19
+ def validate(record)
20
+ postal_code = record.public_send(postal_code_field)
21
+ address = record.public_send(address_field)
22
+
23
+ return if postal_code.blank? || address.blank?
24
+
25
+ return if JpAddressComplement.valid_combination?(postal_code, address)
26
+
27
+ record.errors.add(address_field, :invalid_combination,
28
+ message: 'と郵便番号の組み合わせが正しくありません')
29
+ end
30
+
31
+ private
32
+
33
+ def postal_code_field
34
+ options.fetch(:postal_code_field, :postal_code)
35
+ end
36
+
37
+ def address_field
38
+ options.fetch(:address_field, :address)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ module JpAddressComplement
5
+ VERSION = '0.1.0' #: String
6
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require_relative 'jp_address_complement/version'
5
+ require_relative 'jp_address_complement/address_record'
6
+ require_relative 'jp_address_complement/normalizer'
7
+ require_relative 'jp_address_complement/configuration'
8
+ require_relative 'jp_address_complement/repositories/postal_code_repository'
9
+ require_relative 'jp_address_complement/searcher'
10
+ require_relative 'jp_address_complement/prefecture'
11
+
12
+ # Rails 環境でのみ Railtie をロード
13
+ require_relative 'jp_address_complement/railtie' if defined?(Rails)
14
+
15
+ module JpAddressComplement
16
+ class Error < StandardError; end
17
+ class ImportError < Error; end
18
+
19
+ class << self
20
+ # Gem の設定を行う
21
+ # @rbs () { (Configuration) -> void } -> void
22
+ # @yield [Configuration]
23
+ def configure
24
+ yield(configuration)
25
+ end
26
+
27
+ # 現在の設定を返す
28
+ # @rbs () -> Configuration
29
+ # @return [Configuration]
30
+ def configuration
31
+ @configuration ||= Configuration.new
32
+ end
33
+
34
+ # PostalCode モデルの継承元。未設定時は ActiveRecord::Base。configuration.postal_code_model_base に委譲する。
35
+ # @rbs () -> Class
36
+ def base_record_class
37
+ configuration.postal_code_model_base || ActiveRecord::Base
38
+ end
39
+
40
+ # @rbs (Class) -> void
41
+ def base_record_class=(klass)
42
+ configuration.postal_code_model_base = klass
43
+ end
44
+
45
+ # PostalCode が参照するテーブル名。未設定時は 'jp_address_complement_postal_codes'。configuration.postal_code_table_name に委譲。
46
+ # @rbs () -> String
47
+ def postal_code_table_name
48
+ configuration.postal_code_table_name || 'jp_address_complement_postal_codes'
49
+ end
50
+
51
+ # @rbs (String) -> void
52
+ def postal_code_table_name=(name)
53
+ configuration.postal_code_table_name = name
54
+ end
55
+
56
+ # 設定をリセットする(主にテスト用)
57
+ # @rbs () -> void
58
+ def reset_configuration!
59
+ @configuration = Configuration.new
60
+ end
61
+
62
+ # 設定されたリポジトリを返す(デフォルトは ActiveRecord 実装)
63
+ # @rbs () -> Repositories::PostalCodeRepository
64
+ # @return [Repositories::PostalCodeRepository]
65
+ def repository
66
+ configuration.repository ||= default_repository
67
+ end
68
+
69
+ # 7桁郵便番号から住所レコードを検索する
70
+ # @rbs (String) -> Array[AddressRecord]
71
+ # @param code [String] 郵便番号(ハイフン・全角・〒 記号を自動正規化)
72
+ # @return [Array<AddressRecord>]
73
+ def search_by_postal_code(code)
74
+ Searcher.new(repository).search_by_postal_code(code)
75
+ end
76
+
77
+ # 郵便番号の先頭4桁以上から住所候補を検索する
78
+ # @rbs (String) -> Array[AddressRecord]
79
+ # @param prefix [String] 郵便番号の先頭部分(4桁以上)
80
+ # @return [Array<AddressRecord>]
81
+ def search_by_postal_code_prefix(prefix)
82
+ Searcher.new(repository).search_by_postal_code_prefix(prefix)
83
+ end
84
+
85
+ # 郵便番号と住所文字列の整合性を検証する
86
+ # @rbs (String, String) -> bool
87
+ # @param postal_code [String] 郵便番号(自動正規化)
88
+ # @param address [String] 住所文字列
89
+ # @return [Boolean]
90
+ def valid_combination?(postal_code, address)
91
+ Searcher.new(repository).valid_combination?(postal_code, address)
92
+ end
93
+
94
+ # 都道府県コード(JIS X 0401)から都道府県名を返す
95
+ # @rbs (String | Integer?) -> String?
96
+ # @param code [String, Integer, nil] 都道府県コード(01–47)
97
+ # @return [String, nil] 都道府県名。該当なし時は nil
98
+ def prefecture_name_from_code(code)
99
+ Prefecture.name_from_code(code)
100
+ end
101
+
102
+ # 都道府県名(正式名称)から都道府県コードを2桁文字列で返す
103
+ # @rbs (String?) -> String?
104
+ # @param name [String, nil] 都道府県の正式名称
105
+ # @return [String, nil] 2桁のコード(例: "13")。該当なし時は nil
106
+ def prefecture_code_from_name(name)
107
+ Prefecture.code_from_name(name)
108
+ end
109
+
110
+ # 都道府県・市区町村・町域から郵便番号候補を取得する(逆引き)。町域は前方一致。
111
+ # @rbs (pref: String?, city: String?, ?town: String?) -> Array[[String, AddressRecord]]
112
+ # @param pref [String] 都道府県名(正式名称)
113
+ # @param city [String] 市区町村名
114
+ # @param town [String, nil] 町域名。省略可。指定時は前方一致で候補を返す
115
+ # @return [Array<[String, AddressRecord]>] [郵便番号, AddressRecord] の配列。該当なし・入力不十分時は []
116
+ def search_postal_codes_by_address(pref:, city:, town: nil)
117
+ Searcher.new(repository).search_postal_codes_by_address(pref: pref, city: city, town: town)
118
+ end
119
+
120
+ private
121
+
122
+ # @rbs () -> Repositories::ActiveRecordPostalCodeRepository
123
+ def default_repository
124
+ require_relative 'jp_address_complement/repositories/active_record_postal_code_repository'
125
+ require_relative 'jp_address_complement/models/postal_code'
126
+ Repositories::ActiveRecordPostalCodeRepository.new
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jp_address_complement'
4
+ require 'jp_address_complement/importers/csv_importer'
5
+
6
+ namespace :jp_address_complement do
7
+ desc 'KEN_ALL.CSV から住所データをインポートする(CSV=<ファイルパス> または DOWNLOAD=1 で公式URLから取得)'
8
+ task import: :environment do
9
+ csv_path = resolve_csv_path_for_import
10
+
11
+ puts "インポート開始: #{csv_path}"
12
+ result = JpAddressComplement::Importers::CsvImporter.new(csv_path).import
13
+ puts "インポート完了: upsert #{result.upserted} 件, 削除 #{result.deleted} 件"
14
+ end
15
+ end
16
+
17
+ def resolve_csv_path_for_import
18
+ if ENV['DOWNLOAD'] == '1'
19
+ require 'jp_address_complement/ken_all_downloader'
20
+ url = ENV.fetch('KEN_ALL_ZIP_URL', JpAddressComplement::KenAllDownloader::DEFAULT_URL)
21
+ puts "ダウンロード中: #{url}"
22
+ JpAddressComplement::KenAllDownloader.new(url).download_and_extract
23
+ else
24
+ csv_path = ENV.fetch('CSV', nil)
25
+ if csv_path.nil?
26
+ raise ArgumentError,
27
+ 'CSV 環境変数でファイルパスを指定するか、DOWNLOAD=1 で公式URLから取得してください。' \
28
+ '例: rake jp_address_complement:import CSV=/path/to/KEN_ALL.CSV または DOWNLOAD=1'
29
+ end
30
+ csv_path
31
+ end
32
+ end
@@ -0,0 +1,380 @@
1
+ ---
2
+ path: ".gem_rbs_collection"
3
+ gems:
4
+ - name: actionpack
5
+ version: '7.2'
6
+ source:
7
+ type: git
8
+ name: ruby/gem_rbs_collection
9
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
10
+ remote: https://github.com/ruby/gem_rbs_collection.git
11
+ repo_dir: gems
12
+ - name: actionview
13
+ version: '6.0'
14
+ source:
15
+ type: git
16
+ name: ruby/gem_rbs_collection
17
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
18
+ remote: https://github.com/ruby/gem_rbs_collection.git
19
+ repo_dir: gems
20
+ - name: activemodel
21
+ version: '7.1'
22
+ source:
23
+ type: git
24
+ name: ruby/gem_rbs_collection
25
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
26
+ remote: https://github.com/ruby/gem_rbs_collection.git
27
+ repo_dir: gems
28
+ - name: activerecord
29
+ version: '8.0'
30
+ source:
31
+ type: git
32
+ name: ruby/gem_rbs_collection
33
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
34
+ remote: https://github.com/ruby/gem_rbs_collection.git
35
+ repo_dir: gems
36
+ - name: activesupport
37
+ version: '7.0'
38
+ source:
39
+ type: git
40
+ name: ruby/gem_rbs_collection
41
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
42
+ remote: https://github.com/ruby/gem_rbs_collection.git
43
+ repo_dir: gems
44
+ - name: ast
45
+ version: '2.4'
46
+ source:
47
+ type: git
48
+ name: ruby/gem_rbs_collection
49
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
50
+ remote: https://github.com/ruby/gem_rbs_collection.git
51
+ repo_dir: gems
52
+ - name: base64
53
+ version: 0.3.0
54
+ source:
55
+ type: rubygems
56
+ - name: bigdecimal
57
+ version: '4.0'
58
+ source:
59
+ type: git
60
+ name: ruby/gem_rbs_collection
61
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
62
+ remote: https://github.com/ruby/gem_rbs_collection.git
63
+ repo_dir: gems
64
+ - name: cgi
65
+ version: '0.5'
66
+ source:
67
+ type: git
68
+ name: ruby/gem_rbs_collection
69
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
70
+ remote: https://github.com/ruby/gem_rbs_collection.git
71
+ repo_dir: gems
72
+ - name: concurrent-ruby
73
+ version: '1.1'
74
+ source:
75
+ type: git
76
+ name: ruby/gem_rbs_collection
77
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
78
+ remote: https://github.com/ruby/gem_rbs_collection.git
79
+ repo_dir: gems
80
+ - name: connection_pool
81
+ version: '2.4'
82
+ source:
83
+ type: git
84
+ name: ruby/gem_rbs_collection
85
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
86
+ remote: https://github.com/ruby/gem_rbs_collection.git
87
+ repo_dir: gems
88
+ - name: csv
89
+ version: '3.3'
90
+ source:
91
+ type: git
92
+ name: ruby/gem_rbs_collection
93
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
94
+ remote: https://github.com/ruby/gem_rbs_collection.git
95
+ repo_dir: gems
96
+ - name: date
97
+ version: '0'
98
+ source:
99
+ type: stdlib
100
+ - name: delegate
101
+ version: '0'
102
+ source:
103
+ type: stdlib
104
+ - name: diff-lcs
105
+ version: '1.5'
106
+ source:
107
+ type: git
108
+ name: ruby/gem_rbs_collection
109
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
110
+ remote: https://github.com/ruby/gem_rbs_collection.git
111
+ repo_dir: gems
112
+ - name: digest
113
+ version: '0'
114
+ source:
115
+ type: stdlib
116
+ - name: erb
117
+ version: '0'
118
+ source:
119
+ type: stdlib
120
+ - name: ffi
121
+ version: 1.17.3
122
+ source:
123
+ type: rubygems
124
+ - name: fileutils
125
+ version: '0'
126
+ source:
127
+ type: stdlib
128
+ - name: forwardable
129
+ version: '0'
130
+ source:
131
+ type: stdlib
132
+ - name: i18n
133
+ version: '1.10'
134
+ source:
135
+ type: git
136
+ name: ruby/gem_rbs_collection
137
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
138
+ remote: https://github.com/ruby/gem_rbs_collection.git
139
+ repo_dir: gems
140
+ - name: io-console
141
+ version: '0'
142
+ source:
143
+ type: stdlib
144
+ - name: json
145
+ version: '0'
146
+ source:
147
+ type: stdlib
148
+ - name: listen
149
+ version: '3.9'
150
+ source:
151
+ type: git
152
+ name: ruby/gem_rbs_collection
153
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
154
+ remote: https://github.com/ruby/gem_rbs_collection.git
155
+ repo_dir: gems
156
+ - name: logger
157
+ version: '0'
158
+ source:
159
+ type: stdlib
160
+ - name: minitest
161
+ version: '5.25'
162
+ source:
163
+ type: git
164
+ name: ruby/gem_rbs_collection
165
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
166
+ remote: https://github.com/ruby/gem_rbs_collection.git
167
+ repo_dir: gems
168
+ - name: monitor
169
+ version: '0'
170
+ source:
171
+ type: stdlib
172
+ - name: mutex_m
173
+ version: 0.3.0
174
+ source:
175
+ type: rubygems
176
+ - name: nokogiri
177
+ version: '1.11'
178
+ source:
179
+ type: git
180
+ name: ruby/gem_rbs_collection
181
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
182
+ remote: https://github.com/ruby/gem_rbs_collection.git
183
+ repo_dir: gems
184
+ - name: openssl
185
+ version: '0'
186
+ source:
187
+ type: stdlib
188
+ - name: optparse
189
+ version: '0'
190
+ source:
191
+ type: stdlib
192
+ - name: parallel
193
+ version: '1.20'
194
+ source:
195
+ type: git
196
+ name: ruby/gem_rbs_collection
197
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
198
+ remote: https://github.com/ruby/gem_rbs_collection.git
199
+ repo_dir: gems
200
+ - name: parser
201
+ version: '3.2'
202
+ source:
203
+ type: git
204
+ name: ruby/gem_rbs_collection
205
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
206
+ remote: https://github.com/ruby/gem_rbs_collection.git
207
+ repo_dir: gems
208
+ - name: pp
209
+ version: '0'
210
+ source:
211
+ type: stdlib
212
+ - name: prettyprint
213
+ version: '0'
214
+ source:
215
+ type: stdlib
216
+ - name: prism
217
+ version: 1.9.0
218
+ source:
219
+ type: rubygems
220
+ - name: rack
221
+ version: '2.2'
222
+ source:
223
+ type: git
224
+ name: ruby/gem_rbs_collection
225
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
226
+ remote: https://github.com/ruby/gem_rbs_collection.git
227
+ repo_dir: gems
228
+ - name: rails-dom-testing
229
+ version: '2.0'
230
+ source:
231
+ type: git
232
+ name: ruby/gem_rbs_collection
233
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
234
+ remote: https://github.com/ruby/gem_rbs_collection.git
235
+ repo_dir: gems
236
+ - name: rails-html-sanitizer
237
+ version: '1.6'
238
+ source:
239
+ type: git
240
+ name: ruby/gem_rbs_collection
241
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
242
+ remote: https://github.com/ruby/gem_rbs_collection.git
243
+ repo_dir: gems
244
+ - name: railties
245
+ version: '6.0'
246
+ source:
247
+ type: git
248
+ name: ruby/gem_rbs_collection
249
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
250
+ remote: https://github.com/ruby/gem_rbs_collection.git
251
+ repo_dir: gems
252
+ - name: rainbow
253
+ version: '3.0'
254
+ source:
255
+ type: git
256
+ name: ruby/gem_rbs_collection
257
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
258
+ remote: https://github.com/ruby/gem_rbs_collection.git
259
+ repo_dir: gems
260
+ - name: rake
261
+ version: '13.0'
262
+ source:
263
+ type: git
264
+ name: ruby/gem_rbs_collection
265
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
266
+ remote: https://github.com/ruby/gem_rbs_collection.git
267
+ repo_dir: gems
268
+ - name: rbs
269
+ version: 3.10.3
270
+ source:
271
+ type: rubygems
272
+ - name: rbs-inline
273
+ version: 0.13.0
274
+ source:
275
+ type: rubygems
276
+ - name: rbs_rails
277
+ version: 0.13.0
278
+ source:
279
+ type: rubygems
280
+ - name: rdoc
281
+ version: '0'
282
+ source:
283
+ type: stdlib
284
+ - name: regexp_parser
285
+ version: '2.8'
286
+ source:
287
+ type: git
288
+ name: ruby/gem_rbs_collection
289
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
290
+ remote: https://github.com/ruby/gem_rbs_collection.git
291
+ repo_dir: gems
292
+ - name: rubocop
293
+ version: '1.57'
294
+ source:
295
+ type: git
296
+ name: ruby/gem_rbs_collection
297
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
298
+ remote: https://github.com/ruby/gem_rbs_collection.git
299
+ repo_dir: gems
300
+ - name: rubocop-ast
301
+ version: '1.46'
302
+ source:
303
+ type: git
304
+ name: ruby/gem_rbs_collection
305
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
306
+ remote: https://github.com/ruby/gem_rbs_collection.git
307
+ repo_dir: gems
308
+ - name: securerandom
309
+ version: '0'
310
+ source:
311
+ type: stdlib
312
+ - name: simplecov
313
+ version: '0.22'
314
+ source:
315
+ type: git
316
+ name: ruby/gem_rbs_collection
317
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
318
+ remote: https://github.com/ruby/gem_rbs_collection.git
319
+ repo_dir: gems
320
+ - name: singleton
321
+ version: '0'
322
+ source:
323
+ type: stdlib
324
+ - name: socket
325
+ version: '0'
326
+ source:
327
+ type: stdlib
328
+ - name: sqlite3
329
+ version: '2.0'
330
+ source:
331
+ type: git
332
+ name: ruby/gem_rbs_collection
333
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
334
+ remote: https://github.com/ruby/gem_rbs_collection.git
335
+ repo_dir: gems
336
+ - name: stringio
337
+ version: '0'
338
+ source:
339
+ type: stdlib
340
+ - name: strscan
341
+ version: '0'
342
+ source:
343
+ type: stdlib
344
+ - name: tempfile
345
+ version: '0'
346
+ source:
347
+ type: stdlib
348
+ - name: thor
349
+ version: '1.2'
350
+ source:
351
+ type: git
352
+ name: ruby/gem_rbs_collection
353
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
354
+ remote: https://github.com/ruby/gem_rbs_collection.git
355
+ repo_dir: gems
356
+ - name: time
357
+ version: '0'
358
+ source:
359
+ type: stdlib
360
+ - name: timeout
361
+ version: '0'
362
+ source:
363
+ type: stdlib
364
+ - name: tsort
365
+ version: '0'
366
+ source:
367
+ type: stdlib
368
+ - name: tzinfo
369
+ version: '2.0'
370
+ source:
371
+ type: git
372
+ name: ruby/gem_rbs_collection
373
+ revision: 1acc2fda1726ddac0bd60c4da369ce7266479413
374
+ remote: https://github.com/ruby/gem_rbs_collection.git
375
+ repo_dir: gems
376
+ - name: uri
377
+ version: '0'
378
+ source:
379
+ type: stdlib
380
+ gemfile_lock_path: Gemfile.lock
@@ -0,0 +1,19 @@
1
+ # Download sources
2
+ sources:
3
+ - type: git
4
+ name: ruby/gem_rbs_collection
5
+ remote: https://github.com/ruby/gem_rbs_collection.git
6
+ revision: main
7
+ repo_dir: gems
8
+
9
+ # You can specify local directories as sources also.
10
+ # - type: local
11
+ # path: path/to/your/local/repository
12
+
13
+ # A directory to install the downloaded RBSs
14
+ path: .gem_rbs_collection
15
+
16
+ # gems:
17
+ # # If you want to avoid installing rbs files for gems, you can specify them here.
18
+ # - name: GEM_NAME
19
+ # ignore: true