Compare commits
No commits in common. "67ea7cb20fbb14416febd4bc869245c5bbe40e28" and "305beabacb6615da5f4c8b0577f3131c2ec542a3" have entirely different histories.
67ea7cb20f
...
305beabacb
@ -260,82 +260,3 @@ func (server *Server) getUserReviewByLocation(ctx *gin.Context) {
|
||||
Images: images,
|
||||
})
|
||||
}
|
||||
|
||||
type getLocationReviewGradesReq struct {
|
||||
LocationID int32 `uri:"location_id" binding:"required"`
|
||||
}
|
||||
|
||||
type locationReviewGradesGroup struct {
|
||||
AvgTasteGrade *float64 `json:"avg_taste_grade"`
|
||||
TasteGradeCount int64 `json:"taste_grade_count"`
|
||||
AvgComfortGrade *float64 `json:"avg_comfort_grade"`
|
||||
ComfortGradeCount int64 `json:"comfort_grade_count"`
|
||||
AvgCleanlinessGrade *float64 `json:"avg_cleanliness_grade"`
|
||||
CleanlinessGradeCount int64 `json:"cleanliness_grade_count"`
|
||||
AvgServiceGrade *float64 `json:"avg_service_grade"`
|
||||
ServiceGradeCount int64 `json:"service_grade_count"`
|
||||
AvgFacilitiesGrade *float64 `json:"avg_facilities_grade"`
|
||||
FacilitiesGradeCount int64 `json:"facilities_grade_count"`
|
||||
}
|
||||
|
||||
type getLocationReviewGradesRes struct {
|
||||
CriticsGrades locationReviewGradesGroup `json:"critics_grades"`
|
||||
UsersGrades locationReviewGradesGroup `json:"users_grades"`
|
||||
}
|
||||
|
||||
func nullableFloat(v pgtype.Float8) *float64 {
|
||||
if !v.Valid {
|
||||
return nil
|
||||
}
|
||||
return &v.Float64
|
||||
}
|
||||
|
||||
// @Summary Get aggregated review grades for a location
|
||||
// @Tags reviews
|
||||
// @Produce json
|
||||
// @Param location_id path int true "Location ID"
|
||||
// @Success 200 {object} getLocationReviewGradesRes
|
||||
// @Failure 400 {object} map[string]any
|
||||
// @Failure 500 {object} map[string]any
|
||||
// @Router /location/{location_id}/reviews/grades [get]
|
||||
func (server *Server) getLocationReviewGrades(ctx *gin.Context) {
|
||||
var req getLocationReviewGradesReq
|
||||
|
||||
if err := ctx.ShouldBindUri(&req); err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
|
||||
return
|
||||
}
|
||||
|
||||
grades, err := server.Store.GetLocationReviewGrades(ctx, req.LocationID)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while trying to retrieve review grades"))
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, getLocationReviewGradesRes{
|
||||
CriticsGrades: locationReviewGradesGroup{
|
||||
AvgTasteGrade: nullableFloat(grades.CriticAvgTasteGrade),
|
||||
TasteGradeCount: grades.CriticTasteGradeCount,
|
||||
AvgComfortGrade: nullableFloat(grades.CriticAvgComfortGrade),
|
||||
ComfortGradeCount: grades.CriticComfortGradeCount,
|
||||
AvgCleanlinessGrade: nullableFloat(grades.CriticAvgCleanlinessGrade),
|
||||
CleanlinessGradeCount: grades.CriticCleanlinessGradeCount,
|
||||
AvgServiceGrade: nullableFloat(grades.CriticAvgServiceGrade),
|
||||
ServiceGradeCount: grades.CriticServiceGradeCount,
|
||||
AvgFacilitiesGrade: nullableFloat(grades.CriticAvgFacilitiesGrade),
|
||||
FacilitiesGradeCount: grades.CriticFacilitiesGradeCount,
|
||||
},
|
||||
UsersGrades: locationReviewGradesGroup{
|
||||
AvgTasteGrade: nullableFloat(grades.UserAvgTasteGrade),
|
||||
TasteGradeCount: grades.UserTasteGradeCount,
|
||||
AvgComfortGrade: nullableFloat(grades.UserAvgComfortGrade),
|
||||
ComfortGradeCount: grades.UserComfortGradeCount,
|
||||
AvgCleanlinessGrade: nullableFloat(grades.UserAvgCleanlinessGrade),
|
||||
CleanlinessGradeCount: grades.UserCleanlinessGradeCount,
|
||||
AvgServiceGrade: nullableFloat(grades.UserAvgServiceGrade),
|
||||
ServiceGradeCount: grades.UserServiceGradeCount,
|
||||
AvgFacilitiesGrade: nullableFloat(grades.UserAvgFacilitiesGrade),
|
||||
FacilitiesGradeCount: grades.UserFacilitiesGradeCount,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -91,7 +91,6 @@ func (server *Server) getRoutes() {
|
||||
router.GET("/location/tags/:location_id", server.getTagsByLocation)
|
||||
router.GET("/location/reviews", server.getListLocationReviews)
|
||||
router.GET("/location/:location_id/review/:review_id", server.getReview)
|
||||
router.GET("/location/grades/:location_id", server.getLocationReviewGrades)
|
||||
router.GET("/locations/search", server.searchLocations)
|
||||
router.POST("/location/:location_id/visit", server.recordLocationVisit)
|
||||
|
||||
|
||||
BIN
db/.DS_Store
vendored
BIN
db/.DS_Store
vendored
Binary file not shown.
@ -1,16 +1,13 @@
|
||||
id,address,name,google_maps_link,location_type,submitted_by,thumbnail,regency_id,is_deleted,created_at,updated_at,approved_by,approved_at,amenities,business_hours
|
||||
1,Jalan Raya Beside the bridge Ubud,Murni's Warung,"https://www.google.com/maps/place/Murni's+Warung/@-8.5048696,115.2553417,19z/data=!4m6!3m5!1s0x2dd23d3e0ffaa071:0xf2fa69b4cb211e41!8m2!3d-8.5051184!4d115.2547196!16s%2Fg%2F1tdsmcq7?entry=ttu",culinary,1,https://cdn.discordapp.com/attachments/743422487882104837/1150972798320267304/image.png,5104,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
2,Jl.Taman Wijaya Kusuma Ps. Baru Kecamatan Sawah Besar,Masjid Istiqlal,"https://www.google.com/maps/place/Masjid+Istiqlal/@-6.1703155,106.8308434,19z/data=!4m15!1m7!3m6!1s0x2e69f5ce68b5e01d:0xcafaf042d5840c6c!2sMasjid+Istiqlal!8m2!3d-6.17017!4d106.83139!16zL20vMDRzam1q!3m6!1s0x2e69f5ce68b5e01d:0xcafaf042d5840c6c!8m2!3d-6.17017!4d106.83139!15sCg9tYXNqaWQgaXN0aXFsYWxaESIPbWFzamlkIGlzdGlxbGFskgEGbW9zcXVl4AEA!16zL20vMDRzam1q?entry=ttu",other,1,https://dynamic-media-cdn.tripadvisor.com/media/photo-o/04/11/31/33/istiqlal-mosque-mesjid.jpg?w=500&h=-1&s=1,3173,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
3,Jl. Mayjend Sungkono no. 89,Hotel Ciputra World Surabaya,"https://www.google.com/maps/place/Ciputra+World+Hotel+Surabaya/@-7.2923061,112.7191552,15z/data=!4m2!3m1!1s0x0:0x736a9c49dcc2ac42?sa=X&ved=2ahUKEwjJlbf8gqSBAxWtzzgGHUIkBFYQ_BJ6BAgVEAA&ved=2ahUKEwjJlbf8gqSBAxWtzzgGHUIkBFYQ_BJ6BAgjEAc",accommodation,1,https://lh5.googleusercontent.com/p/AF1QipOvHDO-M6riRoqBrWU3MskhwL_bue8JmN9faq7Q=w500-h500-k-no,3578,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
4,Jl. Taman Safari No.101 . B Cibeureum Kec. Cisarua,Club Huis,"https://www.google.com/maps/place/Club+Huis/@-6.7027857,106.9453741,17z/data=!3m1!4b1!4m6!3m5!1s0x2e69b679d7a09e01:0xf9fc2df396f09977!8m2!3d-6.7027857!4d106.947949!16s%2Fg%2F11c57lh8ky?entry=ttu",recreation,1,https://media-cdn.tripadvisor.com/media/photo-o/0d/6a/5d/63/our-peaceful-backyard.jpg,3201,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
5,Desa Tambakrejo Kecamatan Sumbermanjing Wetan,Pulau Sempu,"https://www.google.com/maps/place/Pulau+Sempu/@-8.446621,112.6746143,14z/data=!3m1!4b1!4m6!3m5!1s0x2dd60120edbc901f:0x8efd89687a308993!8m2!3d-8.4428564!4d112.6973355!16s%2Fm%2F0r8k540?entry=ttu",recreation,1,https://dynamic-media-cdn.tripadvisor.com/media/photo-o/11/3b/06/a5/pulau-sempu.jpg?w=500&h=-1&s=1,3507,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
6,Jl. Bukit Golf I BSD Sektor VI Lengkong Karya Kec. Serpong Utara,Damai Indah Golf,"https://www.google.com/maps/place/Damai+Indah+Golf+-+BSD+Course/@-6.2815644,106.6496566,17z/data=!3m1!4b1!4m6!3m5!1s0x2e69fb152983d973:0x89e58e219f8b93ef!8m2!3d-6.2815644!4d106.6522315!16s%2Fg%2F11c54c9r94?entry=ttu",recreation,1,https://lh3.googleusercontent.com/p/AF1QipN5Z-0J6vIfIO6gqPO0z5HDWlNKqp0t816XIJPS=s680-w500-h500,3674,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
7,Jl. P. Mangkubumi No.72A Cokrodiningratan Kec. Jetis,Hotel Tentrem Yogyakarta,https://www.google.com/maps?q=Hotel+Tentrem+Yogyakarta&source=lmns&entry=mc&bih=1115&biw=2124&hl=en-US&sa=X&ved=2ahUKEwjjl-HHiKSBAxUu5jgGHTU3BiwQ0pQJKAJ6BAgBEAY,accommodation,1,https://cdn.discordapp.com/attachments/743422487882104837/1150987888553623653/image.png,3471,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
8,Moluo Kec.Kwandang,Pulau Saronde Gorontalo,"https://www.google.com/maps/place/Pulau+Saronde+Gorontalo/@0.9263376,122.8613201,17z/data=!3m1!4b1!4m6!3m5!1s0x32795bf34dff4467:0xa8beb2a832ae8176!8m2!3d0.9263376!4d122.863895!16s%2Fg%2F11l241cc1d?hl=id&entry=ttu",recreation,1,https://dynamic-media-cdn.tripadvisor.com/media/photo-o/0d/ec/58/21/saronde-island-a-place.jpg?w=700&h=-1&s=1,7505,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
9,Dusun Katiet Desa Bosua Kecamatan Sipora,Pantai Katiet,"https://www.google.com/maps/place/Katiet,+Bosua,+Sipora+Selatan,+Mentawai+Islands+Regency,+West+Sumatra/@-2.375793,99.848187,15z/data=!3m1!4b1!4m6!3m5!1s0x2fd27efa8363912f:0x8c9c19bd76cba179!8m2!3d-2.375793!4d99.848187!16s%2Fg%2F1tcwz0mt?hl=en-US&entry=ttu",recreation,1,https://dynamic-media-cdn.tripadvisor.com/media/photo-o/1a/d7/fe/f4/mentawai-islands.jpg?w=500&h=-1&s=1,1301,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
10,Pulau Padar,Pulau Padar,"https://www.google.com/maps/place/Pulau+Padar/@-8.6554183,119.570686,14.83z/data=!4m6!3m5!1s0x2db4f84ff6cd01ab:0xf7e6fd33b692a898!8m2!3d-8.6489909!4d119.5832593!16s%2Fg%2F121d16wd?entry=ttu",recreation,2,https://dynamic-media-cdn.tripadvisor.com/media/photo-o/18/4e/11/f3/padar-island.jpg?w=800&h=-1&s=1,5315,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
11,"Jl. Ahmad Yani 18, Kel. Kelimutu, Kec. Ende Tengah",Sari rasa,"https://www.google.com/maps/place/Rumah+Makan+Cha+Cha/@-8.6153697,120.4652533,21z/data=!4m6!3m5!1s0x2db37469e54c0dd3:0x36ac988c726ed544!8m2!3d-8.6153631!4d120.465275!16s%2Fg%2F11bwpclp91?entry=ttu",culinary,3,https://cdn.discordapp.com/attachments/743422487882104837/1151903310295601172/image.png,5315,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
12,Danau Sentani,Danau Sentani,"https://www.google.com/maps/place/Danau+Sentani/@-2.639976,140.3889748,12.46z/data=!4m7!3m6!1s0x686cf33c72660fbf:0x7e5c1e7d20d930d7!4b1!8m2!3d-2.6133004!4d140.518734!16s%2Fm%2F0tkjf6v?entry=ttu",recreation,3,https://dynamic-media-cdn.tripadvisor.com/media/photo-o/1a/c7/e8/17/20190630-143008-largejpg.jpg?w=800&h=-1&s=1,9403,false,2026-04-12 23:50:04.608443,2026-04-12 23:50:04.608443,1,,,
|
||||
19,natohentoahe,aosenhatohe,aoeaoeaoe,mall,4,,1112,false,2026-06-01 09:19:04.996652,2026-06-01 09:19:04.996652,,,"[{""Food & Beverages"": [""Solaria"", ""J.CO Donuts"", ""Pizza Hut"", ""Chatime""]}, {""Fashion"": [""Pull&Bear"", ""Nevada""]}, {""Sports"": [""Reebok"", ""Puma"", ""Nike"", ""Mills""]}, {""Health & Beauty"": [""The Body Shop"", ""Miniso"", ""Innisfree""]}]",
|
||||
20,aoeaoeaoeoae,aoeaoe,aoeaoeoaeaoe,culinary,4,,1118,false,2026-06-06 23:29:37.459913,2026-06-06 23:29:37.459913,,,,
|
||||
21,aotehsnatohesntaho,aoedhnaohesnth,aoeaoeaoeaoeaoe,culinary,4,,1409,false,2026-06-11 12:52:23.675860,2026-06-11 12:52:23.675860,1,,"[{""Facilities"": [""Live Music"", ""Outdoor Seating""]}, {""Services"": [""Parking"", ""Takeout""]}, {""Food Options"": [""Vegetarian"", ""Vegan""]}]","[{""day"": ""Sunday"", ""closed"": true}, {""day"": ""Monday"", ""closed"": true}, {""day"": ""Tuesday"", ""open"": ""09:00"", ""close"": ""21:00""}, {""day"": ""Wednesday"", ""open"": ""09:00"", ""close"": ""21:00""}, {""day"": ""Thursday"", ""open"": ""09:00"", ""close"": ""21:00""}, {""day"": ""Friday"", ""open"": ""09:00"", ""close"": ""21:00""}, {""day"": ""Saturday"", ""open"": ""09:00"", ""close"": ""21:00""}]"
|
||||
id,location_type,address,name,submitted_by,thumbnail,regency_id,google_maps_link,approved_by,is_deleted
|
||||
1#culinary#Jalan Raya Beside the bridge Ubud#Murni’s Warung#1#https://cdn.discordapp.com/attachments/743422487882104837/1150972798320267304/image.png#5104#https://www.google.com/maps/place/Murni's+Warung/@-8.5048696,115.2553417,19z/data=!4m6!3m5!1s0x2dd23d3e0ffaa071:0xf2fa69b4cb211e41!8m2!3d-8.5051184!4d115.2547196!16s%2Fg%2F1tdsmcq7?entry=ttu#1#false
|
||||
2#other#Jl.Taman Wijaya Kusuma Ps. Baru Kecamatan Sawah Besar#Masjid Istiqlal#1#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/04/11/31/33/istiqlal-mosque-mesjid.jpg?w=500&h=-1&s=1#3173#https://www.google.com/maps/place/Masjid+Istiqlal/@-6.1703155,106.8308434,19z/data=!4m15!1m7!3m6!1s0x2e69f5ce68b5e01d:0xcafaf042d5840c6c!2sMasjid+Istiqlal!8m2!3d-6.17017!4d106.83139!16zL20vMDRzam1q!3m6!1s0x2e69f5ce68b5e01d:0xcafaf042d5840c6c!8m2!3d-6.17017!4d106.83139!15sCg9tYXNqaWQgaXN0aXFsYWxaESIPbWFzamlkIGlzdGlxbGFskgEGbW9zcXVl4AEA!16zL20vMDRzam1q?entry=ttu#1#false
|
||||
3#accommodation#Jl. Mayjend Sungkono no. 89#Hotel Ciputra World Surabaya#1#https://lh5.googleusercontent.com/p/AF1QipOvHDO-M6riRoqBrWU3MskhwL_bue8JmN9faq7Q=w500-h500-k-no#3578#https://www.google.com/maps/place/Ciputra+World+Hotel+Surabaya/@-7.2923061,112.7191552,15z/data=!4m2!3m1!1s0x0:0x736a9c49dcc2ac42?sa=X&ved=2ahUKEwjJlbf8gqSBAxWtzzgGHUIkBFYQ_BJ6BAgVEAA&ved=2ahUKEwjJlbf8gqSBAxWtzzgGHUIkBFYQ_BJ6BAgjEAc#1#false
|
||||
4#recreation#Jl. Taman Safari No.101 . B Cibeureum Kec. Cisarua#Club Huis#1#https://media-cdn.tripadvisor.com/media/photo-o/0d/6a/5d/63/our-peaceful-backyard.jpg#3201#https://www.google.com/maps/place/Club+Huis/@-6.7027857,106.9453741,17z/data=!3m1!4b1!4m6!3m5!1s0x2e69b679d7a09e01:0xf9fc2df396f09977!8m2!3d-6.7027857!4d106.947949!16s%2Fg%2F11c57lh8ky?entry=ttu#1#false
|
||||
5#recreation#Desa Tambakrejo Kecamatan Sumbermanjing Wetan#Pulau Sempu#1#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/11/3b/06/a5/pulau-sempu.jpg?w=500&h=-1&s=1#3507#https://www.google.com/maps/place/Pulau+Sempu/@-8.446621,112.6746143,14z/data=!3m1!4b1!4m6!3m5!1s0x2dd60120edbc901f:0x8efd89687a308993!8m2!3d-8.4428564!4d112.6973355!16s%2Fm%2F0r8k540?entry=ttu#1#false
|
||||
6#recreation#Jl. Bukit Golf I BSD Sektor VI Lengkong Karya Kec. Serpong Utara#Damai Indah Golf#1#https://lh3.googleusercontent.com/p/AF1QipN5Z-0J6vIfIO6gqPO0z5HDWlNKqp0t816XIJPS=s680-w500-h500#3674#https://www.google.com/maps/place/Damai+Indah+Golf+-+BSD+Course/@-6.2815644,106.6496566,17z/data=!3m1!4b1!4m6!3m5!1s0x2e69fb152983d973:0x89e58e219f8b93ef!8m2!3d-6.2815644!4d106.6522315!16s%2Fg%2F11c54c9r94?entry=ttu#1#false
|
||||
7#accommodation#Jl. P. Mangkubumi No.72A Cokrodiningratan Kec. Jetis#Hotel Tentrem Yogyakarta#1#https://cdn.discordapp.com/attachments/743422487882104837/1150987888553623653/image.png#3471#https://www.google.com/maps?q=Hotel+Tentrem+Yogyakarta&source=lmns&entry=mc&bih=1115&biw=2124&hl=en-US&sa=X&ved=2ahUKEwjjl-HHiKSBAxUu5jgGHTU3BiwQ0pQJKAJ6BAgBEAY#1#false
|
||||
8#recreation#Moluo Kec.Kwandang#Pulau Saronde Gorontalo#1#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/0d/ec/58/21/saronde-island-a-place.jpg?w=700&h=-1&s=1#7505#https://www.google.com/maps/place/Pulau+Saronde+Gorontalo/@0.9263376,122.8613201,17z/data=!3m1!4b1!4m6!3m5!1s0x32795bf34dff4467:0xa8beb2a832ae8176!8m2!3d0.9263376!4d122.863895!16s%2Fg%2F11l241cc1d?hl=id&entry=ttu#1#false
|
||||
9#recreation#Dusun Katiet Desa Bosua Kecamatan Sipora#Pantai Katiet#1#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/1a/d7/fe/f4/mentawai-islands.jpg?w=500&h=-1&s=1#1301#https://www.google.com/maps/place/Katiet,+Bosua,+Sipora+Selatan,+Mentawai+Islands+Regency,+West+Sumatra/@-2.375793,99.848187,15z/data=!3m1!4b1!4m6!3m5!1s0x2fd27efa8363912f:0x8c9c19bd76cba179!8m2!3d-2.375793!4d99.848187!16s%2Fg%2F1tcwz0mt?hl=en-US&entry=ttu#1#false
|
||||
10#recreation#Pulau Padar#Pulau Padar#2#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/18/4e/11/f3/padar-island.jpg?w=800&h=-1&s=1#5315#https://www.google.com/maps/place/Pulau+Padar/@-8.6554183,119.570686,14.83z/data=!4m6!3m5!1s0x2db4f84ff6cd01ab:0xf7e6fd33b692a898!8m2!3d-8.6489909!4d119.5832593!16s%2Fg%2F121d16wd?entry=ttu#1#false
|
||||
11#culinary#Jl. Ahmad Yani 18, Kel. Kelimutu, Kec. Ende Tengah#Sari rasa#3#https://cdn.discordapp.com/attachments/743422487882104837/1151903310295601172/image.png#5315#https://www.google.com/maps/place/Rumah+Makan+Cha+Cha/@-8.6153697,120.4652533,21z/data=!4m6!3m5!1s0x2db37469e54c0dd3:0x36ac988c726ed544!8m2!3d-8.6153631!4d120.465275!16s%2Fg%2F11bwpclp91?entry=ttu#1#false
|
||||
12#recreation#Danau Sentani#Danau Sentani#3#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/1a/c7/e8/17/20190630-143008-largejpg.jpg?w=800&h=-1&s=1#9403#https://www.google.com/maps/place/Danau+Sentani/@-2.639976,140.3889748,12.46z/data=!4m7!3m6!1s0x686cf33c72660fbf:0x7e5c1e7d20d930d7!4b1!8m2!3d-2.6133004!4d140.518734!16s%2Fm%2F0tkjf6v?entry=ttu#1#false
|
||||
|
@ -338,21 +338,6 @@ func (mr *MockStoreMockRecorder) GetLocationLifetimeVisits(ctx, locationID any)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLocationLifetimeVisits", reflect.TypeOf((*MockStore)(nil).GetLocationLifetimeVisits), ctx, locationID)
|
||||
}
|
||||
|
||||
// GetLocationReviewGrades mocks base method.
|
||||
func (m *MockStore) GetLocationReviewGrades(ctx context.Context, locationID int32) (db.GetLocationReviewGradesRow, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetLocationReviewGrades", ctx, locationID)
|
||||
ret0, _ := ret[0].(db.GetLocationReviewGradesRow)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetLocationReviewGrades indicates an expected call of GetLocationReviewGrades.
|
||||
func (mr *MockStoreMockRecorder) GetLocationReviewGrades(ctx, locationID any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLocationReviewGrades", reflect.TypeOf((*MockStore)(nil).GetLocationReviewGrades), ctx, locationID)
|
||||
}
|
||||
|
||||
// GetLocationTag mocks base method.
|
||||
func (m *MockStore) GetLocationTag(ctx context.Context, targetID int32) ([]string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@ -146,84 +146,6 @@ func (q *Queries) GetReviewByLocationAndId(ctx context.Context, arg GetReviewByL
|
||||
return i, err
|
||||
}
|
||||
|
||||
type GetLocationReviewGradesRow struct {
|
||||
CriticAvgTasteGrade pgtype.Float8 `json:"critic_avg_taste_grade"`
|
||||
CriticTasteGradeCount int64 `json:"critic_taste_grade_count"`
|
||||
CriticAvgComfortGrade pgtype.Float8 `json:"critic_avg_comfort_grade"`
|
||||
CriticComfortGradeCount int64 `json:"critic_comfort_grade_count"`
|
||||
CriticAvgCleanlinessGrade pgtype.Float8 `json:"critic_avg_cleanliness_grade"`
|
||||
CriticCleanlinessGradeCount int64 `json:"critic_cleanliness_grade_count"`
|
||||
CriticAvgServiceGrade pgtype.Float8 `json:"critic_avg_service_grade"`
|
||||
CriticServiceGradeCount int64 `json:"critic_service_grade_count"`
|
||||
CriticAvgFacilitiesGrade pgtype.Float8 `json:"critic_avg_facilities_grade"`
|
||||
CriticFacilitiesGradeCount int64 `json:"critic_facilities_grade_count"`
|
||||
|
||||
UserAvgTasteGrade pgtype.Float8 `json:"user_avg_taste_grade"`
|
||||
UserTasteGradeCount int64 `json:"user_taste_grade_count"`
|
||||
UserAvgComfortGrade pgtype.Float8 `json:"user_avg_comfort_grade"`
|
||||
UserComfortGradeCount int64 `json:"user_comfort_grade_count"`
|
||||
UserAvgCleanlinessGrade pgtype.Float8 `json:"user_avg_cleanliness_grade"`
|
||||
UserCleanlinessGradeCount int64 `json:"user_cleanliness_grade_count"`
|
||||
UserAvgServiceGrade pgtype.Float8 `json:"user_avg_service_grade"`
|
||||
UserServiceGradeCount int64 `json:"user_service_grade_count"`
|
||||
UserAvgFacilitiesGrade pgtype.Float8 `json:"user_avg_facilities_grade"`
|
||||
UserFacilitiesGradeCount int64 `json:"user_facilities_grade_count"`
|
||||
}
|
||||
|
||||
const getLocationReviewGrades = `
|
||||
SELECT
|
||||
AVG(re.taste_grade) FILTER (WHERE re.is_from_critic = true)::float8 AS critic_avg_taste_grade,
|
||||
COUNT(re.taste_grade) FILTER (WHERE re.is_from_critic = true) AS critic_taste_grade_count,
|
||||
AVG(re.comfort_grade) FILTER (WHERE re.is_from_critic = true)::float8 AS critic_avg_comfort_grade,
|
||||
COUNT(re.comfort_grade) FILTER (WHERE re.is_from_critic = true) AS critic_comfort_grade_count,
|
||||
AVG(re.cleanliness_grade) FILTER (WHERE re.is_from_critic = true)::float8 AS critic_avg_cleanliness_grade,
|
||||
COUNT(re.cleanliness_grade) FILTER (WHERE re.is_from_critic = true) AS critic_cleanliness_grade_count,
|
||||
AVG(re.service_grade) FILTER (WHERE re.is_from_critic = true)::float8 AS critic_avg_service_grade,
|
||||
COUNT(re.service_grade) FILTER (WHERE re.is_from_critic = true) AS critic_service_grade_count,
|
||||
AVG(re.facilities_grade) FILTER (WHERE re.is_from_critic = true)::float8 AS critic_avg_facilities_grade,
|
||||
COUNT(re.facilities_grade) FILTER (WHERE re.is_from_critic = true) AS critic_facilities_grade_count,
|
||||
AVG(re.taste_grade) FILTER (WHERE re.is_from_critic = false)::float8 AS user_avg_taste_grade,
|
||||
COUNT(re.taste_grade) FILTER (WHERE re.is_from_critic = false) AS user_taste_grade_count,
|
||||
AVG(re.comfort_grade) FILTER (WHERE re.is_from_critic = false)::float8 AS user_avg_comfort_grade,
|
||||
COUNT(re.comfort_grade) FILTER (WHERE re.is_from_critic = false) AS user_comfort_grade_count,
|
||||
AVG(re.cleanliness_grade) FILTER (WHERE re.is_from_critic = false)::float8 AS user_avg_cleanliness_grade,
|
||||
COUNT(re.cleanliness_grade) FILTER (WHERE re.is_from_critic = false) AS user_cleanliness_grade_count,
|
||||
AVG(re.service_grade) FILTER (WHERE re.is_from_critic = false)::float8 AS user_avg_service_grade,
|
||||
COUNT(re.service_grade) FILTER (WHERE re.is_from_critic = false) AS user_service_grade_count,
|
||||
AVG(re.facilities_grade) FILTER (WHERE re.is_from_critic = false)::float8 AS user_avg_facilities_grade,
|
||||
COUNT(re.facilities_grade) FILTER (WHERE re.is_from_critic = false) AS user_facilities_grade_count
|
||||
FROM reviews re
|
||||
WHERE re.location_id = $1 AND re.is_hided = false;
|
||||
`
|
||||
|
||||
func (q *Queries) GetLocationReviewGrades(ctx context.Context, locationID int32) (GetLocationReviewGradesRow, error) {
|
||||
row := q.db.QueryRow(ctx, getLocationReviewGrades, locationID)
|
||||
var i GetLocationReviewGradesRow
|
||||
err := row.Scan(
|
||||
&i.CriticAvgTasteGrade,
|
||||
&i.CriticTasteGradeCount,
|
||||
&i.CriticAvgComfortGrade,
|
||||
&i.CriticComfortGradeCount,
|
||||
&i.CriticAvgCleanlinessGrade,
|
||||
&i.CriticCleanlinessGradeCount,
|
||||
&i.CriticAvgServiceGrade,
|
||||
&i.CriticServiceGradeCount,
|
||||
&i.CriticAvgFacilitiesGrade,
|
||||
&i.CriticFacilitiesGradeCount,
|
||||
&i.UserAvgTasteGrade,
|
||||
&i.UserTasteGradeCount,
|
||||
&i.UserAvgComfortGrade,
|
||||
&i.UserComfortGradeCount,
|
||||
&i.UserAvgCleanlinessGrade,
|
||||
&i.UserCleanlinessGradeCount,
|
||||
&i.UserAvgServiceGrade,
|
||||
&i.UserServiceGradeCount,
|
||||
&i.UserAvgFacilitiesGrade,
|
||||
&i.UserFacilitiesGradeCount,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
func (q *Queries) GetListLocationReviews(ctx context.Context, arg GetListLocationReviewsParams) ([]GetListLocationReviewsRow, error) {
|
||||
rows, err := q.db.Query(ctx, getListLocationReviews, arg.LocationID, arg.IsCritics, arg.Limit, arg.Offset)
|
||||
if err != nil {
|
||||
|
||||
@ -29,7 +29,6 @@ type Store interface {
|
||||
RecordLocationVisit(ctx context.Context, locationID int32) error
|
||||
GetLocationLifetimeVisits(ctx context.Context, locationID int32) (int64, error)
|
||||
GetTrendingLocations(ctx context.Context, arg GetTrendingLocationsParams) ([]GetTrendingLocationsRow, error)
|
||||
GetLocationReviewGrades(ctx context.Context, locationID int32) (GetLocationReviewGradesRow, error)
|
||||
}
|
||||
|
||||
type SQLStore struct {
|
||||
|
||||
264
docs/docs.go
264
docs/docs.go
@ -258,88 +258,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/location/{location_id}/reviews/grades": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"reviews"
|
||||
],
|
||||
"summary": "Get aggregated review grades for a location",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Location ID",
|
||||
"name": "location_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.getLocationReviewGradesRes"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/location/{location_id}/visit": {
|
||||
"post": {
|
||||
"description": "Increments today's visit bucket. A single client (IP) is rate-limited to one visit per location per 30 minutes via Redis to deter trivial F5 inflation.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"locations"
|
||||
],
|
||||
"summary": "Record a page visit for a location",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Location ID",
|
||||
"name": "location_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/locations": {
|
||||
"get": {
|
||||
"produces": [
|
||||
@ -438,12 +356,6 @@ const docTemplate = `{
|
||||
"name": "amenities",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Business hours JSON: [{\\",
|
||||
"name": "business_hours",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Google Maps link",
|
||||
@ -624,104 +536,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/locations/trending": {
|
||||
"get": {
|
||||
"description": "Ranks approved, non-deleted locations by total page-visits in the trailing window.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"locations"
|
||||
],
|
||||
"summary": "Trending locations",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Window: week | month | 3month | semester | year",
|
||||
"name": "window",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Page (min 1)",
|
||||
"name": "page",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Page size (1-50)",
|
||||
"name": "page_size",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/menu-items": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"menu"
|
||||
],
|
||||
"summary": "Get menu items",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Filter by location ID (omit for all)",
|
||||
"name": "location_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/db.GetMenuItemsRow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/news-events": {
|
||||
"get": {
|
||||
"produces": [
|
||||
@ -1373,84 +1187,6 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.getLocationReviewGradesRes": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"critics_grades": {
|
||||
"$ref": "#/definitions/api.locationReviewGradesGroup"
|
||||
},
|
||||
"users_grades": {
|
||||
"$ref": "#/definitions/api.locationReviewGradesGroup"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.locationReviewGradesGroup": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"avg_cleanliness_grade": {
|
||||
"type": "number"
|
||||
},
|
||||
"avg_comfort_grade": {
|
||||
"type": "number"
|
||||
},
|
||||
"avg_facilities_grade": {
|
||||
"type": "number"
|
||||
},
|
||||
"avg_service_grade": {
|
||||
"type": "number"
|
||||
},
|
||||
"avg_taste_grade": {
|
||||
"type": "number"
|
||||
},
|
||||
"cleanliness_grade_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"comfort_grade_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"facilities_grade_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"service_grade_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"taste_grade_count": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"db.GetMenuItemsRow": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"avg_score": {
|
||||
"type": "number"
|
||||
},
|
||||
"category": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"is_available": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"location_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"price": {
|
||||
"type": "integer"
|
||||
},
|
||||
"submitted_by": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
|
||||
@ -252,88 +252,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/location/{location_id}/reviews/grades": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"reviews"
|
||||
],
|
||||
"summary": "Get aggregated review grades for a location",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Location ID",
|
||||
"name": "location_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.getLocationReviewGradesRes"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/location/{location_id}/visit": {
|
||||
"post": {
|
||||
"description": "Increments today's visit bucket. A single client (IP) is rate-limited to one visit per location per 30 minutes via Redis to deter trivial F5 inflation.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"locations"
|
||||
],
|
||||
"summary": "Record a page visit for a location",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Location ID",
|
||||
"name": "location_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/locations": {
|
||||
"get": {
|
||||
"produces": [
|
||||
@ -432,12 +350,6 @@
|
||||
"name": "amenities",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Business hours JSON: [{\\",
|
||||
"name": "business_hours",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Google Maps link",
|
||||
@ -618,104 +530,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/locations/trending": {
|
||||
"get": {
|
||||
"description": "Ranks approved, non-deleted locations by total page-visits in the trailing window.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"locations"
|
||||
],
|
||||
"summary": "Trending locations",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Window: week | month | 3month | semester | year",
|
||||
"name": "window",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Page (min 1)",
|
||||
"name": "page",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Page size (1-50)",
|
||||
"name": "page_size",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/menu-items": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"menu"
|
||||
],
|
||||
"summary": "Get menu items",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Filter by location ID (omit for all)",
|
||||
"name": "location_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/db.GetMenuItemsRow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/news-events": {
|
||||
"get": {
|
||||
"produces": [
|
||||
@ -1367,84 +1181,6 @@
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.getLocationReviewGradesRes": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"critics_grades": {
|
||||
"$ref": "#/definitions/api.locationReviewGradesGroup"
|
||||
},
|
||||
"users_grades": {
|
||||
"$ref": "#/definitions/api.locationReviewGradesGroup"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.locationReviewGradesGroup": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"avg_cleanliness_grade": {
|
||||
"type": "number"
|
||||
},
|
||||
"avg_comfort_grade": {
|
||||
"type": "number"
|
||||
},
|
||||
"avg_facilities_grade": {
|
||||
"type": "number"
|
||||
},
|
||||
"avg_service_grade": {
|
||||
"type": "number"
|
||||
},
|
||||
"avg_taste_grade": {
|
||||
"type": "number"
|
||||
},
|
||||
"cleanliness_grade_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"comfort_grade_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"facilities_grade_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"service_grade_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"taste_grade_count": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"db.GetMenuItemsRow": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"avg_score": {
|
||||
"type": "number"
|
||||
},
|
||||
"category": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"is_available": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"location_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"price": {
|
||||
"type": "integer"
|
||||
},
|
||||
"submitted_by": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
|
||||
@ -58,57 +58,6 @@ definitions:
|
||||
- password
|
||||
- username
|
||||
type: object
|
||||
api.getLocationReviewGradesRes:
|
||||
properties:
|
||||
critics_grades:
|
||||
$ref: '#/definitions/api.locationReviewGradesGroup'
|
||||
users_grades:
|
||||
$ref: '#/definitions/api.locationReviewGradesGroup'
|
||||
type: object
|
||||
api.locationReviewGradesGroup:
|
||||
properties:
|
||||
avg_cleanliness_grade:
|
||||
type: number
|
||||
avg_comfort_grade:
|
||||
type: number
|
||||
avg_facilities_grade:
|
||||
type: number
|
||||
avg_service_grade:
|
||||
type: number
|
||||
avg_taste_grade:
|
||||
type: number
|
||||
cleanliness_grade_count:
|
||||
type: integer
|
||||
comfort_grade_count:
|
||||
type: integer
|
||||
facilities_grade_count:
|
||||
type: integer
|
||||
service_grade_count:
|
||||
type: integer
|
||||
taste_grade_count:
|
||||
type: integer
|
||||
type: object
|
||||
db.GetMenuItemsRow:
|
||||
properties:
|
||||
avg_score:
|
||||
type: number
|
||||
category:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
is_available:
|
||||
type: boolean
|
||||
location_id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
price:
|
||||
type: integer
|
||||
submitted_by:
|
||||
type: integer
|
||||
type: object
|
||||
host: localhost:8888
|
||||
info:
|
||||
contact: {}
|
||||
@ -215,62 +164,6 @@ paths:
|
||||
summary: Get a single review
|
||||
tags:
|
||||
- reviews
|
||||
/location/{location_id}/reviews/grades:
|
||||
get:
|
||||
parameters:
|
||||
- description: Location ID
|
||||
in: path
|
||||
name: location_id
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/api.getLocationReviewGradesRes'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
summary: Get aggregated review grades for a location
|
||||
tags:
|
||||
- reviews
|
||||
/location/{location_id}/visit:
|
||||
post:
|
||||
description: Increments today's visit bucket. A single client (IP) is rate-limited
|
||||
to one visit per location per 30 minutes via Redis to deter trivial F5 inflation.
|
||||
parameters:
|
||||
- description: Location ID
|
||||
in: path
|
||||
name: location_id
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
summary: Record a page visit for a location
|
||||
tags:
|
||||
- locations
|
||||
/location/reviews:
|
||||
get:
|
||||
parameters:
|
||||
@ -400,10 +293,6 @@ paths:
|
||||
in: formData
|
||||
name: amenities
|
||||
type: string
|
||||
- description: 'Business hours JSON: [{\'
|
||||
in: formData
|
||||
name: business_hours
|
||||
type: string
|
||||
- description: Google Maps link
|
||||
in: formData
|
||||
name: google_maps_link
|
||||
@ -527,73 +416,6 @@ paths:
|
||||
summary: Top-rated locations
|
||||
tags:
|
||||
- locations
|
||||
/locations/trending:
|
||||
get:
|
||||
description: Ranks approved, non-deleted locations by total page-visits in the
|
||||
trailing window.
|
||||
parameters:
|
||||
- description: 'Window: week | month | 3month | semester | year'
|
||||
in: query
|
||||
name: window
|
||||
required: true
|
||||
type: string
|
||||
- description: Page (min 1)
|
||||
in: query
|
||||
name: page
|
||||
required: true
|
||||
type: integer
|
||||
- description: Page size (1-50)
|
||||
in: query
|
||||
name: page_size
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
type: array
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
summary: Trending locations
|
||||
tags:
|
||||
- locations
|
||||
/menu-items:
|
||||
get:
|
||||
parameters:
|
||||
- description: Filter by location ID (omit for all)
|
||||
in: query
|
||||
name: location_id
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/db.GetMenuItemsRow'
|
||||
type: array
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
summary: Get menu items
|
||||
tags:
|
||||
- menu
|
||||
/news-events:
|
||||
get:
|
||||
parameters:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user