Skip to content

Commit 11535e0

Browse files
Add sorting/filters for issues endpoint (#587)
* Add filters for category/language/keyword on the issues endpoint. Add sorting for created/updated/stars. * Add test for issues endpoint. * Disable index while testing.
1 parent 93900e8 commit 11535e0

File tree

6 files changed

+240
-59
lines changed

6 files changed

+240
-59
lines changed

Gemfile.lock

+4-36
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,6 @@ GEM
9999
language_list (~> 1.2.1)
100100
chronic_duration (0.10.6)
101101
numerizer (~> 0.1.1)
102-
commonmarker (2.3.0)
103-
rb_sys (~> 0.9)
104102
commonmarker (2.3.0-aarch64-linux)
105103
commonmarker (2.3.0-aarch64-linux-musl)
106104
commonmarker (2.3.0-arm64-darwin)
@@ -128,7 +126,7 @@ GEM
128126
ethon (0.16.0)
129127
ffi (>= 1.15.0)
130128
execjs (2.10.0)
131-
faraday (2.12.2)
129+
faraday (2.12.3)
132130
faraday-net_http (>= 2.0, < 3.5)
133131
json
134132
logger
@@ -141,20 +139,14 @@ GEM
141139
faraday-typhoeus (1.1.0)
142140
faraday (~> 2.0)
143141
typhoeus (~> 1.4)
144-
ffi (1.17.1)
145142
ffi (1.17.1-aarch64-linux-gnu)
146143
ffi (1.17.1-aarch64-linux-musl)
147-
ffi (1.17.1-arm-linux-gnu)
148-
ffi (1.17.1-arm-linux-musl)
149144
ffi (1.17.1-arm64-darwin)
150145
ffi (1.17.1-x86_64-darwin)
151146
ffi (1.17.1-x86_64-linux-gnu)
152147
ffi (1.17.1-x86_64-linux-musl)
153148
globalid (1.2.1)
154149
activesupport (>= 6.1)
155-
google-protobuf (4.30.2)
156-
bigdecimal
157-
rake (>= 13)
158150
google-protobuf (4.30.2-aarch64-linux)
159151
bigdecimal
160152
rake (>= 13)
@@ -207,7 +199,6 @@ GEM
207199
meilisearch (~> 0.31.0)
208200
mutex_m (~> 0.2)
209201
mini_mime (1.1.5)
210-
mini_portile2 (2.8.8)
211202
minitest (5.25.5)
212203
mocha (2.7.1)
213204
ruby2_keywords (>= 0.0.5)
@@ -227,17 +218,10 @@ GEM
227218
net-smtp (0.5.1)
228219
net-protocol
229220
nio4r (2.7.4)
230-
nokogiri (1.18.7)
231-
mini_portile2 (~> 2.8.2)
232-
racc (~> 1.4)
233221
nokogiri (1.18.7-aarch64-linux-gnu)
234222
racc (~> 1.4)
235223
nokogiri (1.18.7-aarch64-linux-musl)
236224
racc (~> 1.4)
237-
nokogiri (1.18.7-arm-linux-gnu)
238-
racc (~> 1.4)
239-
nokogiri (1.18.7-arm-linux-musl)
240-
racc (~> 1.4)
241225
nokogiri (1.18.7-arm64-darwin)
242226
racc (~> 1.4)
243227
nokogiri (1.18.7-x86_64-darwin)
@@ -313,9 +297,6 @@ GEM
313297
thor (~> 1.0, >= 1.2.2)
314298
zeitwerk (~> 2.6)
315299
rake (13.2.1)
316-
rake-compiler-dock (1.9.1)
317-
rb_sys (0.9.111)
318-
rake-compiler-dock (= 1.9.1)
319300
rdoc (6.13.1)
320301
psych (>= 4.0.0)
321302
redis (5.4.0)
@@ -397,13 +378,11 @@ GEM
397378

398379
PLATFORMS
399380
aarch64-linux
381+
aarch64-linux-gnu
400382
aarch64-linux-musl
401-
arm-linux-gnu
402-
arm-linux-musl
403383
arm64-darwin
404-
ruby
405384
x86_64-darwin
406-
x86_64-linux
385+
x86_64-linux-gnu
407386
x86_64-linux-musl
408387

409388
DEPENDENCIES
@@ -480,7 +459,6 @@ CHECKSUMS
480459
builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f
481460
cff (1.3.0) sha256=d2b65d57160040ad244087d65b89769558a40aafb34b13d048e0ea72bc521316
482461
chronic_duration (0.10.6) sha256=fac58d4147d3183a40811400380cafcef049f2bb02421d2fd1c6e685fbe8facc
483-
commonmarker (2.3.0) sha256=74fb85e4ae59a9fc166dd1813ad791805d09dec1a4e79c81a7be0a6a8dc5dc63
484462
commonmarker (2.3.0-aarch64-linux) sha256=63e6c599ed2b1a01c012e5524ed25f60ab1132c6b582bcef0aa542770d3087ee
485463
commonmarker (2.3.0-aarch64-linux-musl) sha256=2be68fc9106fe5b0a92928cf2903c0924ee2ef862fefd2b5c7943292902e79ab
486464
commonmarker (2.3.0-arm64-darwin) sha256=fb5a6416395cbac63bb7741887c74e17141be75f407a292ab98cd6c8ab4894a2
@@ -501,22 +479,18 @@ CHECKSUMS
501479
erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
502480
ethon (0.16.0) sha256=bba0da1cea8ac3e1f5cdd7cb1cb5fc78d7ac562c33736f18f0c3eb2b63053d9e
503481
execjs (2.10.0) sha256=6bcb8be8f0052ff9d370b65d1c080f2406656e150452a0abdb185a133048450d
504-
faraday (2.12.2) sha256=157339c25c7b8bcb739f5cf1207cb0cefe8fa1c65027266bcbc34c90c84b9ad6
482+
faraday (2.12.3) sha256=b1ad088abda31b356657c96944be5aa2a5546952b6a47f5a9572370ad8a5aa37
505483
faraday-follow_redirects (0.3.0) sha256=d92d975635e2c7fe525dd494fcd4b9bb7f0a4a0ec0d5f4c15c729530fdb807f9
506484
faraday-net_http (3.4.0) sha256=a1f1e4cd6a2cf21599c8221595e27582d9936819977bbd4089a601f24c64e54a
507485
faraday-retry (2.3.1) sha256=4004faa21f41fc5360d359bc79889fc58fb7fae0ce93bfb737a784ac76805c03
508486
faraday-typhoeus (1.1.0) sha256=24c6147c213818dde3ebc50ae47ab92f9a7e554903aa362707126f749c6890e7
509-
ffi (1.17.1) sha256=26f6b0dbd1101e6ffc09d3ca640b2a21840cc52731ad8a7ded9fb89e5fb0fc39
510487
ffi (1.17.1-aarch64-linux-gnu) sha256=c5d22cb545a3a691d46060f1343c461d1a8d38c3fd71b96b4cbbe6906bf1fd38
511488
ffi (1.17.1-aarch64-linux-musl) sha256=88b9d6ae905d21142df27c94bb300042c1aae41b67291885f600eaad16326b1d
512-
ffi (1.17.1-arm-linux-gnu) sha256=fe14f5ece94082f3b0e651a09008113281f2764e7ea95f522b64e2fe32e11504
513-
ffi (1.17.1-arm-linux-musl) sha256=df14927ca7bd9095148a7d1938bb762bbf189d190cf25d9547395ec7acc198a0
514489
ffi (1.17.1-arm64-darwin) sha256=a8e04f79d375742c54ee7f9fff4b4022b87200a4ec0eb082128d3b6559e67b4d
515490
ffi (1.17.1-x86_64-darwin) sha256=0036199c290462dd7f03bc22933644c1685b7834a21788062bd5df48c72aa7a6
516491
ffi (1.17.1-x86_64-linux-gnu) sha256=8c0ade2a5d19f3672bccfe3b58e016ae5f159e3e2e741c856db87fcf07c903d0
517492
ffi (1.17.1-x86_64-linux-musl) sha256=3a343086820c96d6fbea4a5ef807fb69105b2b8174678f103b3db210c3f78401
518493
globalid (1.2.1) sha256=70bf76711871f843dbba72beb8613229a49429d1866828476f9c9d6ccc327ce9
519-
google-protobuf (4.30.2) sha256=0f35168dbeeccf13d928acf6c128cfec17b9a826ae4505246a02c115f4ae16ed
520494
google-protobuf (4.30.2-aarch64-linux) sha256=a99d2f31bc2bebf4994b7cd2dd4c1d3ef28a0acc8f1b37be236982f7dc21bd8d
521495
google-protobuf (4.30.2-arm64-darwin) sha256=c66a93ceef100fb2390615e76310491cc6e1944f7b9cda2cf1e3279887f817d1
522496
google-protobuf (4.30.2-x86_64-darwin) sha256=17f4567dff431f8dd5be5ff6395824ec044413f67d2803a9941ebc8c70dec604
@@ -539,7 +513,6 @@ CHECKSUMS
539513
meilisearch (0.31.0) sha256=f32a49b195d56434f671fc95aae75b08ee78629b167dd4db514ef824393a7cd6
540514
meilisearch-rails (0.15.0) sha256=5a59f0e605455e506f90633518407f69549e99a771505919adc44ed8eda5d930
541515
mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef
542-
mini_portile2 (2.8.8) sha256=8e47136cdac04ce81750bb6c09733b37895bf06962554e4b4056d78168d70a75
543516
minitest (5.25.5) sha256=391b6c6cb43a4802bfb7c93af1ebe2ac66a210293f4a3fb7db36f2fc7dc2c756
544517
mocha (2.7.1) sha256=8f7d538d5d3ebc75fc788b3d92fbab913a93a78462d2a3ce99d1bdde7af7f851
545518
msgpack (1.8.0) sha256=e64ce0212000d016809f5048b48eb3a65ffb169db22238fb4b72472fecb2d732
@@ -551,11 +524,8 @@ CHECKSUMS
551524
net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8
552525
net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736
553526
nio4r (2.7.4) sha256=d95dee68e0bb251b8ff90ac3423a511e3b784124e5db7ff5f4813a220ae73ca9
554-
nokogiri (1.18.7) sha256=6b63ff5defe48f30d1d3b3122f65255ca91df2caf5378c6e0482ce73ff46fb31
555527
nokogiri (1.18.7-aarch64-linux-gnu) sha256=57a064ab5440814a69a0e040817bd8154adea68a30d2ff2b3aa515a6a06dbb5f
556528
nokogiri (1.18.7-aarch64-linux-musl) sha256=3e442dc5b69376e84288295fe37cbb890a21ad816a7e571e5e9967b3c1e30cd3
557-
nokogiri (1.18.7-arm-linux-gnu) sha256=337d9149deb5ae01022dff7c90f97bed81715fd586aacab0c5809ef933994c5e
558-
nokogiri (1.18.7-arm-linux-musl) sha256=97a26edcc975f780a0822aaf7f7d7427c561067c1c9ee56bd3542960f0c28a6e
559529
nokogiri (1.18.7-arm64-darwin) sha256=083abb2e9ed2646860f6b481a981485a658c6064caafaa81bf1cda1bada2e9d5
560530
nokogiri (1.18.7-x86_64-darwin) sha256=081d1aa517454ba3415304e2ea51fe411d6a3a809490d0c4aa42799cada417b7
561531
nokogiri (1.18.7-x86_64-linux-gnu) sha256=3a0bf946eb2defde13d760f869b61bc8b0c18875afdd3cffa96543cfa3a18005
@@ -586,8 +556,6 @@ CHECKSUMS
586556
rails-html-sanitizer (1.6.2) sha256=35fce2ca8242da8775c83b6ba9c1bcaad6751d9eb73c1abaa8403475ab89a560
587557
railties (8.0.2) sha256=0d7c3f40c49ba74980f1bac1d4bb153a9331c5ee8a9631d89c7bf79db82e5cf9
588558
rake (13.2.1) sha256=46cb38dae65d7d74b6020a4ac9d48afed8eb8149c040eccf0523bec91907059d
589-
rake-compiler-dock (1.9.1) sha256=e73720a29aba9c114728ce39cc0d8eef69ba61d88e7978c57bac171724cd4d53
590-
rb_sys (0.9.111) sha256=65822fd8d57c248cd893db0efe01bc6edc15fcbea3ba6666091e35430c1cbaf0
591559
rdoc (6.13.1) sha256=62a0dac99493c94e8eb7a3fb44e55aefcb4cecb119f7991f25bddc5ed8d472f7
592560
redis (5.4.0) sha256=798900d869418a9fc3977f916578375b45c38247a556b61d58cba6bb02f7d06b
593561
redis-client (0.24.0) sha256=ee65ee39cb2c38608b734566167fd912384f3c1241f59075e22858f23a085dbb

app/controllers/api/v1/issues_controller.rb

+18-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,26 @@ def index
33
scope = Issue.where(pull_request: false, state: 'open').includes(:project)
44
scope = scope.joins(:project).where(projects: { reviewed: true }).climatetriage.good_first_issue
55

6+
# Apply filters if provided
7+
scope = scope.joins(:project).where(projects: { category: params[:category] }) if params[:category].present?
8+
scope = scope.joins(:project).merge(Project.language(params[:language])) if params[:language].present?
9+
scope = scope.joins(:project).merge(Project.keyword(params[:keyword])) if params[:keyword].present?
10+
11+
# Define allowed sort fields with database expressions
12+
allowed_sort_fields = {
13+
'created_at' => 'issues.created_at',
14+
'updated_at' => 'issues.updated_at',
15+
'stars' => "CAST(projects.repository->>'stargazers_count' AS INTEGER)"
16+
}
17+
618
if params[:sort].present? || params[:order].present?
7-
sort = params[:sort].presence || 'issues.created_at'
19+
sort_key = params[:sort].presence || 'created_at'
20+
sort_field = allowed_sort_fields[sort_key] || 'issues.created_at'
21+
822
if params[:order] == 'asc'
9-
scope = scope.order(Arel.sql(sort).asc.nulls_last)
23+
scope = scope.order(Arel.sql(sort_field).asc.nulls_last)
1024
else
11-
scope = scope.order(Arel.sql(sort).desc.nulls_last)
25+
scope = scope.order(Arel.sql(sort_field).desc.nulls_last)
1226
end
1327
else
1428
scope = scope.order('issues.created_at DESC')
@@ -35,4 +49,4 @@ def openclimateaction
3549

3650
@pagy, @projects = pagy(scope)
3751
end
38-
end
52+
end

app/controllers/issues_controller.rb

+18-4
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,31 @@ class IssuesController < ApplicationController
22
def index
33
scope = Issue.good_first_issue.joins(:project).where(projects: { reviewed: true }).includes(:project)
44

5+
# Apply filters if provided
6+
scope = scope.joins(:project).where(projects: { category: params[:category] }) if params[:category].present?
7+
scope = scope.joins(:project).merge(Project.language(params[:language])) if params[:language].present?
8+
scope = scope.joins(:project).merge(Project.keyword(params[:keyword])) if params[:keyword].present?
9+
10+
# Define allowed sort fields with database expressions
11+
allowed_sort_fields = {
12+
'created_at' => 'issues.created_at',
13+
'updated_at' => 'issues.updated_at',
14+
'stars' => "CAST(projects.repository->>'stargazers_count' AS INTEGER)"
15+
}
16+
517
if params[:sort].present? || params[:order].present?
6-
sort = params[:sort].presence || 'issues.created_at'
18+
sort_key = params[:sort].presence || 'created_at'
19+
sort_field = allowed_sort_fields[sort_key] || 'issues.created_at'
20+
721
if params[:order] == 'asc'
8-
scope = scope.order(Arel.sql(sort).asc.nulls_last)
22+
scope = scope.order(Arel.sql(sort_field).asc.nulls_last)
923
else
10-
scope = scope.order(Arel.sql(sort).desc.nulls_last)
24+
scope = scope.order(Arel.sql(sort_field).desc.nulls_last)
1125
end
1226
else
1327
scope = scope.order('issues.created_at DESC')
1428
end
1529

1630
@pagy, @issues = pagy(scope)
1731
end
18-
end
32+
end

openapi/api/v1/openapi.yaml

+34-15
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ info:
55
contact:
66
name: Ecosyste.ms
77
8-
url: https://ecosyste.ms
8+
url: https://ecosyste.ms
99
version: 1.0.0
1010
license:
1111
name: CC-BY-SA-4.0
@@ -14,7 +14,7 @@ externalDocs:
1414
description: GitHub Project
1515
url: https://github.com/ecosyste-ms/ost
1616
servers:
17-
- url: https://ost.ecosyste.ms/api/v1
17+
- url: https://ost.ecosyste.ms/api/v1
1818
paths:
1919
/projects:
2020
get:
@@ -31,13 +31,13 @@ paths:
3131
type: boolean
3232
- name: page
3333
in: query
34-
description: pagination page number
34+
description: pagination page number
3535
required: false
3636
schema:
3737
type: integer
3838
- name: per_page
3939
in: query
40-
description: Number of records to return
40+
description: Number of records to return
4141
required: false
4242
schema:
4343
type: integer
@@ -62,7 +62,7 @@ paths:
6262
schema:
6363
type: array
6464
items:
65-
$ref: '#/components/schemas/Project'
65+
$ref: "#/components/schemas/Project"
6666
/projects/{id}:
6767
get:
6868
description: get a project by id
@@ -82,7 +82,7 @@ paths:
8282
content:
8383
application/json:
8484
schema:
85-
$ref: '#/components/schemas/Project'
85+
$ref: "#/components/schemas/Project"
8686
/projects/lookup:
8787
get:
8888
description: lookup project by url
@@ -102,7 +102,7 @@ paths:
102102
content:
103103
application/json:
104104
schema:
105-
$ref: '#/components/schemas/Project'
105+
$ref: "#/components/schemas/Project"
106106
/projects/packages:
107107
get:
108108
description: get projects with packages
@@ -117,7 +117,7 @@ paths:
117117
schema:
118118
type: array
119119
items:
120-
$ref: '#/components/schemas/Project'
120+
$ref: "#/components/schemas/Project"
121121
/projects/images:
122122
get:
123123
description: get projects with images
@@ -132,23 +132,41 @@ paths:
132132
schema:
133133
type: array
134134
items:
135-
$ref: '#/components/schemas/Project'
135+
$ref: "#/components/schemas/Project"
136136
/issues:
137137
get:
138138
description: get issues
139139
operationId: getIssues
140140
tags:
141141
- issues
142142
parameters:
143+
- name: category
144+
in: query
145+
description: Filter issues by project category
146+
required: false
147+
schema:
148+
type: string
149+
- name: language
150+
in: query
151+
description: Filter issues by programming language
152+
required: false
153+
schema:
154+
type: string
155+
- name: keyword
156+
in: query
157+
description: Filter issues by project keyword
158+
required: false
159+
schema:
160+
type: string
143161
- name: page
144162
in: query
145-
description: pagination page number
163+
description: pagination page number
146164
required: false
147165
schema:
148166
type: integer
149167
- name: per_page
150168
in: query
151-
description: Number of records to return
169+
description: Number of records to return
152170
required: false
153171
schema:
154172
type: integer
@@ -158,6 +176,7 @@ paths:
158176
required: false
159177
schema:
160178
type: string
179+
enum: [created_at, updated_at, stars]
161180
- name: order
162181
in: query
163182
description: The sort order (asc or desc)
@@ -173,7 +192,7 @@ paths:
173192
schema:
174193
type: array
175194
items:
176-
$ref: '#/components/schemas/Issue'
195+
$ref: "#/components/schemas/Issue"
177196
/issues/openclimateaction:
178197
get:
179198
description: get issues for openclimateaction
@@ -183,13 +202,13 @@ paths:
183202
parameters:
184203
- name: page
185204
in: query
186-
description: pagination page number
205+
description: pagination page number
187206
required: false
188207
schema:
189208
type: integer
190209
- name: per_page
191210
in: query
192-
description: Number of records to return
211+
description: Number of records to return
193212
required: false
194213
schema:
195214
type: integer
@@ -214,7 +233,7 @@ paths:
214233
schema:
215234
type: array
216235
items:
217-
$ref: '#/components/schemas/Issue'
236+
$ref: "#/components/schemas/Issue"
218237
components:
219238
schemas:
220239
Project:

0 commit comments

Comments
 (0)