fix auth, add reviews, fix cors, fix queries

This commit is contained in:
nochill 2023-09-27 21:58:14 +07:00
parent 8a677a2130
commit 675abcdb18
18 changed files with 639 additions and 124 deletions

View File

@ -209,10 +209,104 @@ func (server *Server) getLocation(ctx *gin.Context) {
return
}
users_reviews, err := server.Store.GetListLocationReviews(ctx, db.GetListLocationReviewsParams{
LocationID: req.ID,
Limit: 5,
Offset: 0,
IsCritics: false,
})
if err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to receive user reviews for this location"))
return
}
critics_reviews, err := server.Store.GetListLocationReviews(ctx, db.GetListLocationReviewsParams{
LocationID: req.ID,
Limit: 20,
Offset: 0,
IsCritics: true,
})
if err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to receive user reviews for this location"))
return
}
res := gin.H{
"tags": tags,
"detail": location,
"tags": tags,
"detail": location,
"users_review": users_reviews,
"critics_review": critics_reviews,
}
ctx.JSON(http.StatusOK, res)
}
type getListLocationReviewsReq struct {
PageSize int8 `form:"page_size" binding:"required"`
Page int8 `form:"page" binding:"required,min=1"`
Type int8 `form:"type" binding:"required"` // 0 = all, 1 = critics,2 = users
LocationID int32 `form:"location_id" binding:"required"`
}
type getListLocationReviewsRes struct {
CriticsReviews []db.GetListLocationReviewsRow `json:"critics_reviews"`
UsersReviews []db.GetListLocationReviewsRow `json:"users_reviews"`
}
func (server *Server) getListLocationReviews(ctx *gin.Context) {
var req getListLocationReviewsReq
var res getListLocationReviewsRes
if err := ctx.ShouldBindQuery(&req); err != nil {
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
return
}
if req.Type-1 == 1 || req.Type-1 == 0 {
arg := db.GetListLocationReviewsParams{
LocationID: req.LocationID,
Offset: (req.Page - 1) * req.PageSize,
Limit: req.PageSize,
IsCritics: true,
}
reviews, err := server.Store.GetListLocationReviews(ctx, arg)
if err != nil {
if err == sql.ErrNoRows {
ctx.JSON(http.StatusNotFound, ErrorResponse(err, "There's no critics reviews for this location yet"))
return
}
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to get critics reviews for this location"))
return
}
res.CriticsReviews = reviews
}
if req.Type-1 == 2 || req.Type-1 == 0 {
arg := db.GetListLocationReviewsParams{
LocationID: req.LocationID,
Limit: req.PageSize,
Offset: (req.Page - 1) * req.PageSize,
IsCritics: false,
}
reviews, err := server.Store.GetListLocationReviews(ctx, arg)
if err != nil {
if err == sql.ErrNoRows {
ctx.JSON(http.StatusNotFound, ErrorResponse(err, "There's no critics reviews for this location yet"))
return
}
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to get critics reviews for this location"))
return
}
res.UsersReviews = reviews
}
ctx.JSON(http.StatusOK, res)
}

View File

@ -1,19 +1,50 @@
package api
import "github.com/gin-gonic/gin"
import (
"net/http"
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
"git.nochill.in/nochill/hiling_go/util/token"
"github.com/gin-gonic/gin"
)
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
// func CORSMiddleware() gin.HandlerFunc {
// return func(ctx *gin.Context) {
// ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*")
// ctx.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
// ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
// ctx.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
// if ctx.Request.Method == "OPTIONS" {
// ctx.AbortWithStatus(204)
// return
// }
// ctx.Next()
// }
// }
const (
authorizationPayloadKey = "authorization_payload"
)
func authMiddleware(tokenMaker token.Maker) gin.HandlerFunc {
return func(ctx *gin.Context) {
str, err := ctx.Cookie("paseto")
if err != nil {
ctx.AbortWithStatusJSON(http.StatusUnauthorized, ErrorResponse(err, "Unauthorized"))
return
}
c.Next()
payload, err := tokenMaker.VerifyToken(str)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to verify token"))
return
}
ctx.Set(authorizationPayloadKey, payload)
ctx.Next()
}
}

96
api/reviews.go Normal file
View File

