Skip to content

Commit a58af0a

Browse files
committed
search: enforce bounded result limits and add api.cleanapp.io v3/v4 compatibility routes
1 parent 1020082 commit a58af0a

File tree

4 files changed

+43
-11
lines changed

4 files changed

+43
-11
lines changed

platform_blueprint/deploy/prod/nginx_conf_d/apicleanapp.conf

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ server {
3333
location = /create_or_update_area { proxy_pass http://127.0.0.1:8079; proxy_set_header Host $host; proxy_read_timeout 60; proxy_redirect http:// https://; }
3434
location = /get_reports_by_lat_lon { proxy_pass http://127.0.0.1:8079; proxy_set_header Host $host; proxy_read_timeout 60; proxy_redirect http:// https://; }
3535

36+
# Compatibility routes for older frontend bundles hitting api.cleanapp.io
37+
location /api/v3/ {
38+
proxy_pass http://127.0.0.1:9081;
39+
proxy_http_version 1.1;
40+
proxy_set_header Host $host;
41+
proxy_set_header Upgrade $http_upgrade;
42+
proxy_set_header Connection "upgrade";
43+
proxy_read_timeout 86400;
44+
}
45+
46+
location /api/v4/ {
47+
proxy_pass http://127.0.0.1:9097;
48+
proxy_http_version 1.1;
49+
proxy_set_header Host $host;
50+
proxy_set_header Upgrade $http_upgrade;
51+
proxy_set_header Connection "upgrade";
52+
proxy_read_timeout 86400;
53+
}
3654

3755

3856

report-listener/.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
BUILD_VERSION=1.0.113
1+
BUILD_VERSION=1.0.114

report-listener/database/database.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ func (d *Database) GetLastNAnalyzedReports(ctx context.Context, limit int, class
654654
// If full_data is true, returns reports with analysis. If false, returns only reports.
655655
// Only returns reports that are not resolved and are not privately owned
656656
// If classification is empty, returns both physical and digital reports
657-
func (d *Database) SearchReports(ctx context.Context, searchQuery string, classification string, full_data bool) (interface{}, error) {
657+
func (d *Database) SearchReports(ctx context.Context, searchQuery string, classification string, full_data bool, limit int) (interface{}, error) {
658658
// OPTIMIZED 2-PHASE SEARCH:
659659
// Phase 1: Fast FULLTEXT-only query to get seq IDs (no expensive JOINs)
660660
// Phase 2: Fetch report details only for matching IDs
@@ -679,18 +679,18 @@ func (d *Database) SearchReports(ctx context.Context, searchQuery string, classi
679679
WHERE is_valid = TRUE
680680
AND classification = ?
681681
AND brand_name LIKE ?
682-
LIMIT 200
682+
LIMIT ?
683683
`
684-
fastArgs = []interface{}{classification, prefixTerm}
684+
fastArgs = []interface{}{classification, prefixTerm, limit}
685685
} else {
686686
fastQuery = `
687687
SELECT DISTINCT seq
688688
FROM report_analysis
689689
WHERE is_valid = TRUE
690690
AND brand_name LIKE ?
691-
LIMIT 200
691+
LIMIT ?
692692
`
693-
fastArgs = []interface{}{prefixTerm}
693+
fastArgs = []interface{}{prefixTerm, limit}
694694
}
695695

696696
fastRows, err := d.db.QueryContext(ctx, fastQuery, fastArgs...)
@@ -729,18 +729,18 @@ func (d *Database) SearchReports(ctx context.Context, searchQuery string, classi
729729
WHERE is_valid = TRUE
730730
AND classification = ?
731731
AND MATCH(title, description, brand_name, brand_display_name, summary) AGAINST (? IN BOOLEAN MODE)
732-
LIMIT 200
732+
LIMIT ?
733733
`
734-
seqArgs = []interface{}{classification, searchQuery}
734+
seqArgs = []interface{}{classification, searchQuery, limit}
735735
} else {
736736
seqQuery = `
737737
SELECT DISTINCT seq
738738
FROM report_analysis
739739
WHERE is_valid = TRUE
740740
AND MATCH(title, description, brand_name, brand_display_name, summary) AGAINST (? IN BOOLEAN MODE)
741-
LIMIT 200
741+
LIMIT ?
742742
`
743-
seqArgs = []interface{}{searchQuery}
743+
seqArgs = []interface{}{searchQuery, limit}
744744
}
745745

746746
// Phase 1 fallback: FULLTEXT search for seq IDs

report-listener/handlers/handlers.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,20 @@ func (h *Handlers) GetSearchReports(c *gin.Context) {
629629
return
630630
}
631631

632+
// Get the max result limit. Keep default low for predictable latency.
633+
limit := 50
634+
if nStr := strings.TrimSpace(c.Query("n")); nStr != "" {
635+
parsedN, err := strconv.Atoi(nStr)
636+
if err != nil || parsedN <= 0 {
637+
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'n' parameter. Must be a positive integer."})
638+
return
639+
}
640+
if parsedN > 200 {
641+
parsedN = 200
642+
}
643+
limit = parsedN
644+
}
645+
632646
// Transform search query: replace "-" with "+" and add "+" before each word for boolean mode
633647
// First, replace any minus signs with plus signs
634648
searchQuery = strings.ReplaceAll(searchQuery, "-", "+")
@@ -654,7 +668,7 @@ func (h *Handlers) GetSearchReports(c *gin.Context) {
654668
}
655669

656670
// Get the reports from the database
657-
reportsInterface, err := h.db.SearchReports(c.Request.Context(), transformedQuery, classification, fullData)
671+
reportsInterface, err := h.db.SearchReports(c.Request.Context(), transformedQuery, classification, fullData, limit)
658672
if err != nil {
659673
log.Printf("Failed to search reports: %v", err)
660674
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve reports"})

0 commit comments

Comments
 (0)