hiling_go/docs/swagger.json
2026-06-16 19:38:23 +03:00

1457 lines
48 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"swagger": "2.0",
"info": {
"description": "REST API for Hiling — a location review and discovery platform.",
"title": "Hiling API",
"contact": {},
"version": "1.0"
},
"host": "localhost:8888",
"basePath": "/",
"paths": {
"/images/location": {
"get": {
"produces": [
"application/json"
],
"tags": [
"images"
],
"summary": "Get all images for a location",
"parameters": [
{
"type": "integer",
"description": "Location ID",
"name": "location_id",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Page (min 1)",
"name": "page",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Page size (min 5)",
"name": "page_size",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/location/reviews": {
"get": {
"produces": [
"application/json"
],
"tags": [
"locations"
],
"summary": "List location reviews",
"parameters": [
{
"type": "integer",
"description": "Location ID",
"name": "location_id",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Page (min 1)",
"name": "page",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Page size",
"name": "page_size",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Review type: 1=critics, 2=users, 0=all",
"name": "type",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/location/tags/{location_id}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"locations"
],
"summary": "Get tags for a location",
"parameters": [
{
"type": "integer",
"description": "Location ID",
"name": "location_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/location/{location_id}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"locations"
],
"summary": "Get location detail",
"parameters": [
{
"type": "integer",
"description": "Location ID",
"name": "location_id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Review type: 'user', 'critics', or both (default)",
"name": "review",
"in": "query"
},
{
"type": "integer",
"description": "Page (default 1)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "Page size (default 5)",
"name": "page_size",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"404": {
"description": "Not Found",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/location/{location_id}/review/{review_id}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"reviews"
],
"summary": "Get a single review",
"parameters": [
{
"type": "integer",
"description": "Location ID",
"name": "location_id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Review ID",
"name": "review_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"404": {
"description": "Not Found",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/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": [
"application/json"
],
"tags": [
"locations"
],
"summary": "List locations",
"parameters": [
{
"type": "integer",
"description": "Page number (min 1)",
"name": "page",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Page size (min 5)",
"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
}
}
}
},
"post": {
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"locations"
],
"summary": "Create a location",
"parameters": [
{
"type": "string",
"description": "Address",
"name": "address",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "Name",
"name": "name",
"in": "formData",
"required": true
},
{
"type": "integer",
"description": "Submitted by user ID",
"name": "submitted_by",
"in": "formData",
"required": true
},
{
"type": "integer",
"description": "Regency ID",
"name": "regency_id",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "Location type",
"name": "location_type",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "Amenities (comma-separated)",
"name": "amenities",
"in": "formData"
},
{
"type": "string",
"description": "Business hours JSON: [{\\",
"name": "business_hours",
"in": "formData"
},
{
"type": "string",
"description": "Google Maps link",
"name": "google_maps_link",
"in": "formData"
},
{
"type": "file",
"description": "Thumbnail image",
"name": "thumbnail",
"in": "formData"
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/locations/recent": {
"get": {
"produces": [
"application/json"
],
"tags": [
"locations"
],
"summary": "Recent locations with ratings",
"parameters": [
{
"type": "integer",
"description": "Number of results (min 1)",
"name": "page_size",
"in": "query",
"required": true
},
{
"type": "string",
"description": "Filter by location type",
"name": "location_type",
"in": "query"
},
{
"type": "string",
"description": "Filter by region",
"name": "regions",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/locations/search": {
"get": {
"produces": [
"application/json"
],
"tags": [
"locations"
],
"summary": "Search locations",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "name",
"in": "query"
},
{
"type": "string",
"description": "Meilisearch filter expression",
"name": "filter",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/locations/top-ratings": {
"get": {
"produces": [
"application/json"
],
"tags": [
"locations"
],
"summary": "Top-rated locations",
"parameters": [
{
"type": "integer",
"description": "Page number (min 1)",
"name": "page",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Page size (min 5)",
"name": "page_size",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Sort: 1=overall, 2=critics, 3=users",
"name": "order_by",
"in": "query"
},
{
"type": "integer",
"description": "Region type filter (07)",
"name": "region_type",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/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": [
"application/json"
],
"tags": [
"news"
],
"summary": "List news and events",
"parameters": [
{
"type": "integer",
"description": "Page (min 1)",
"name": "page",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Page size (min 5)",
"name": "page_size",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "1 = only approved items",
"name": "is_with_approval",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
},
"post": {
"security": [
{
"CookieAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"news"
],
"summary": "Create a news/event",
"parameters": [
{
"description": "News/event payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.CreateNewsEventsReq"
}
}
],
"responses": {
"201": {
"description": "Created"
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/region/provinces": {
"get": {
"produces": [
"application/json"
],
"tags": [
"regions"
],
"summary": "List provinces",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
},
"/region/regencies": {
"get": {
"produces": [
"application/json"
],
"tags": [
"regions"
],
"summary": "List regencies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
},
"/regions": {
"get": {
"produces": [
"application/json"
],
"tags": [
"regions"
],
"summary": "List all regions",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
},
"/review/location": {
"post": {
"security": [
{
"CookieAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"reviews"
],
"summary": "Create a review",
"parameters": [
{
"description": "Review payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.createReviewReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"409": {
"description": "Conflict",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/review/location/images": {
"post": {
"security": [
{
"CookieAuth": []
}
],
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"reviews"
],
"summary": "Upload images for a review",
"parameters": [
{
"type": "integer",
"description": "Review ID",
"name": "review_id",
"in": "formData",
"required": true
},
{
"type": "file",
"description": "Image files",
"name": "images",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/user": {
"patch": {
"security": [
{
"CookieAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Update user profile",
"parameters": [
{
"description": "Update payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.UpdateUserRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/user/avatar": {
"delete": {
"security": [
{
"CookieAuth": []
}
],
"tags": [
"user"
],
"summary": "Remove user avatar",
"responses": {
"204": {
"description": "No Content"
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
},
"patch": {
"security": [
{
"CookieAuth": []
}
],
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Upload user avatar",
"parameters": [
{
"type": "file",
"description": "Avatar image",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/user/login": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Login",
"parameters": [
{
"description": "Login credentials",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.createUserRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"404": {
"description": "Not Found",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/user/logout": {
"post": {
"security": [
{
"CookieAuth": []
}
],
"tags": [
"auth"
],
"summary": "Logout",
"responses": {
"204": {
"description": "No Content"
}
}
}
},
"/user/profile": {
"get": {
"security": [
{
"CookieAuth": []
}
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Get current user profile and stats",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/user/review/location/{location_id}": {
"get": {
"security": [
{
"CookieAuth": []
}
],
"produces": [
"application/json"
],
"tags": [
"reviews"
],
"summary": "Get current user's review for a location",
"parameters": [
{
"type": "integer",
"description": "Location ID",
"name": "location_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"404": {
"description": "Not Found",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/user/signup": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Register a new user",
"parameters": [
{
"description": "Signup payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.createUserRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"409": {
"description": "Conflict",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
},
"definitions": {
"api.CreateNewsEventsReq": {
"type": "object",
"required": [
"submitted_by",
"title",
"url"
],
"properties": {
"description": {
"type": "string"
},
"source": {
"type": "string"
},
"submitted_by": {
"type": "integer"
},
"title": {
"type": "string"
},
"url": {
"type": "string"
}
}
},
"api.UpdateUserRequest": {
"type": "object",
"properties": {
"about": {
"type": "string"
},
"social_media": {},
"website": {
"type": "string"
}
}
},
"api.createReviewReq": {
"type": "object",
"required": [
"comments",
"location_id",
"submitted_by"
],
"properties": {
"comments": {
"type": "string"
},
"is_from_critic": {
"type": "boolean"
},
"is_hided": {
"type": "boolean"
},
"location_id": {
"type": "integer"
},
"score": {
"type": "integer",
"maximum": 100
},
"submitted_by": {
"type": "integer"
},
"title": {
"type": "string"
}
}
},
"api.createUserRequest": {
"type": "object",
"required": [
"password",
"username"
],
"properties": {
"password": {
"type": "string",
"minLength": 7
},
"username": {
"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": {
"CookieAuth": {
"type": "apiKey",
"name": "paseto",
"in": "cookie"
}
}
}