@ -0,0 +1,96 @@
package api
import (
"database/sql"
"net/http"
db "git.nochill.in/nochill/hiling_go/db/sqlc"
"git.nochill.in/nochill/hiling_go/util/token"
"github.com/gin-gonic/gin"
)
type createReviewReq struct {
SubmittedBy int8 `json:"submitted_by" binding:"required"`
Comments string `json:"comments" binding:"required"`
Score int8 `json:"score" binding:"numeric,max=100"`
IsFromCritic *bool `json:"is_from_critic"`
IsHided *bool `json:"is_hided"`
LocationId int32 `json:"location_id" binding:"required"`
}
func (server *Server) createReview(ctx *gin.Context) {
var req createReviewReq
if err := ctx.ShouldBindJSON(&req); err != nil {
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
return
}
checkArg := db.CheckIfReviewExistsParams{
LocationID: req.LocationId,
SubmittedBy: int32(req.SubmittedBy),
}
reviewExist, err := server.Store.CheckIfReviewExists(ctx, checkArg)
if err != nil {
ctx.JSON(http.StatusInternalServerError, "Something went wrong while try to check review")
return
}
if reviewExist != 0 {
ctx.JSON(http.StatusConflict, "User review already exist")
return
}
arg := db.CreateReviewParams{
SubmittedBy: int32(req.SubmittedBy),
Comments: req.Comments,
Score: int16(req.Score),
IsFromCritic: *req.IsFromCritic,
IsHided: *req.IsHided,
LocationID: req.LocationId,
}
review, err := server.Store.CreateReview(ctx, arg)
if err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to save review"))
return
}
ctx.JSON(http.StatusOK, review)
}
type getUserReviewByLocationReq struct {
LocationID int32 `uri:"location_id" binding:"required"`
}
func (server *Server) getUserReviewByLocation(ctx *gin.Context) {
var req getUserReviewByLocationReq
if err := ctx.ShouldBindUri(&req); err != nil {
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
return
}
authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload)
arg := db.GetUserReviewByLocationParams{
SubmittedBy: int32(authPayload.UserID),
LocationID: req.LocationID,
}
review, err := server.Store.GetUserReviewByLocation(ctx, arg)
if err != nil {
if err == sql.ErrNoRows {
ctx.JSON(http.StatusNotFound, ErrorResponse(err, "Review not found"))
return
}
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to recevie current user review"))
return
}
ctx.JSON(http.StatusOK, review)
}

View File

@ -6,6 +6,7 @@ import (
db "git.nochill.in/nochill/hiling_go/db/sqlc"
"git.nochill.in/nochill/hiling_go/util"
"git.nochill.in/nochill/hiling_go/util/token"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
@ -35,7 +36,14 @@ func NewServer(config util.Config, store db.Store) (*Server, error) {
func (server *Server) getRoutes() {
router := gin.Default()
router.Use(CORSMiddleware())
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:5173"},
AllowCredentials: true,
AllowHeaders: []string{"Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization", "accept", "origin", "Cache-Control", "X-Requested-With"},
AllowMethods: []string{"POST", "PUT", "GET", "DELETE", "PATCH"},
}))
// router.Use(CORSMiddleware())
router.POST("/user/signup", server.createUser)
router.POST("/user/login", server.login)
@ -48,10 +56,16 @@ func (server *Server) getRoutes() {
router.GET("/locations", server.getListLocations)
router.GET("/location/:location_id", server.getLocation)
router.GET("/location/tags/:location_id", server.getTagsByLocation)
router.GET("/location/reviews", server.getListLocationReviews)
//IMAGES
router.GET("/images/location", server.getAllImagesByLocation)
// REQUIRE AUTH TOKEN
authRoutes := router.Use(authMiddleware(server.TokenMaker))
authRoutes.POST("/review/location", server.createReview)
authRoutes.GET("/user/review/location/:location_id", server.getUserReviewByLocation)
server.Router = router
}

View File

