Skip to content

Commit 3678f9f

Browse files
committed
feat(products): move catalog REST endpoints to /api/v2
## Context The product catalog is the new billing surface and should live under a dedicated API version rather than alongside the legacy v1 endpoints. ## Description Move the products, product items and filters controllers and request specs under Api::V2 and a v2 routes namespace. Serializers stay under V1 because the activity log infrastructure resolves them by the V1:: prefix; the v2 controllers reuse them.
1 parent 205e2bf commit 3678f9f

7 files changed

Lines changed: 52 additions & 49 deletions

File tree

app/controllers/api/v1/product_items/filters_controller.rb renamed to app/controllers/api/v2/product_items/filters_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
module Api
4-
module V1
4+
module V2
55
module ProductItems
66
class FiltersController < Api::BaseController
77
before_action :find_product_item

app/controllers/api/v1/product_items_controller.rb renamed to app/controllers/api/v2/product_items_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
module Api
4-
module V1
4+
module V2
55
class ProductItemsController < Api::BaseController
66
def create
77
result = ::ProductItems::CreateService.call(

app/controllers/api/v1/products_controller.rb renamed to app/controllers/api/v2/products_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
module Api
4-
module V1
4+
module V2
55
class ProductsController < Api::BaseController
66
def create
77
result = ::Products::CreateService.call(

config/routes.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,6 @@
179179
end
180180
end
181181
end
182-
resources :product_items, only: %i[index show create update destroy] do
183-
resources :filters, only: %i[index show create update destroy], controller: "product_items/filters"
184-
end
185-
resources :products, param: :code, code: /.*/, only: %i[index show create update destroy]
186182
resources :taxes, param: :code, code: /.*/
187183
resources :wallet_transactions, only: %i[create show] do
188184
post :payment_url, on: :member
@@ -210,6 +206,13 @@
210206
get :json_public_key, on: :collection
211207
end
212208
end
209+
210+
namespace :v2 do
211+
resources :product_items, only: %i[index show create update destroy] do
212+
resources :filters, only: %i[index show create update destroy], controller: "product_items/filters"
213+
end
214+
resources :products, param: :code, code: /.*/, only: %i[index show create update destroy]
215+
end
213216
end
214217
resources :webhooks, only: [] do
215218
post "stripe/:organization_id", to: "webhooks#stripe", on: :collection, as: :stripe

spec/requests/api/v1/product_items/filters_controller_spec.rb renamed to spec/requests/api/v2/product_items/filters_controller_spec.rb

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
require "rails_helper"
44

5-
RSpec.describe Api::V1::ProductItems::FiltersController do
5+
RSpec.describe Api::V2::ProductItems::FiltersController do
66
let(:organization) { create(:organization) }
77
let(:billable_metric) { create(:billable_metric, organization:) }
88
let(:product_item) { create(:product_item, organization:, billable_metric:) }
99
let(:region_filter) { create(:billable_metric_filter, organization:, billable_metric:, key: "region", values: %w[us eu]) }
1010

11-
describe "POST /api/v1/product_items/:product_item_id/filters" do
12-
subject { post_with_token(organization, "/api/v1/product_items/#{product_item.id}/filters", {filter: create_params}) }
11+
describe "POST /api/v2/product_items/:product_item_id/filters" do
12+
subject { post_with_token(organization, "/api/v2/product_items/#{product_item.id}/filters", {filter: create_params}) }
1313

1414
let(:create_params) do
1515
{
@@ -42,7 +42,7 @@
4242
end
4343

4444
context "when the product item does not exist" do
45-
subject { post_with_token(organization, "/api/v1/product_items/#{SecureRandom.uuid}/filters", {filter: create_params}) }
45+
subject { post_with_token(organization, "/api/v2/product_items/#{SecureRandom.uuid}/filters", {filter: create_params}) }
4646

4747
it "returns a not found error" do
4848
subject
@@ -52,11 +52,11 @@
5252
end
5353
end
5454

55-
describe "PUT /api/v1/product_items/:product_item_id/filters/:id" do
55+
describe "PUT /api/v2/product_items/:product_item_id/filters/:id" do
5656
subject do
5757
put_with_token(
5858
organization,
59-
"/api/v1/product_items/#{product_item.id}/filters/#{filter.id}",
59+
"/api/v2/product_items/#{product_item.id}/filters/#{filter.id}",
6060
{filter: update_params}
6161
)
6262
end
@@ -92,7 +92,7 @@
9292
end
9393

9494
context "when the filter does not exist" do
95-
subject { put_with_token(organization, "/api/v1/product_items/#{product_item.id}/filters/#{SecureRandom.uuid}", {filter: update_params}) }
95+
subject { put_with_token(organization, "/api/v2/product_items/#{product_item.id}/filters/#{SecureRandom.uuid}", {filter: update_params}) }
9696

9797
it "returns a not found error" do
9898
subject
@@ -102,8 +102,8 @@
102102
end
103103
end
104104

105-
describe "GET /api/v1/product_items/:product_item_id/filters/:id" do
106-
subject { get_with_token(organization, "/api/v1/product_items/#{product_item.id}/filters/#{filter.id}") }
105+
describe "GET /api/v2/product_items/:product_item_id/filters/:id" do
106+
subject { get_with_token(organization, "/api/v2/product_items/#{product_item.id}/filters/#{filter.id}") }
107107

108108
let(:filter) { create(:product_item_filter, :with_values, organization:, product_item:) }
109109

@@ -118,8 +118,8 @@
118118
end
119119
end
120120

121-
describe "GET /api/v1/product_items/:product_item_id/filters" do
122-
subject { get_with_token(organization, "/api/v1/product_items/#{product_item.id}/filters") }
121+
describe "GET /api/v2/product_items/:product_item_id/filters" do
122+
subject { get_with_token(organization, "/api/v2/product_items/#{product_item.id}/filters") }
123123

124124
before do
125125
create(:product_item_filter, organization:, product_item:)
@@ -137,7 +137,7 @@
137137
end
138138

139139
context "with a search term" do
140-
subject { get_with_token(organization, "/api/v1/product_items/#{product_item.id}/filters?search_term=findme") }
140+
subject { get_with_token(organization, "/api/v2/product_items/#{product_item.id}/filters?search_term=findme") }
141141

142142
let!(:matching) { create(:product_item_filter, organization:, product_item:, name: "findme filter") }
143143

@@ -150,8 +150,8 @@
150150
end
151151
end
152152

153-
describe "DELETE /api/v1/product_items/:product_item_id/filters/:id" do
154-
subject { delete_with_token(organization, "/api/v1/product_items/#{product_item.id}/filters/#{filter.id}") }
153+
describe "DELETE /api/v2/product_items/:product_item_id/filters/:id" do
154+
subject { delete_with_token(organization, "/api/v2/product_items/#{product_item.id}/filters/#{filter.id}") }
155155

156156
let(:filter) { create(:product_item_filter, :with_values, organization:, product_item:) }
157157

spec/requests/api/v1/product_items_controller_spec.rb renamed to spec/requests/api/v2/product_items_controller_spec.rb

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
require "rails_helper"
44

5-
RSpec.describe Api::V1::ProductItemsController do
5+
RSpec.describe Api::V2::ProductItemsController do
66
let(:organization) { create(:organization) }
77

8-
describe "POST /api/v1/product_items" do
9-
subject { post_with_token(organization, "/api/v1/product_items", {product_item: create_params}) }
8+
describe "POST /api/v2/product_items" do
9+
subject { post_with_token(organization, "/api/v2/product_items", {product_item: create_params}) }
1010

1111
let(:product) { create(:product, organization:) }
1212
let(:billable_metric) { create(:billable_metric, organization:) }
@@ -59,8 +59,8 @@
5959
end
6060
end
6161

62-
describe "PUT /api/v1/product_items/:id" do
63-
subject { put_with_token(organization, "/api/v1/product_items/#{product_item.id}", {product_item: update_params}) }
62+
describe "PUT /api/v2/product_items/:id" do
63+
subject { put_with_token(organization, "/api/v2/product_items/#{product_item.id}", {product_item: update_params}) }
6464

6565
let(:product_item) { create(:product_item, organization:, name: "Before") }
6666
let(:update_params) { {name: "After"} }
@@ -88,7 +88,7 @@
8888
end
8989

9090
context "when the product item does not exist" do
91-
subject { put_with_token(organization, "/api/v1/product_items/#{SecureRandom.uuid}", {product_item: update_params}) }
91+
subject { put_with_token(organization, "/api/v2/product_items/#{SecureRandom.uuid}", {product_item: update_params}) }
9292

9393
it "returns a not found error" do
9494
subject
@@ -98,8 +98,8 @@
9898
end
9999
end
100100

101-
describe "GET /api/v1/product_items/:id" do
102-
subject { get_with_token(organization, "/api/v1/product_items/#{product_item.id}") }
101+
describe "GET /api/v2/product_items/:id" do
102+
subject { get_with_token(organization, "/api/v2/product_items/#{product_item.id}") }
103103

104104
let(:product_item) { create(:product_item, organization:) }
105105

@@ -124,8 +124,8 @@
124124
end
125125
end
126126

127-
describe "GET /api/v1/product_items" do
128-
subject { get_with_token(organization, "/api/v1/product_items#{query_params}") }
127+
describe "GET /api/v2/product_items" do
128+
subject { get_with_token(organization, "/api/v2/product_items#{query_params}") }
129129

130130
let(:query_params) { "" }
131131
let(:product) { create(:product, organization:) }
@@ -174,8 +174,8 @@
174174
end
175175
end
176176

177-
describe "DELETE /api/v1/product_items/:id" do
178-
subject { delete_with_token(organization, "/api/v1/product_items/#{product_item.id}") }
177+
describe "DELETE /api/v2/product_items/:id" do
178+
subject { delete_with_token(organization, "/api/v2/product_items/#{product_item.id}") }
179179

180180
let(:product_item) { create(:product_item, organization:) }
181181

@@ -190,7 +190,7 @@
190190
end
191191

192192
context "when the product item does not exist" do
193-
subject { delete_with_token(organization, "/api/v1/product_items/#{SecureRandom.uuid}") }
193+
subject { delete_with_token(organization, "/api/v2/product_items/#{SecureRandom.uuid}") }
194194

195195
it "returns a not found error" do
196196
subject

spec/requests/api/v1/products_controller_spec.rb renamed to spec/requests/api/v2/products_controller_spec.rb

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
require "rails_helper"
44

5-
RSpec.describe Api::V1::ProductsController do
5+
RSpec.describe Api::V2::ProductsController do
66
let(:organization) { create(:organization) }
77

8-
describe "POST /api/v1/products" do
9-
subject { post_with_token(organization, "/api/v1/products", {product: create_params}) }
8+
describe "POST /api/v2/products" do
9+
subject { post_with_token(organization, "/api/v2/products", {product: create_params}) }
1010

1111
let(:create_params) do
1212
{
@@ -41,8 +41,8 @@
4141
end
4242
end
4343

44-
describe "PUT /api/v1/products/:code" do
45-
subject { put_with_token(organization, "/api/v1/products/#{product.code}", {product: update_params}) }
44+
describe "PUT /api/v2/products/:code" do
45+
subject { put_with_token(organization, "/api/v2/products/#{product.code}", {product: update_params}) }
4646

4747
let(:product) { create(:product, organization:, name: "Before") }
4848
let(:update_params) { {name: "After"} }
@@ -70,7 +70,7 @@
7070
end
7171

7272
context "when the product does not exist" do
73-
subject { put_with_token(organization, "/api/v1/products/unknown", {product: update_params}) }
73+
subject { put_with_token(organization, "/api/v2/products/unknown", {product: update_params}) }
7474

7575
it "returns a not found error" do
7676
subject
@@ -80,8 +80,8 @@
8080
end
8181
end
8282

83-
describe "GET /api/v1/products/:code" do
84-
subject { get_with_token(organization, "/api/v1/products/#{product.code}") }
83+
describe "GET /api/v2/products/:code" do
84+
subject { get_with_token(organization, "/api/v2/products/#{product.code}") }
8585

8686
let(:product) { create(:product, organization:) }
8787

@@ -99,7 +99,7 @@
9999
end
100100

101101
context "when the product does not exist" do
102-
subject { get_with_token(organization, "/api/v1/products/unknown") }
102+
subject { get_with_token(organization, "/api/v2/products/unknown") }
103103

104104
it "returns a not found error" do
105105
subject
@@ -119,8 +119,8 @@
119119
end
120120
end
121121

122-
describe "GET /api/v1/products" do
123-
subject { get_with_token(organization, "/api/v1/products?page=1&per_page=1") }
122+
describe "GET /api/v2/products" do
123+
subject { get_with_token(organization, "/api/v2/products?page=1&per_page=1") }
124124

125125
before { create(:product, organization:) }
126126

@@ -146,7 +146,7 @@
146146
end
147147

148148
context "with a search term" do
149-
subject { get_with_token(organization, "/api/v1/products?search_term=#{search_term}") }
149+
subject { get_with_token(organization, "/api/v2/products?search_term=#{search_term}") }
150150

151151
let(:search_term) { "matching" }
152152
let(:matching) { create(:product, organization:, name: "matching product") }
@@ -166,8 +166,8 @@
166166
end
167167
end
168168

169-
describe "DELETE /api/v1/products/:code" do
170-
subject { delete_with_token(organization, "/api/v1/products/#{product.code}") }
169+
describe "DELETE /api/v2/products/:code" do
170+
subject { delete_with_token(organization, "/api/v2/products/#{product.code}") }
171171

172172
let(:product) { create(:product, organization:) }
173173

@@ -182,7 +182,7 @@
182182
end
183183

184184
context "when the product does not exist" do
185-
subject { delete_with_token(organization, "/api/v1/products/unknown") }
185+
subject { delete_with_token(organization, "/api/v2/products/unknown") }
186186

187187
it "returns a not found error" do
188188
subject

0 commit comments

Comments
 (0)