fix: improvement log record ads tih ip, useragent, and uer_id

This commit is contained in:
ericprd 2025-03-19 22:43:31 +08:00
parent b0099dac1e
commit 290d7f6701
9 changed files with 83 additions and 28 deletions

2
.gitignore vendored
View File

@ -2,3 +2,5 @@ bin
.env .env
.DS_Store .DS_Store
/cmd/legalgo/env /cmd/legalgo/env
__debug*

View File

@ -3,9 +3,11 @@ package database
import "time" import "time"
type LogAds struct { type LogAds struct {
ID string `gorm:"primaryKey;not null" json:"id"` ID string `gorm:"primaryKey;not null" json:"id"`
AdsID string `gorm:"not null" json:"ads_id"` ContentID string `gorm:"not null" json:"content_id"`
// UserID string `gorm:"default:null" json:"user_id"` UserID string `gorm:"default:null" json:"user_id"`
IP string `gorm:"default:null" json:"ip"`
UserAgent string `gorm:"default:null" json:"user_agent"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"` CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"` UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
} }

View File

@ -9,8 +9,8 @@ func (a *accessor) GetAll() ([]adsdomain.AdsResponse, error) {
var ads []adsdomain.AdsResponse var ads []adsdomain.AdsResponse
if err := a.db.Table("ads"). if err := a.db.Table("ads").
Select("ads.*, COUNT(log_ads.ads_id) as clicked"). Select("ads.*, COUNT(log_ads.content_id) as clicked").
Joins("LEFT JOIN log_ads ON log_ads.ads_id = ads.id"). Joins("LEFT JOIN log_ads ON log_ads.content_id = ads.id").
Group("ads.id"). Group("ads.id").
Scan(&ads).Error; err != nil { Scan(&ads).Error; err != nil {
return ads, fmt.Errorf("failed to get all ads: %v", err) return ads, fmt.Errorf("failed to get all ads: %v", err)

View File

@ -2,16 +2,29 @@ package logrepository
import ( import (
"legalgo-BE-go/database" "legalgo-BE-go/database"
logsdomain "legalgo-BE-go/internal/domain/logs"
"github.com/google/uuid" "github.com/google/uuid"
) )
func (a *accessor) CreateLogAds(adsID string) error { func (a *accessor) CreateLogAds(spec logsdomain.LogsSpec) error {
spec := database.LogAds{ newSpec := database.LogAds{
ID: uuid.NewString(), ID: uuid.NewString(),
AdsID: adsID, ContentID: spec.ContentID,
} }
if err := a.db.Create(&spec).Error; err != nil {
if spec.UserID != nil {
newSpec.UserID = *spec.UserID
}
if spec.IP != nil {
newSpec.IP = *spec.IP
}
if spec.UserAgent != nil {
newSpec.UserAgent = *spec.UserAgent
}
if err := a.db.Create(&newSpec).Error; err != nil {
return err return err
} }

View File

@ -3,6 +3,7 @@ package logrepository
import ( import (
"legalgo-BE-go/database" "legalgo-BE-go/database"
adsdomain "legalgo-BE-go/internal/domain/ads" adsdomain "legalgo-BE-go/internal/domain/ads"
logsdomain "legalgo-BE-go/internal/domain/logs"
) )
type accessor struct { type accessor struct {
@ -10,7 +11,7 @@ type accessor struct {
} }
type Log interface { type Log interface {
CreateLogAds(string) error CreateLogAds(logsdomain.LogsSpec) error
GetAllLogAds(string) ([]adsdomain.Ads, error) GetAllLogAds(string) ([]adsdomain.Ads, error)
} }

View File

@ -7,30 +7,22 @@ import (
"legalgo-BE-go/internal/utilities/response" "legalgo-BE-go/internal/utilities/response"
"legalgo-BE-go/internal/utilities/utils" "legalgo-BE-go/internal/utilities/utils"
"net/http" "net/http"
"strings"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
"github.com/go-playground/validator/v10"
) )
func CreateLogAds( func CreateLogAds(
router chi.Router, router chi.Router,
userSvc usersvc.User, userSvc usersvc.User,
logsSvc logssvc.Log, logsSvc logssvc.Log,
validate *validator.Validate,
) { ) {
router.Post("/logs/ads", func(w http.ResponseWriter, r *http.Request) { router.Post("/logs/ads", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
// userDetail, err := utils.GetTokenDetail(r) var specReq logsdomain.LogsSpec
// if err != nil {
// response.RespondJsonErrorWithCode(
// ctx,
// w,
// err,
// response.ErrUnauthorized.Code,
// response.ErrUnauthorized.HttpCode,
// "unauthorized",
// )
// return
// }
var spec logsdomain.LogsRequest var spec logsdomain.LogsRequest
@ -46,7 +38,41 @@ func CreateLogAds(
return return
} }
if err := logsSvc.CreateLogAds(spec.AdsID); err != nil { if err := validate.Struct(spec); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.(validator.ValidationErrors).Error(),
)
return
}
specReq.ContentID = spec.AdsID
userDetail, _ := utils.GetTokenDetail(r)
if userDetail.ID != "" {
specReq.UserID = &userDetail.ID
}
ip := r.RemoteAddr
if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
ip = strings.Split(forwarded, ",")[0]
}
if ip != "" {
specReq.IP = &ip
}
if userAgent := r.UserAgent(); userAgent != "" {
specReq.UserAgent = &userAgent
}
if err := logsSvc.CreateLogAds(specReq); err != nil {
response.RespondJsonErrorWithCode( response.RespondJsonErrorWithCode(
ctx, ctx,
w, w,

View File

@ -8,6 +8,13 @@ type LogsRequest struct {
AdsID string `json:"ads_id" validate:"required"` AdsID string `json:"ads_id" validate:"required"`
} }
type LogsSpec struct {
ContentID string `json:"content_id" validate:"required"`
IP *string `json:"ip"`
UserID *string `json:"user_id"`
UserAgent *string `json:"user_agent"`
}
type LogResponse struct { type LogResponse struct {
ID string `json:"id"` ID string `json:"id"`
News []adsdomain.Ads `json:"news"` News []adsdomain.Ads `json:"news"`

View File

@ -1,9 +1,12 @@
package logssvc package logssvc
import "fmt" import (
"fmt"
logsdomain "legalgo-BE-go/internal/domain/logs"
)
func (i *impl) CreateLogAds(adsID string) error { func (i *impl) CreateLogAds(spec logsdomain.LogsSpec) error {
if err := i.logsRepo.CreateLogAds(adsID); err != nil { if err := i.logsRepo.CreateLogAds(spec); err != nil {
return fmt.Errorf("failed to create ads log: %v", err) return fmt.Errorf("failed to create ads log: %v", err)
} }

View File

@ -3,6 +3,7 @@ package logssvc
import ( import (
logrepository "legalgo-BE-go/internal/accessor/log" logrepository "legalgo-BE-go/internal/accessor/log"
adsdomain "legalgo-BE-go/internal/domain/ads" adsdomain "legalgo-BE-go/internal/domain/ads"
logsdomain "legalgo-BE-go/internal/domain/logs"
) )
type impl struct { type impl struct {
@ -10,7 +11,7 @@ type impl struct {
} }
type Log interface { type Log interface {
CreateLogAds(string) error CreateLogAds(logsdomain.LogsSpec) error
GetAllLogAds(string) ([]adsdomain.Ads, error) GetAllLogAds(string) ([]adsdomain.Ads, error)
} }