@ -31,12 +31,6 @@ type createUserResponse struct {
UpdatedAt time.Time `json:"updated_at"`
}
type userTokenResponse struct {
SessionID int32 `json:"session_id"`
AccesToken string `json:"access_token"`
AccessTokenExpiresAt time.Time `json:"access_token_expires_at"`
}
func (server *Server) createUser(ctx *gin.Context) {
var req createUserRequest
if err := ctx.ShouldBindJSON(&req); err != nil {
@ -71,7 +65,7 @@ func (server *Server) createUser(ctx *gin.Context) {
return
}
accessToken, accessPayload, err := server.TokenMaker.CreateToken(
accessToken, _, err := server.TokenMaker.CreateToken(
user.Username,
int(user.ID),
server.Config.TokenDuration,
@ -88,7 +82,7 @@ func (server *Server) createUser(ctx *gin.Context) {
// server.Config.RefreshTokenDuration,
// )
session, err := server.Store.CreateSession(ctx, db.CreateSessionParams{
_, err = server.Store.CreateSession(ctx, db.CreateSessionParams{
Username: user.Username,
// RefreshToken: refreshToken,
UserAgent: ctx.Request.UserAgent(),
@ -102,12 +96,6 @@ func (server *Server) createUser(ctx *gin.Context) {
return
}
tokenResponse := userTokenResponse{
SessionID: session.ID,
AccesToken: accessToken,
AccessTokenExpiresAt: accessPayload.ExpiredAt,
}
res := createUserResponse{
ID: user.ID,
Username: user.Username,
@ -126,17 +114,14 @@ func (server *Server) createUser(ctx *gin.Context) {
ctx.SetCookie(
"paseto",
accessToken,
accessPayload.ExpiredAt.Second(),
int(server.Config.CookieDuration),
"/",
"localhost",
false,
true,
false,
)
ctx.JSON(http.StatusOK, gin.H{
"token": tokenResponse,
"user": res,
})
ctx.JSON(http.StatusOK, res)
}
func (server *Server) login(ctx *gin.Context) {
@ -163,7 +148,7 @@ func (server *Server) login(ctx *gin.Context) {
return
}
accessToken, accessPayload, err := server.TokenMaker.CreateToken(user.Username, int(user.ID), server.Config.TokenDuration)
accessToken, _, err := server.TokenMaker.CreateToken(user.Username, int(user.ID), server.Config.TokenDuration)
if err != nil {
ctx.JSON(http.StatusInternalServerError, "Something went wrong while try to create token")
@ -185,13 +170,12 @@ func (server *Server) login(ctx *gin.Context) {
ctx.SetCookie(
"paseto",
accessToken,
accessPayload.ExpiredAt.Second(),
"",
int(server.Config.CookieDuration),
"/",
"localhost",
false,
true,
false,
)
ctx.JSON(http.StatusOK, user)
}

View File

@ -1,16 +1,16 @@
id,submitted_by,is_from_critic,comments,score,is_hided,location_id
1#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
2#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1
3#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1
4#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#2
5#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#3
6#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#9
7#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
8#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#9
9#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#4
10#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#4
11#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#2
12#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1
13#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
14#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
15#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
1#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
2#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1
3#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1
4#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#2
5#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#3
6#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#9
7#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
8#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#9
9#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#4
10#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#4
11#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#2
12#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1
13#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
14#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
15#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
1 id,submitted_by,is_from_critic,comments,score,is_hided,location_id
2 1#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8 1#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
3 2#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1 2#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1
4 3#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1 3#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1
5 4#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#2 4#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#2
6 5#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#3 5#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#3
7 6#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#9 6#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#9
8 7#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8 7#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
9 8#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#9 8#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#9
10 9#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#4 9#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#4
11 10#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#4 10#3#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#4
12 11#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#2 11#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#2
13 12#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1 12#2#true#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#1
14 13#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8 13#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
15 14#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8 14#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8
16 15#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.\nFrom the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.\nOne of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8 15#1#false#I recently had the opportunity to visit a breathtaking beach that left me in awe. Nestled between rolling waves and golden sands, this hidden gem is a true paradise for beach lovers and nature enthusiasts alike.From the moment I set foot on the powdery shoreline, I was captivated by the crystal-clear azure waters that stretched as far as the eye could see. The gentle caress of the ocean breeze and the soothing sound of waves crashing created an instant sense of relaxation.One of the most remarkable features of this beach is its untouched beauty. The absence of crowds and commercialization allowed for an authentic and serene experience. I was able to walk along the shoreline, feeling the soft sand beneath my feet, and listen to the symphony of seagulls above. It was a refreshing escape from the hustle and bustle of daily life.#8#false#8

View File

@ -35,6 +35,21 @@ func (m *MockStore) EXPECT() *MockStoreMockRecorder {
return m.recorder
}
// CheckIfReviewExists mocks base method.
func (m *MockStore) CheckIfReviewExists(arg0 context.Context, arg1 db.CheckIfReviewExistsParams) (int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CheckIfReviewExists", arg0, arg1)
ret0, _ := ret[0].(int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// CheckIfReviewExists indicates an expected call of CheckIfReviewExists.
func (mr *MockStoreMockRecorder) CheckIfReviewExists(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckIfReviewExists", reflect.TypeOf((*MockStore)(nil).CheckIfReviewExists), arg0, arg1)
}
// CreateLocation mocks base method.
func (m *MockStore) CreateLocation(arg0 context.Context, arg1 db.CreateLocationParams) error {
m.ctrl.T.Helper()
@ -49,6 +64,21 @@ func (mr *MockStoreMockRecorder) CreateLocation(arg0, arg1 interface{}) *gomock.
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateLocation", reflect.TypeOf((*MockStore)(nil).CreateLocation), arg0, arg1)
}
// CreateReview mocks base method.
func (m *MockStore) CreateReview(arg0 context.Context, arg1 db.CreateReviewParams) (db.Review, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateReview", arg0, arg1)
ret0, _ := ret[0].(db.Review)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// CreateReview indicates an expected call of CreateReview.
func (mr *MockStoreMockRecorder) CreateReview(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateReview", reflect.TypeOf((*MockStore)(nil).CreateReview), arg0, arg1)
}
// CreateSession mocks base method.
func (m *MockStore) CreateSession(arg0 context.Context, arg1 db.CreateSessionParams) (db.UserSession, error) {
m.ctrl.T.Helper()
@ -109,6 +139,21 @@ func (mr *MockStoreMockRecorder) GetImagesByLocation(arg0, arg1 interface{}) *go
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImagesByLocation", reflect.TypeOf((*MockStore)(nil).GetImagesByLocation), arg0, arg1)
}
// GetListLocationReviews mocks base method.
func (m *MockStore) GetListLocationReviews(arg0 context.Context, arg1 db.GetListLocationReviewsParams) ([]db.GetListLocationReviewsRow, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetListLocationReviews", arg0, arg1)
ret0, _ := ret[0].([]db.GetListLocationReviewsRow)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetListLocationReviews indicates an expected call of GetListLocationReviews.
func (mr *MockStoreMockRecorder) GetListLocationReviews(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetListLocationReviews", reflect.TypeOf((*MockStore)(nil).GetListLocationReviews), arg0, arg1)
}
// GetListLocations mocks base method.
func (m *MockStore) GetListLocations(arg0 context.Context) ([]db.Location, error) {
m.ctrl.T.Helper()
@ -214,6 +259,21 @@ func (mr *MockStoreMockRecorder) GetUser(arg0, arg1 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUser", reflect.TypeOf((*MockStore)(nil).GetUser), arg0, arg1)
}
// GetUserReviewByLocation mocks base method.
func (m *MockStore) GetUserReviewByLocation(arg0 context.Context, arg1 db.GetUserReviewByLocationParams) (db.GetUserReviewByLocationRow, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserReviewByLocation", arg0, arg1)
ret0, _ := ret[0].(db.GetUserReviewByLocationRow)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserReviewByLocation indicates an expected call of GetUserReviewByLocation.
func (mr *MockStoreMockRecorder) GetUserReviewByLocation(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserReviewByLocation", reflect.TypeOf((*MockStore)(nil).GetUserReviewByLocation), arg0, arg1)
}
// UpdatePassword mocks base method.
func (m *MockStore) UpdatePassword(arg0 context.Context, arg1 db.UpdatePasswordParams) error {
m.ctrl.T.Helper()

View File

@ -19,25 +19,6 @@ WHERE approved_by IS NOT NULL
ORDER BY l.created_at ASC
LIMIT $1;
-- name: GetLocation :one
SELECT
l.id,
l.name,
l.address,
COALESCE(l.google_maps_link, '') as google_maps_link,
l.thumbnail,
l.submitted_by,
COALESCE(r.regency_name, '') as regency_name,
COALESCE(p.province_name, '') as province_name,
COALESCE(r2.region_name, '') as region_name,
u.username as submitted_by_user
FROM locations l
JOIN regencies r on r.id = l.regency_id
JOIN provinces p on p.id = r.province_id
JOIN regions r2 on r2.id = p.region_id
JOIN users u on l.approved_by = u.id
WHERE l.id = $1;
-- name: CreateLocation :exec
INSERT INTO locations(
address,

16
db/queries/reviews.sql Normal file
View File

@ -0,0 +1,16 @@
-- name: CheckIfReviewExists :one
SELECT COUNT(1)
FROM reviews
WHERE reviews.location_id = $1 AND reviews.submitted_by = $2;
-- name: GetUserReviewByLocation :one
SELECT
re.id,
re.location_id,
re.score,
re.comments,
re.created_at,
re.updated_at
FROM reviews re
WHERE submitted_by = $1 AND location_id = $2;

View File

@ -109,3 +109,65 @@ func (q *Queries) GetTopListLocations(ctx context.Context, arg GetTopListLocatio
}
return items, nil
}
type GetLocationRow struct {
ID int32 `json:"id"`
Name string `json:"name"`
Address string `json:"address"`
RegencyName string `json:"regency_name"`
ProvinceName string `json:"province_name"`
RegionName string `json:"region_name"`
GoogleMapsLink string `json:"google_maps_link"`
Thumbnail sql.NullString `json:"thumbnail"`
SubmittedBy string `json:"submitted_by"`
CriticScore int32 `json:"critic_score"`
CriticCount int32 `json:"critic_count"`
UserScore int32 `json:"user_score"`
UserCount int32 `json:"user_count"`
}
var getLocationQ = `
SELECT
l.id,
name,
l.address,
COALESCE(re.regency_name, '') as regency_name,
COALESCE(prov.province_name, '') as province_name,
COALESCE(reg.region_name, '') as region_name,
COALESCE(l.google_maps_link, '') as google_maps_link,
thumbnail,
u.username as submitted_by,
(SELECT COALESCE(SUM(score), 0) from reviews re where re.is_from_critic = true and re.location_id = l.id) as critic_score,
(SELECT COUNT(id) from reviews re where re.is_from_critic = true and re.location_id = l.id) as critic_count,
(SELECT COALESCE(SUM(score), 0) from reviews re where re.is_from_critic = false and re.location_id = l.id) as user_score,
(SELECT COUNT(id) from reviews re where re.is_from_critic = false and re.location_id = l.id) as user_count
FROM locations l
JOIN regencies re on re.id = l.regency_id
JOIN provinces prov on prov.id = re.province_id
JOIN regions reg on reg.id = prov.region_id
JOIN users u on u.id = l.submitted_by
WHERE l.id = $1
`
func (q *Queries) GetLocation(ctx context.Context, location_id int32) (GetLocationRow, error) {
row := q.db.QueryRowContext(ctx, getLocationQ, location_id)
var i GetLocationRow
err := row.Scan(
&i.ID,
&i.Name,
&i.Address,
&i.RegencyName,
&i.ProvinceName,
&i.RegionName,
&i.GoogleMapsLink,
&i.Thumbnail,
&i.SubmittedBy,
&i.CriticScore,
&i.CriticCount,
&i.UserScore,
&i.UserCount,
)
return i, err
}

View File

@ -146,57 +146,6 @@ func (q *Queries) GetListRecentLocationsWithRatings(ctx context.Context, limit i
return items, nil
}
const getLocation = `-- name: GetLocation :one
SELECT
l.id,
l.name,
l.address,
COALESCE(l.google_maps_link, '') as google_maps_link,
l.thumbnail,
l.submitted_by,
COALESCE(r.regency_name, '') as regency_name,
COALESCE(p.province_name, '') as province_name,
COALESCE(r2.region_name, '') as region_name,
u.username as submitted_by_user
FROM locations l
JOIN regencies r on r.id = l.regency_id
JOIN provinces p on p.id = r.province_id
JOIN regions r2 on r2.id = p.region_id
JOIN users u on l.approved_by = u.id
WHERE l.id = $1
`
type GetLocationRow struct {
ID int32 `json:"id"`
Name string `json:"name"`
Address string `json:"address"`
GoogleMapsLink string `json:"google_maps_link"`
Thumbnail sql.NullString `json:"thumbnail"`
SubmittedBy int32 `json:"submitted_by"`
RegencyName string `json:"regency_name"`
ProvinceName string `json:"province_name"`
RegionName string `json:"region_name"`
SubmittedByUser string `json:"submitted_by_user"`
}
func (q *Queries) GetLocation(ctx context.Context, id int32) (GetLocationRow, error) {
row := q.db.QueryRowContext(ctx, getLocation, id)
var i GetLocationRow
err := row.Scan(
&i.ID,
&i.Name,
&i.Address,
&i.GoogleMapsLink,
&i.Thumbnail,
&i.SubmittedBy,
&i.RegencyName,
&i.ProvinceName,
&i.RegionName,
&i.SubmittedByUser,
)
return i, err
}
const getLocationTag = `-- name: GetLocationTag :many
SELECT
name

View File

@ -9,15 +9,16 @@ import (
)
type Querier interface {
CheckIfReviewExists(ctx context.Context, arg CheckIfReviewExistsParams) (int64, error)
CreateLocation(ctx context.Context, arg CreateLocationParams) error
CreateSession(ctx context.Context, arg CreateSessionParams) (UserSession, error)
CreateUser(ctx context.Context, arg CreateUserParams) (User, error)
GetCountImageByLocation(ctx context.Context, imageOf int32) (int64, error)
GetListLocations(ctx context.Context) ([]Location, error)
GetListRecentLocationsWithRatings(ctx context.Context, limit int32) ([]GetListRecentLocationsWithRatingsRow, error)
GetLocation(ctx context.Context, id int32) (GetLocationRow, error)
GetLocationTag(ctx context.Context, targetID int32) ([]string, error)
GetSession(ctx context.Context, id int32) (UserSession, error)
GetUserReviewByLocation(ctx context.Context, arg GetUserReviewByLocationParams) (GetUserReviewByLocationRow, error)
UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error
UpdateUser(ctx context.Context, arg UpdateUserParams) (User, error)
}

125
db/sqlc/reviews.go Normal file
View File

@ -0,0 +1,125 @@
package db
import (
"context"
"database/sql"
"time"
)
const createReview = `-- name: CreateReview :one
INSERT INTO reviews (
submitted_by,
comments,
score,
is_from_critic,
is_hided,
location_id
) VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id, submitted_by, comments, score, is_from_critic, is_hided, location_id, created_at, updated_at
`
type CreateReviewParams struct {
SubmittedBy int32 `json:"submitted_by"`
Comments string `json:"comments"`
Score int16 `json:"score"`
IsFromCritic bool `json:"is_from_critic"`
IsHided bool `json:"is_hided"`
LocationID int32 `json:"location_id"`
}
func (q *Queries) CreateReview(ctx context.Context, arg CreateReviewParams) (Review, error) {
row := q.db.QueryRowContext(ctx, createReview,
arg.SubmittedBy,
arg.Comments,
arg.Score,
arg.IsFromCritic,
arg.IsHided,
arg.LocationID,
)
var i Review
err := row.Scan(
&i.ID,
&i.SubmittedBy,
&i.Comments,
&i.Score,
&i.IsFromCritic,
&i.IsHided,
&i.LocationID,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
type GetListLocationReviewsParams struct {
LocationID int32 `json:"location_id"`
Limit int8 `json:"limit"`
Offset int8 `json:"offset"`
IsCritics bool `json:"is_critics"`
}
type GetListLocationReviewsRow struct {
ID int32 `json:"id"`
Score int8 `json:"score"`
Comment string `json:"comments"`
UserID int32 `json:"user_id"`
Username string `json:"username"`
UserAvatar sql.NullString `json:"user_avatar"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
const getListLocationReviews = `
SELECT
re.id as id,
re.score as score,
re.comments as comments,
u.id as user_id,
u.username as username,
u.avatar_picture as user_avatar,
re.created_at as created_at,
re.updated_at as updated_at
FROM REVIEWS re
JOIN users u on re.submitted_by = u.id
WHERE re.location_id = $1 AND re.is_from_critic = $2
LIMIT $3
OFFSET $4;
`
func (q *Queries) GetListLocationReviews(ctx context.Context, arg GetListLocationReviewsParams) ([]GetListLocationReviewsRow, error) {
rows, err := q.db.QueryContext(ctx, getListLocationReviews, arg.LocationID, arg.IsCritics, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []GetListLocationReviewsRow{}
for rows.Next() {
var i GetListLocationReviewsRow
if err := rows.Scan(
&i.ID,
&i.Score,
&i.Comment,
&i.UserID,
&i.Username,
&i.UserAvatar,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}

69
db/sqlc/reviews.sql.go Normal file
View File

@ -0,0 +1,69 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.20.0
// source: reviews.sql
package db
import (
"context"
"database/sql"
)
const checkIfReviewExists = `-- name: CheckIfReviewExists :one
SELECT COUNT(1)
FROM reviews
WHERE reviews.location_id = $1 AND reviews.submitted_by = $2
`
type CheckIfReviewExistsParams struct {
LocationID int32 `json:"location_id"`
SubmittedBy int32 `json:"submitted_by"`
}
func (q *Queries) CheckIfReviewExists(ctx context.Context, arg CheckIfReviewExistsParams) (int64, error) {
row := q.db.QueryRowContext(ctx, checkIfReviewExists, arg.LocationID, arg.SubmittedBy)
var count int64
err := row.Scan(&count)
return count, err
}
const getUserReviewByLocation = `-- name: GetUserReviewByLocation :one
SELECT
re.id,
re.location_id,
re.score,
re.comments,
re.created_at,
re.updated_at
FROM reviews re
WHERE submitted_by = $1 AND location_id = $2
`
type GetUserReviewByLocationParams struct {
SubmittedBy int32 `json:"submitted_by"`
LocationID int32 `json:"location_id"`
}
type GetUserReviewByLocationRow struct {
ID int32 `json:"id"`
LocationID int32 `json:"location_id"`
Score int16 `json:"score"`
Comments string `json:"comments"`
CreatedAt sql.NullTime `json:"created_at"`
UpdatedAt sql.NullTime `json:"updated_at"`
}
func (q *Queries) GetUserReviewByLocation(ctx context.Context, arg GetUserReviewByLocationParams) (GetUserReviewByLocationRow, error) {
row := q.db.QueryRowContext(ctx, getUserReviewByLocation, arg.SubmittedBy, arg.LocationID)
var i GetUserReviewByLocationRow
err := row.Scan(
&i.ID,
&i.LocationID,
&i.Score,
&i.Comments,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}

View File

@ -11,7 +11,10 @@ type Store interface {
Querier
GetTopListLocations(ctx context.Context, arg GetTopListLocationsParams) ([]GetTopListLocationsRow, error)
GetImagesByLocation(ctx context.Context, arg GetImagesByLocationParams) ([]GetImagesByLocationRow, error)
GetLocation(ctx context.Context, location_id int32) (GetLocationRow, error)
GetUser(ctx context.Context, username string) (GetUserRow, error)
CreateReview(ctx context.Context, arg CreateReviewParams) (Review, error)
GetListLocationReviews(ctx context.Context, arg GetListLocationReviewsParams) ([]GetListLocationReviewsRow, error)
}
type SQLStore struct {

1
go.mod
View File

@ -12,6 +12,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/cors v1.4.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.9.1 // indirect
github.com/go-playground/locales v0.14.1 // indirect

28
go.sum
View File

@ -62,6 +62,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -75,19 +76,27 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g=
github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.15.3 h1:S+sSpunYjNPDuXkWbK+x+bA7iXiW296KG4dL3X7xUZo=
github.com/go-playground/validator/v10 v10.15.3/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -166,14 +175,19 @@ github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZY
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
@ -186,8 +200,10 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/o1egl/paseto v1.0.0 h1:bwpvPu2au176w4IBlhbyUv/S5VPptERIA99Oap5qUd0=
github.com/o1egl/paseto v1.0.0/go.mod h1:5HxsZPmw/3RI2pAwGo1HhOOwSdvBpcuVzO7uDkm+CLU=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -198,6 +214,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
github.com/ramya-rao-a/go-outline v0.0.0-20210608161538-9736a4bde949 h1:iaD+iVf9xGfajsJp+zYrg9Lrk6gMJ6/hZHO4cYq5D5o=
github.com/ramya-rao-a/go-outline v0.0.0-20210608161538-9736a4bde949/go.mod h1:9V3eNbj9Z53yO7cKB6cSX9f0O7rYdIiuGBhjA1YsQuw=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
@ -218,6 +236,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@ -229,6 +248,8 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/yiplee/nap v1.0.1 h1:5p8KAIkYy+PIMGSk+ScF13Hh/OFkIEBHPuD14OFvStg=
@ -258,6 +279,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
@ -395,6 +417,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -557,15 +581,19 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -13,6 +13,7 @@ type Config struct {
ServerAddress string `mapstructure:"SERVER_ADDRESS"`
TokenSymmetricKey string `mapstructure:"TOKEN_SYMMETRIC_KEY"`
TokenDuration time.Duration `mapstructure:"TOKEN_DURATION"`
CookieDuration int32 `mapstructure:"COOKIE_DURATION"`
RefreshTokenDuration time.Duration `mapstructure:"REFRESH_TOKEN_DURATION"`
}