Compare commits
40
Commits
ce17e9dc73
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
211f0154be | ||
|
|
136c4634c8 | ||
|
|
987ac2fe4a | ||
|
|
02d8a509ff | ||
|
|
e29bd7986f | ||
|
|
4bf318a9c2 | ||
|
|
52085a5be0 | ||
|
|
21c4c1efba | ||
|
|
c17540cc20 | ||
|
|
714b1ff4eb | ||
|
|
abc3ce8d2b | ||
|
|
cd1097d3d0 | ||
|
|
52991059c6 | ||
|
|
a7ef3f8ca2 | ||
|
|
6f1ac37915 | ||
|
|
e20c63e694 | ||
|
|
abcbc014a2 | ||
|
|
98b871a5ed | ||
|
|
3311b80943 | ||
|
|
16fef8706a | ||
|
|
4fbfa9c2c9 | ||
|
|
a68780f09e | ||
|
|
49dc0e4a7b | ||
|
|
09d9c4efb8 | ||
|
|
990026cece | ||
|
|
11051ae89c | ||
|
|
24f0fe6efa | ||
|
|
8d7500610e | ||
|
|
0c8133c802 | ||
|
|
d8f6968f64 | ||
|
|
290d7f6701 | ||
|
|
b0099dac1e | ||
|
|
d7fa8496b0 | ||
|
|
efab193793 | ||
|
|
7b529ba46e | ||
|
|
c0dcdb77fa | ||
|
|
ee8e8e140d | ||
|
|
11bc19360c | ||
|
|
1297c71200 | ||
|
|
47085ca0ae |
@@ -2,3 +2,5 @@ bin
|
||||
.env
|
||||
.DS_Store
|
||||
/cmd/legalgo/env
|
||||
|
||||
__debug*
|
||||
|
||||
+15
-2
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"legalgo-BE-go/config"
|
||||
"legalgo-BE-go/database"
|
||||
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -36,9 +37,10 @@ func main() {
|
||||
log.Fatal("Migration failed: ", err)
|
||||
}
|
||||
|
||||
var temp subscribeplandomain.SubscribePlan
|
||||
var tempSP subscribeplandomain.SubscribePlan
|
||||
var tempCtg categorydomain.Category
|
||||
|
||||
if err := db.Where("code = ?", "basic").First(&temp).Error; err != nil {
|
||||
if err := db.Where("code = ?", "basic").First(&tempSP).Error; err != nil {
|
||||
log.Print("seeding basic subscribe plan")
|
||||
db.Create(&subscribeplandomain.SubscribePlan{
|
||||
ID: uuid.NewString(),
|
||||
@@ -50,5 +52,16 @@ func main() {
|
||||
})
|
||||
}
|
||||
|
||||
if err := db.Where("code = ?", "spotlight").First(&tempCtg).Error; err != nil {
|
||||
log.Print("seeding basic subscribe plan")
|
||||
seq := 0
|
||||
db.Create(&categorydomain.Category{
|
||||
ID: uuid.NewString(),
|
||||
Code: "spotlight",
|
||||
Name: "Spotlight",
|
||||
Sequence: &seq,
|
||||
})
|
||||
}
|
||||
|
||||
log.Print("migrate success")
|
||||
}
|
||||
|
||||
+3
-2
@@ -12,14 +12,15 @@ import (
|
||||
const (
|
||||
YAML_PATH = "env/%s"
|
||||
ENV_MODE = "ENV_MODE"
|
||||
DEFAULT_ENV_MODE = "development"
|
||||
DEFAULT_ENV_MODE = "local"
|
||||
)
|
||||
|
||||
var (
|
||||
validEnvMode = map[string]struct{}{
|
||||
"local": {},
|
||||
"development": {},
|
||||
"staging": {},
|
||||
"production": {},
|
||||
"debug": {},
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ type Redis struct {
|
||||
DB int `mapstructure:"db"`
|
||||
Username string `mapstructure:"username"`
|
||||
Password string `mapstructure:"password"`
|
||||
SslMode string `mapstructure:"ssl-mode"`
|
||||
SSL bool `mapstructure:"ssl"`
|
||||
Debug bool `mapstructure:"debug"`
|
||||
MaxIdleConnectionsInSecond int `mapstructure:"max-idle-connections-in-second"`
|
||||
MaxOpenConnectionsInSecond int `mapstructure:"max-open-connections-in-second"`
|
||||
|
||||
@@ -6,6 +6,8 @@ type Ads struct {
|
||||
ID string `gorm:"primaryKey;not null" json:"id"`
|
||||
ImageUrl string `gorm:"not null" json:"image_url"`
|
||||
Url string `gorm:"not null" json:"url"`
|
||||
StartDate *time.Time `gorm:"default:null" json:"start_date"`
|
||||
EndDate *time.Time `gorm:"default:null" json:"end_date"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package database
|
||||
|
||||
import "time"
|
||||
|
||||
type ContentLog struct {
|
||||
ID string `gorm:"primaryKey;not null" json:"id"`
|
||||
ContentID string `gorm:"not null" json:"content_id"`
|
||||
UserID string `gorm:"default:null" json:"user_id"`
|
||||
IP string `gorm:"default:null" json:"ip"`
|
||||
UserAgent string `gorm:"default:null" json:"user_agent"`
|
||||
Category string `gorm:"not null" json:"category"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
}
|
||||
+3
-1
@@ -15,12 +15,13 @@ type DB struct {
|
||||
|
||||
func NewDB(cfg *config.Config) (*DB, error) {
|
||||
dsn := fmt.Sprintf(
|
||||
"host=%s user=%s password=%s dbname=%s port=%v sslmode=disable",
|
||||
"host=%s user=%s password=%s dbname=%s port=%v sslmode=%s",
|
||||
cfg.Database.Host,
|
||||
cfg.Database.Username,
|
||||
cfg.Database.Password,
|
||||
cfg.Database.DB,
|
||||
cfg.Database.Port,
|
||||
cfg.Database.SslMode,
|
||||
)
|
||||
|
||||
if dsn == "" {
|
||||
@@ -55,5 +56,6 @@ func (db *DB) Migrate() error {
|
||||
&Tag{},
|
||||
&Category{},
|
||||
&Ads{},
|
||||
&ContentLog{},
|
||||
)
|
||||
}
|
||||
|
||||
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
server:
|
||||
base-url: https://api.legalgo.id/core
|
||||
local-url: http://localhost:3300
|
||||
port: 3300
|
||||
|
||||
jwt:
|
||||
token:
|
||||
expires-ttl: 1440
|
||||
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
|
||||
|
||||
postgresql:
|
||||
host: dpg-d046h549c44c739arfv0-a.singapore-postgres.render.com
|
||||
port: 5432
|
||||
driver: postgres
|
||||
db: legalgonews_prod
|
||||
username: legalgo_admin
|
||||
password: "656ogwc0JlLEVQyHnT5RrrYa7762iBQQ"
|
||||
ssl-mode: require
|
||||
max-idle-connections-in-second: 600
|
||||
max-open-connections-in-second: 600
|
||||
connection-max-life-time-in-second: 600
|
||||
debug: false
|
||||
|
||||
oss:
|
||||
access_key_id: GTK7i3SVy9llQeGH0Htv
|
||||
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
|
||||
endpoint: news-cdn.legalgo.id
|
||||
bucket_name: uploads
|
||||
log_level: Error
|
||||
host_url: https://news-cdn.legalgo.id
|
||||
public_url: https://news-cdn.legalgo.id
|
||||
|
||||
redis:
|
||||
host: singapore-keyvalue.render.com
|
||||
port: 6379
|
||||
username: red-d046l42dbo4c73ea9iag
|
||||
password: 7cZvu08JKuO9MPNxBb97tZCVNj0ZGNp2
|
||||
db: 5
|
||||
ssl: true
|
||||
max-idle-connections-in-second: 600
|
||||
max-open-connections-in-second: 600
|
||||
connection-max-life-time-in-second: 600
|
||||
debug: false
|
||||
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
server:
|
||||
base-url: https://api.legalgo.id/core
|
||||
local-url: http://localhost:3300
|
||||
port: 3300
|
||||
|
||||
jwt:
|
||||
token:
|
||||
expires-ttl: 1440
|
||||
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
|
||||
|
||||
postgresql:
|
||||
host: dpg-d04bi9juibrs73augcc0-a.singapore-postgres.render.com
|
||||
port: 5432
|
||||
driver: postgres
|
||||
db: legalgonews_dev
|
||||
username: legalgo_admin
|
||||
password: "5h7DCBR1T8pug6AlbrHXqIDAr9o2vnky"
|
||||
ssl-mode: require
|
||||
max-idle-connections-in-second: 600
|
||||
max-open-connections-in-second: 600
|
||||
connection-max-life-time-in-second: 600
|
||||
debug: false
|
||||
|
||||
oss:
|
||||
access_key_id: GTK7i3SVy9llQeGH0Htv
|
||||
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
|
||||
endpoint: news-cdn.legalgo.id
|
||||
bucket_name: uploads-staging
|
||||
log_level: Error
|
||||
host_url: https://news-cdn.legalgo.id
|
||||
public_url: https://news-cdn.legalgo.id
|
||||
|
||||
redis:
|
||||
host: singapore-keyvalue.render.com
|
||||
port: 6379
|
||||
username: red-d04c8k49c44c739ga8dg
|
||||
password: ItPzniHv94yr8vY4HTrhCfKoibqBh61T
|
||||
db: 5
|
||||
ssl: true
|
||||
max-idle-connections-in-second: 600
|
||||
max-open-connections-in-second: 600
|
||||
connection-max-life-time-in-second: 600
|
||||
debug: false
|
||||
+13
-13
@@ -9,12 +9,12 @@ jwt:
|
||||
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
|
||||
|
||||
postgresql:
|
||||
host: 62.72.45.250
|
||||
port: 20826
|
||||
host: dpg-d046h549c44c739arfv0-a
|
||||
port: 5432
|
||||
driver: postgres
|
||||
db: legalgonews-dev
|
||||
db: legalgonews_prod
|
||||
username: legalgo_admin
|
||||
password: "K4K!2Kg7c@KW6H&4A2aBy2dFCRY3Sh"
|
||||
password: "656ogwc0JlLEVQyHnT5RrrYa7762iBQQ"
|
||||
ssl-mode: disable
|
||||
max-idle-connections-in-second: 600
|
||||
max-open-connections-in-second: 600
|
||||
@@ -22,18 +22,18 @@ postgresql:
|
||||
debug: false
|
||||
|
||||
oss:
|
||||
access_key_id: cf9a475e18bc7626cbdbf09709d82a64
|
||||
access_key_secret: 91f3321294d3e23035427a0ecb893ada
|
||||
endpoint: sin1.contabostorage.com
|
||||
bucket_name: legalgonews-dev
|
||||
access_key_id: GTK7i3SVy9llQeGH0Htv
|
||||
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
|
||||
endpoint: news-cdn.legalgo.id
|
||||
bucket_name: uploads
|
||||
log_level: Error
|
||||
host_url: https://sin1.contabostorage.com
|
||||
public_url: https://sin1.contabostorage.com/fda98c2228f246f29a7e466b86b3b9e7
|
||||
host_url: https://news-cdn.legalgo.id
|
||||
public_url: https://news-cdn.legalgo.id
|
||||
|
||||
redis:
|
||||
host: 62.72.45.250
|
||||
port: 26379
|
||||
password: mDtpsyEW8W26vwLhglpO
|
||||
host: red-d046l42dbo4c73ea9iag
|
||||
port: 6379
|
||||
password: 7cZvu08JKuO9MPNxBb97tZCVNj0ZGNp2
|
||||
db: 5
|
||||
ssl: false
|
||||
max-idle-connections-in-second: 600
|
||||
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
server:
|
||||
base-url: https://api.legalgo.id/core
|
||||
local-url: http://localhost:3300
|
||||
port: 3300
|
||||
|
||||
jwt:
|
||||
token:
|
||||
expires-ttl: 1440
|
||||
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
|
||||
|
||||
postgresql:
|
||||
host: dpg-d04bi9juibrs73augcc0-a
|
||||
port: 5432
|
||||
driver: postgres
|
||||
db: legalgonews_dev
|
||||
username: legalgo_admin
|
||||
password: "5h7DCBR1T8pug6AlbrHXqIDAr9o2vnky"
|
||||
ssl-mode: disable
|
||||
max-idle-connections-in-second: 600
|
||||
max-open-connections-in-second: 600
|
||||
connection-max-life-time-in-second: 600
|
||||
debug: false
|
||||
|
||||
oss:
|
||||
access_key_id: GTK7i3SVy9llQeGH0Htv
|
||||
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
|
||||
endpoint: news-cdn.legalgo.id
|
||||
bucket_name: uploads-staging
|
||||
log_level: Error
|
||||
host_url: https://news-cdn.legalgo.id
|
||||
public_url: https://news-cdn.legalgo.id
|
||||
|
||||
redis:
|
||||
host: red-d04c8k49c44c739ga8dg
|
||||
port: 6379
|
||||
password: ItPzniHv94yr8vY4HTrhCfKoibqBh61T
|
||||
db: 5
|
||||
ssl: false
|
||||
max-idle-connections-in-second: 600
|
||||
max-open-connections-in-second: 600
|
||||
connection-max-life-time-in-second: 600
|
||||
debug: false
|
||||
@@ -5,9 +5,14 @@ import (
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
)
|
||||
|
||||
func (a *accessor) GetAll() ([]adsdomain.Ads, error) {
|
||||
var ads []adsdomain.Ads
|
||||
if err := a.db.Find(&ads).Error; err != nil {
|
||||
func (a *accessor) GetAll() ([]adsdomain.AdsResponse, error) {
|
||||
var ads []adsdomain.AdsResponse
|
||||
|
||||
if err := a.db.Table("ads").
|
||||
Select("ads.*, COUNT(content_logs.content_id) as clicked").
|
||||
Joins("LEFT JOIN content_logs ON content_logs.content_id = ads.id").
|
||||
Group("ads.id").
|
||||
Scan(&ads).Error; err != nil {
|
||||
return ads, fmt.Errorf("failed to get all ads: %v", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ type accessor struct {
|
||||
|
||||
type Ads interface {
|
||||
Create(adsdomain.Ads) error
|
||||
GetAll() ([]adsdomain.Ads, error)
|
||||
GetAll() ([]adsdomain.AdsResponse, error)
|
||||
Update(adsdomain.Ads) error
|
||||
Delete(string) error
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package adsrepository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
func (a *accessor) Update(spec adsdomain.Ads) error {
|
||||
if err := a.db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{
|
||||
"image_url",
|
||||
"url",
|
||||
"updated_at",
|
||||
"start_date",
|
||||
"end_date",
|
||||
}),
|
||||
}).Select(
|
||||
"image_url",
|
||||
"url",
|
||||
"updated_at",
|
||||
"start_date",
|
||||
"end_date",
|
||||
).Save(&spec).Error; err != nil {
|
||||
return fmt.Errorf("failed to update tag: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package logrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
logsdomain "legalgo-BE-go/internal/domain/logs"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (a *accessor) CreateLog(spec logsdomain.LogsSpec) error {
|
||||
newSpec := database.ContentLog{
|
||||
ID: uuid.NewString(),
|
||||
ContentID: spec.ContentID,
|
||||
Category: spec.Category,
|
||||
}
|
||||
|
||||
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 nil
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package logrepository
|
||||
|
||||
import (
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
)
|
||||
|
||||
func (a *accessor) GetAllLogAds(userID string) ([]adsdomain.Ads, error) {
|
||||
var ads []adsdomain.Ads
|
||||
|
||||
// if err := a.db.Find(&ads, "user_id = ?", userID).Error; err != nil {
|
||||
// return ads, err
|
||||
// }
|
||||
|
||||
if err := a.db.
|
||||
Joins("JOIN log_ads ON ads.id = log_ads.ads_id").
|
||||
Find(&ads, "log_ads.user_id = ?", userID).Error; err != nil {
|
||||
return ads, err
|
||||
}
|
||||
|
||||
return ads, nil
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package logrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
logsdomain "legalgo-BE-go/internal/domain/logs"
|
||||
)
|
||||
|
||||
type accessor struct {
|
||||
db *database.DB
|
||||
}
|
||||
|
||||
type Log interface {
|
||||
CreateLog(logsdomain.LogsSpec) error
|
||||
GetAllLogAds(string) ([]adsdomain.Ads, error)
|
||||
}
|
||||
|
||||
func New(db *database.DB) Log {
|
||||
return &accessor{db}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package repository
|
||||
import (
|
||||
adsrepository "legalgo-BE-go/internal/accessor/ads"
|
||||
categoryrepository "legalgo-BE-go/internal/accessor/category"
|
||||
logrepository "legalgo-BE-go/internal/accessor/log"
|
||||
newsrepository "legalgo-BE-go/internal/accessor/news"
|
||||
"legalgo-BE-go/internal/accessor/oss"
|
||||
redisaccessor "legalgo-BE-go/internal/accessor/redis"
|
||||
@@ -26,4 +27,5 @@ var Module = fx.Module("repository", fx.Provide(
|
||||
newsrepository.New,
|
||||
oss.New,
|
||||
adsrepository.New,
|
||||
logrepository.New,
|
||||
))
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
package newsrepository
|
||||
|
||||
import newsdomain "legalgo-BE-go/internal/domain/news"
|
||||
import (
|
||||
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||
timeutils "legalgo-BE-go/internal/utilities/time_utils"
|
||||
)
|
||||
|
||||
func (a *accessor) GetAll(filter newsdomain.NewsFilter) ([]newsdomain.News, error) {
|
||||
var news []newsdomain.News
|
||||
query := a.db.
|
||||
type is_active string
|
||||
|
||||
const (
|
||||
active is_active = "true"
|
||||
notActive is_active = "false"
|
||||
)
|
||||
|
||||
func (a *accessor) GetAll(filter newsdomain.NewsFilter) ([]newsdomain.NewsResponse, error) {
|
||||
var news []newsdomain.NewsResponse
|
||||
query := a.db.Table("news").
|
||||
Preload("Tags").
|
||||
Preload("Categories").
|
||||
Preload("Author")
|
||||
Preload("Author").
|
||||
Joins("LEFT JOIN content_logs ON content_logs.content_id = news.id")
|
||||
|
||||
if len(filter.Category) > 0 {
|
||||
query = query.Joins("JOIN news_categories nc ON nc.news_id = news.id").
|
||||
@@ -19,6 +30,19 @@ func (a *accessor) GetAll(filter newsdomain.NewsFilter) ([]newsdomain.News, erro
|
||||
Where("nt.tag_id IN (?)", filter.Tags)
|
||||
}
|
||||
|
||||
if filter.Active == string(active) {
|
||||
query = query.Where("news.live_at <= ?", timeutils.Now())
|
||||
}
|
||||
|
||||
if filter.Search != "" {
|
||||
query = query.Where("news.title ILIKE ?", "%"+filter.Search+"%")
|
||||
}
|
||||
|
||||
query.
|
||||
Select("news.*, COUNT(content_logs.content_id) as views").
|
||||
Group("news.id").
|
||||
Order("news.created_at DESC")
|
||||
|
||||
if err := query.
|
||||
Find(&news).Error; err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package newsrepository
|
||||
|
||||
import newsdomain "legalgo-BE-go/internal/domain/news"
|
||||
|
||||
func (a *accessor) GetByID(id string) (*newsdomain.News, error) {
|
||||
var news newsdomain.News
|
||||
|
||||
if err := a.db.
|
||||
Preload("Tags").
|
||||
Preload("Categories").
|
||||
Preload("Author").
|
||||
First(&news, "id = ?", id).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &news, nil
|
||||
}
|
||||
@@ -10,8 +10,9 @@ type accessor struct {
|
||||
}
|
||||
|
||||
type News interface {
|
||||
GetAll(filter newsdomain.NewsFilter) ([]newsdomain.News, error)
|
||||
GetAll(filter newsdomain.NewsFilter) ([]newsdomain.NewsResponse, error)
|
||||
GetBySlug(string) (*newsdomain.News, error)
|
||||
GetByID(string) (*newsdomain.News, error)
|
||||
Create(newsdomain.News) error
|
||||
Update(newsdomain.News) error
|
||||
Delete(string) error
|
||||
|
||||
@@ -66,7 +66,7 @@ func (r *OssRepositoryImpl) GetPublicURL(fileName string) string {
|
||||
if fileName == "" {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s:%s%s", r.cfg.GetPublicURL(), r.cfg.GetBucketName(), fileName)
|
||||
return fmt.Sprintf("%s/%s%s", r.cfg.GetPublicURL(), r.cfg.GetBucketName(), fileName)
|
||||
}
|
||||
|
||||
func (r *OssRepositoryImpl) DeleteObject(ctx context.Context, fileName string) error {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package redisaccessor
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"legalgo-BE-go/config"
|
||||
|
||||
@@ -16,11 +17,19 @@ func Get() *redis.Client {
|
||||
func New(cfg *config.Config) *redis.Client {
|
||||
addr := fmt.Sprintf("%s:%s", cfg.Redis.Host, cfg.Redis.Port)
|
||||
|
||||
redisClient = redis.NewClient(&redis.Options{
|
||||
options := &redis.Options{
|
||||
Addr: addr,
|
||||
Password: cfg.Redis.Password,
|
||||
DB: cfg.Redis.DB,
|
||||
})
|
||||
}
|
||||
|
||||
if cfg.Redis.Username != "" {
|
||||
options.Username = cfg.Redis.Username
|
||||
}
|
||||
if cfg.Redis.SSL {
|
||||
options.TLSConfig = &tls.Config{}
|
||||
}
|
||||
|
||||
redisClient = redis.NewClient(options)
|
||||
return redisClient
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package staffrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
|
||||
@@ -12,12 +13,12 @@ func (sr *accessor) GetStaffByEmail(email string) (*staffdomain.Staff, error) {
|
||||
var staff staffdomain.Staff
|
||||
|
||||
if email == "" {
|
||||
return nil, errors.New("email is required")
|
||||
return nil, fmt.Errorf("email is required")
|
||||
}
|
||||
|
||||
if err := sr.db.First(&staff, "email = ?", email).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("staff not found")
|
||||
return nil, fmt.Errorf("staff not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package staffrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -11,12 +12,12 @@ func (sr *accessor) GetStaffByID(ID string) (*staffdomain.Staff, error) {
|
||||
var staff staffdomain.Staff
|
||||
|
||||
if ID == "" {
|
||||
return nil, errors.New("id is required")
|
||||
return nil, fmt.Errorf("id is required")
|
||||
}
|
||||
|
||||
if err := sr.db.First(&staff, "id = ? ", ID).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("staff not found")
|
||||
return nil, fmt.Errorf("staff not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package staffrepository
|
||||
|
||||
import staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
|
||||
func (a *accessor) GetStaffs() ([]staffdomain.StaffProfile, error) {
|
||||
var staffs []staffdomain.StaffProfile
|
||||
|
||||
if err := a.db.Table("staffs").Find(&staffs).Error; err != nil {
|
||||
return staffs, err
|
||||
}
|
||||
|
||||
return staffs, nil
|
||||
}
|
||||
@@ -20,6 +20,7 @@ func (a *accessor) GetUsers() ([]userdomain.UserProfile, error) {
|
||||
Email: user.Email,
|
||||
Phone: user.Phone,
|
||||
Subscribe: user.Subscribe,
|
||||
CreatedAt: user.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ type Staff interface {
|
||||
GetStaffByEmail(string) (*staffdomain.Staff, error)
|
||||
GetStaffByID(string) (*staffdomain.Staff, error)
|
||||
GetUsers() ([]userdomain.UserProfile, error)
|
||||
GetStaffs() ([]staffdomain.StaffProfile, error)
|
||||
Create(staffdomain.Staff) error
|
||||
Update(staffdomain.Staff) error
|
||||
}
|
||||
|
||||
@@ -2,16 +2,15 @@ package staffrepository
|
||||
|
||||
import (
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
)
|
||||
|
||||
func (ur *accessor) Update(spec staffdomain.Staff) error {
|
||||
val, err := utils.StructToMap(spec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// val, err := utils.StructToMap(spec)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
if err := ur.db.Model(&staffdomain.Staff{}).Where("id = ?", spec.ID).Updates(val).Error; err != nil {
|
||||
if err := ur.db.Model(&staffdomain.Staff{}).Where("id = ?", spec.ID).Updates(spec).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package subscribeplanrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -12,7 +13,7 @@ func (s *accessor) GetByID(id string) (*subscribeplandomain.SubscribePlan, error
|
||||
|
||||
if err := s.db.First(&subscribePlan, "id = ? ", id).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return subscribePlan, errors.New("subscribe plan not found")
|
||||
return subscribePlan, fmt.Errorf("subscribe plan not found")
|
||||
}
|
||||
return subscribePlan, err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package userrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
userdomain "legalgo-BE-go/internal/domain/user"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -11,12 +12,12 @@ func (ur *accessor) GetUserByEmail(email string) (*userdomain.User, error) {
|
||||
var user *userdomain.User
|
||||
|
||||
if email == "" {
|
||||
return nil, errors.New("email is empty")
|
||||
return nil, fmt.Errorf("email is empty")
|
||||
}
|
||||
|
||||
if err := ur.db.First(&user, "email = ?", email).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("user not found")
|
||||
return nil, fmt.Errorf("user not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package userrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"fmt"
|
||||
userdomain "legalgo-BE-go/internal/domain/user"
|
||||
)
|
||||
|
||||
@@ -10,7 +9,7 @@ func (ur *accessor) GetUserByID(id string) (*userdomain.User, error) {
|
||||
var user userdomain.User
|
||||
|
||||
if id == "" {
|
||||
return nil, errors.New("id is empty")
|
||||
return nil, fmt.Errorf("id is empty")
|
||||
}
|
||||
|
||||
if err := ur.db.
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
package userrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
userdomain "legalgo-BE-go/internal/domain/user"
|
||||
)
|
||||
|
||||
func (ur *accessor) GetUserProfile(email string) (*userdomain.UserProfile, error) {
|
||||
func (ur *accessor) GetUserProfile(id string) (*userdomain.UserProfile, error) {
|
||||
var user *userdomain.User
|
||||
|
||||
if email == "" {
|
||||
return nil, errors.New("email is empty")
|
||||
if id == "" {
|
||||
return nil, fmt.Errorf("email is empty")
|
||||
}
|
||||
|
||||
if err := ur.db.
|
||||
Preload("Subscribe").
|
||||
Preload("Subscribe.SubscribePlan").
|
||||
First(&user, "email = ?", email).
|
||||
First(&user, "id = ?", id).
|
||||
Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -25,6 +25,7 @@ func (ur *accessor) GetUserProfile(email string) (*userdomain.UserProfile, error
|
||||
Email: user.Email,
|
||||
Phone: user.Phone,
|
||||
Subscribe: user.Subscribe,
|
||||
CreatedAt: user.CreatedAt,
|
||||
}
|
||||
|
||||
return userProfile, nil
|
||||
|
||||
@@ -5,5 +5,6 @@ import "go.uber.org/fx"
|
||||
var Module = fx.Module("ads-http", fx.Invoke(
|
||||
Create,
|
||||
GetAll,
|
||||
Update,
|
||||
Delete,
|
||||
))
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package adshttp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
adssvc "legalgo-BE-go/internal/services/ads"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func Update(
|
||||
router chi.Router,
|
||||
validate *validator.Validate,
|
||||
adsSvc adssvc.Ads,
|
||||
) {
|
||||
router.
|
||||
With(authmiddleware.Authorize()).
|
||||
Put("/ads/{ads_id}/update", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
adsID := chi.URLParam(r, "ads_id")
|
||||
|
||||
if adsID == "" {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
fmt.Errorf("ads id is not provided"),
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"ads id is not provided",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
var spec adsdomain.AdsReq
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed to unmarshal body",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.(validator.ValidationErrors).Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := adsSvc.Update(adsID, spec); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string
|
||||
}{
|
||||
Message: "update ads success",
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package logshttp
|
||||
|
||||
import (
|
||||
logsdomain "legalgo-BE-go/internal/domain/logs"
|
||||
logssvc "legalgo-BE-go/internal/services/logs"
|
||||
usersvc "legalgo-BE-go/internal/services/user"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func CreateLogAds(
|
||||
router chi.Router,
|
||||
userSvc usersvc.User,
|
||||
logsSvc logssvc.Log,
|
||||
validate *validator.Validate,
|
||||
) {
|
||||
router.Post("/logs/ads", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var specReq logsdomain.LogsSpec
|
||||
|
||||
var spec logsdomain.LogsRequest
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed unmarshal body",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if ip := r.Header.Get("X-Ip-Address"); ip != "" {
|
||||
specReq.IP = &ip
|
||||
}
|
||||
|
||||
if userAgent := r.Header.Get("X-User-Agent"); userAgent != "" {
|
||||
specReq.UserAgent = &userAgent
|
||||
}
|
||||
|
||||
if err := logsSvc.CreateLogAds(specReq); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string
|
||||
}{
|
||||
Message: "logs ads recorded successfully",
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package logshttp
|
||||
|
||||
import (
|
||||
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
|
||||
logssvc "legalgo-BE-go/internal/services/logs"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func GetUserAds(
|
||||
router chi.Router,
|
||||
logSvc logssvc.Log,
|
||||
) {
|
||||
router.With(authmiddleware.Authorize()).Get("/logs/ads", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
userDetail, err := utils.GetTokenDetail(r)
|
||||
|
||||
subsPlan, err := logSvc.GetAllLogAds(userDetail.ID)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, subsPlan)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package logshttp
|
||||
|
||||
import "go.uber.org/fx"
|
||||
|
||||
var Module = fx.Module("logs-http", fx.Invoke(
|
||||
CreateLogAds,
|
||||
GetUserAds,
|
||||
))
|
||||
@@ -59,20 +59,7 @@ func Create(
|
||||
return
|
||||
}
|
||||
|
||||
staffProfile, err := staffRepo.GetStaffByEmail(destructedToken.Email)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := newsSvc.Create(spec, staffProfile.ID); err != nil {
|
||||
if err := newsSvc.Create(spec, destructedToken.ID); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
|
||||
@@ -15,7 +15,7 @@ func GetAll(
|
||||
) {
|
||||
router.Get("/news", func(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
news []newsdomain.News
|
||||
news []newsdomain.NewsResponse
|
||||
err error
|
||||
)
|
||||
ctx := r.Context()
|
||||
@@ -23,8 +23,15 @@ func GetAll(
|
||||
|
||||
category := query.Get("categories")
|
||||
tags := query.Get("tags")
|
||||
activeOnly := query.Get("active")
|
||||
search := query.Get("q")
|
||||
|
||||
news, err = newsSvc.GetAll(category, tags)
|
||||
news, err = newsSvc.GetAll(newsdomain.Filter{
|
||||
Category: category,
|
||||
Tags: tags,
|
||||
Active: activeOnly,
|
||||
Search: search,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package newshttp
|
||||
|
||||
import (
|
||||
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
|
||||
logssvc "legalgo-BE-go/internal/services/logs"
|
||||
newssvc "legalgo-BE-go/internal/services/news"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func GetByID(
|
||||
router chi.Router,
|
||||
newsSvc newssvc.News,
|
||||
logSvc logssvc.Log,
|
||||
) {
|
||||
router.With(authmiddleware.Authorize()).Get("/staff/news/{id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
id := chi.URLParam(r, "id")
|
||||
|
||||
token, err := utils.GetToken(r)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
staffDetail, err := utils.DestructToken(token)
|
||||
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if staffDetail.Role != "staff" {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrUnauthorized.Code,
|
||||
response.ErrUnauthorized.HttpCode,
|
||||
"unauthorized",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
news, err := newsSvc.GetByID(id)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, news)
|
||||
})
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
package newshttp
|
||||
|
||||
import (
|
||||
logsdomain "legalgo-BE-go/internal/domain/logs"
|
||||
logssvc "legalgo-BE-go/internal/services/logs"
|
||||
newssvc "legalgo-BE-go/internal/services/news"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -11,6 +14,7 @@ import (
|
||||
func GetBySlug(
|
||||
router chi.Router,
|
||||
newsSvc newssvc.News,
|
||||
logSvc logssvc.Log,
|
||||
) {
|
||||
router.Get("/news/{slug}", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
@@ -29,6 +33,38 @@ func GetBySlug(
|
||||
return
|
||||
}
|
||||
|
||||
userDetail, _ := utils.GetTokenDetail(r)
|
||||
|
||||
if userDetail.Role != "staff" {
|
||||
var specReq logsdomain.LogsSpec
|
||||
|
||||
specReq.ContentID = news.ID
|
||||
|
||||
if userDetail.ID != "" {
|
||||
specReq.UserID = &userDetail.ID
|
||||
}
|
||||
|
||||
if ip := r.Header.Get("X-Ip-Address"); ip != "" {
|
||||
specReq.IP = &ip
|
||||
}
|
||||
|
||||
if userAgent := r.Header.Get("X-User-Agent"); userAgent != "" {
|
||||
specReq.UserAgent = &userAgent
|
||||
}
|
||||
|
||||
if err := logSvc.CreateLogNews(specReq); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, news)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import "go.uber.org/fx"
|
||||
var Module = fx.Module("news", fx.Invoke(
|
||||
GetAll,
|
||||
GetBySlug,
|
||||
GetByID,
|
||||
Create,
|
||||
Update,
|
||||
Delete,
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
|
||||
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||
authsvc "legalgo-BE-go/internal/services/auth"
|
||||
newssvc "legalgo-BE-go/internal/services/news"
|
||||
staffsvc "legalgo-BE-go/internal/services/staff"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
func Update(
|
||||
router chi.Router,
|
||||
newsSvc newssvc.News,
|
||||
authSvc authsvc.Auth,
|
||||
authSvc staffsvc.Auth,
|
||||
) {
|
||||
router.With(authmiddleware.Authorize()).
|
||||
Put("/news/{news_id}/update", func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -48,19 +48,6 @@ func Update(
|
||||
return
|
||||
}
|
||||
|
||||
staff, err := authSvc.GetStaffProfile(destructedToken.Email)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
var spec newsdomain.NewsUpdate
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
@@ -76,7 +63,7 @@ func Update(
|
||||
|
||||
spec.ID = newsID
|
||||
|
||||
if err := newsSvc.Update(staff.ID, spec); err != nil {
|
||||
if err := newsSvc.Update(destructedToken.ID, spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
|
||||
@@ -3,9 +3,10 @@ package internalhttp
|
||||
import (
|
||||
adshttp "legalgo-BE-go/internal/api/http/ads"
|
||||
categoryhttp "legalgo-BE-go/internal/api/http/category"
|
||||
logshttp "legalgo-BE-go/internal/api/http/logs"
|
||||
newshttp "legalgo-BE-go/internal/api/http/news"
|
||||
osshttp "legalgo-BE-go/internal/api/http/oss"
|
||||
staffhttp "legalgo-BE-go/internal/api/http/staffhttp"
|
||||
staffhttp "legalgo-BE-go/internal/api/http/staff"
|
||||
subscribehttp "legalgo-BE-go/internal/api/http/subscribe"
|
||||
subscribeplanhttp "legalgo-BE-go/internal/api/http/subscribe_plan"
|
||||
taghttp "legalgo-BE-go/internal/api/http/tag"
|
||||
@@ -33,6 +34,7 @@ var Module = fx.Module("router",
|
||||
userhttp.Module,
|
||||
subscribehttp.Module,
|
||||
adshttp.Module,
|
||||
logshttp.Module,
|
||||
)
|
||||
|
||||
func initRouter() chi.Router {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package staffhttp
|
||||
|
||||
import (
|
||||
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
|
||||
staffsvc "legalgo-BE-go/internal/services/staff"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func GetStaffs(
|
||||
router chi.Router,
|
||||
staffSvc staffsvc.Auth,
|
||||
) {
|
||||
router.With(authmiddleware.Authorize()).Get("/staff/get-all", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
staffDetail, err := utils.GetTokenDetail(r)
|
||||
if err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed to get staff token",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if staffDetail.Role != "staff" {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrUnauthorized.Code,
|
||||
response.ErrUnauthorized.HttpCode,
|
||||
"unauthorized",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
staffs, err := staffSvc.GetStaffs()
|
||||
if err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, staffs)
|
||||
})
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package staffhttp
|
||||
|
||||
import (
|
||||
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
|
||||
authsvc "legalgo-BE-go/internal/services/auth"
|
||||
staffsvc "legalgo-BE-go/internal/services/staff"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
func GetUsers(
|
||||
router chi.Router,
|
||||
authSvc authsvc.Auth,
|
||||
authSvc staffsvc.Auth,
|
||||
) {
|
||||
router.With(authmiddleware.Authorize()).Get("/staff/users", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
responsedomain "legalgo-BE-go/internal/domain/reponse"
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
authsvc "legalgo-BE-go/internal/services/auth"
|
||||
staffsvc "legalgo-BE-go/internal/services/staff"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
|
||||
func Login(
|
||||
router chi.Router,
|
||||
authSvc authsvc.Auth,
|
||||
authSvc staffsvc.Auth,
|
||||
validate *validator.Validate,
|
||||
rdb *redis.Client,
|
||||
) {
|
||||
@@ -49,7 +49,7 @@ func Login(
|
||||
return
|
||||
}
|
||||
|
||||
token, err := authSvc.LoginAsStaff(spec)
|
||||
token, err := authSvc.Login(spec)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
@@ -9,5 +9,6 @@ var Module = fx.Module("auth-api",
|
||||
Update,
|
||||
GetProfile,
|
||||
GetUsers,
|
||||
GetStaffs,
|
||||
),
|
||||
)
|
||||
@@ -1,7 +1,7 @@
|
||||
package staffhttp
|
||||
|
||||
import (
|
||||
authsvc "legalgo-BE-go/internal/services/auth"
|
||||
staffsvc "legalgo-BE-go/internal/services/staff"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
func GetProfile(
|
||||
router chi.Router,
|
||||
authSvc authsvc.Auth,
|
||||
authSvc staffsvc.Auth,
|
||||
) {
|
||||
router.Get("/staff/profile", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
@@ -28,7 +28,7 @@ func GetProfile(
|
||||
return
|
||||
}
|
||||
|
||||
staffProfile, err := authSvc.GetStaffProfile(destructedToken.Email)
|
||||
staffProfile, err := authSvc.GetProfile(destructedToken.ID)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
@@ -3,9 +3,8 @@ package staffhttp
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
responsedomain "legalgo-BE-go/internal/domain/reponse"
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
authsvc "legalgo-BE-go/internal/services/auth"
|
||||
staffsvc "legalgo-BE-go/internal/services/staff"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
|
||||
@@ -17,7 +16,7 @@ import (
|
||||
func Register(
|
||||
router chi.Router,
|
||||
validate *validator.Validate,
|
||||
authSvc authsvc.Auth,
|
||||
authSvc staffsvc.Auth,
|
||||
rdb *redis.Client,
|
||||
) {
|
||||
router.Post("/staff/register", func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -49,7 +48,7 @@ func Register(
|
||||
return
|
||||
}
|
||||
|
||||
token, err := authSvc.RegisterStaff(spec)
|
||||
_, err := authSvc.Register(spec)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
@@ -62,21 +61,10 @@ func Register(
|
||||
return
|
||||
}
|
||||
|
||||
if err := utils.StoreTokenRedis(ctx, rdb, token, spec.Email); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
responsePayload := &responsedomain.Auth{
|
||||
Token: token,
|
||||
}
|
||||
response.RespondJsonSuccess(ctx, w, responsePayload)
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string
|
||||
}{
|
||||
Message: "staff created successfully.",
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package staffhttp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
authsvc "legalgo-BE-go/internal/services/auth"
|
||||
staffsvc "legalgo-BE-go/internal/services/staff"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
@@ -13,25 +12,25 @@ import (
|
||||
|
||||
func Update(
|
||||
router chi.Router,
|
||||
authSvc authsvc.Auth,
|
||||
authSvc staffsvc.Auth,
|
||||
) {
|
||||
router.Patch("/staff/{id}/update", func(w http.ResponseWriter, r *http.Request) {
|
||||
router.Put("/staff/update", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
id := chi.URLParam(r, "id")
|
||||
if id == "" {
|
||||
destructedToken, err := utils.GetTokenDetail(r)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
errors.New("provided id is empty"),
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"required params is not provided",
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
var spec staffdomain.StaffRegister
|
||||
var spec staffdomain.StaffUpdate
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
@@ -45,14 +44,7 @@ func Update(
|
||||
return
|
||||
}
|
||||
|
||||
staff := staffdomain.Staff{
|
||||
ID: id,
|
||||
Email: spec.Email,
|
||||
Password: spec.Password,
|
||||
Name: spec.Name,
|
||||
}
|
||||
|
||||
if err := authSvc.UpdateStaff(staff); err != nil {
|
||||
if err := authSvc.Update(destructedToken.ID, spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
@@ -60,7 +60,7 @@ func Update(
|
||||
return
|
||||
}
|
||||
|
||||
user, err := userRepo.GetUserProfile(detail.Email)
|
||||
user, err := userRepo.GetUserProfile(detail.ID)
|
||||
|
||||
body.ID = user.Subscribe.ID
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ func GetProfile(
|
||||
return
|
||||
}
|
||||
|
||||
userProfile, err := userSvc.GetUserProfile(destructedToken.Email)
|
||||
userProfile, err := userSvc.GetUserProfile(destructedToken.ID)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
|
||||
@@ -5,14 +5,23 @@ import (
|
||||
)
|
||||
|
||||
type Ads struct {
|
||||
ID string `gorm:"primaryKey;not null" json:"id"`
|
||||
ImageUrl string `gorm:"not null" json:"image_url"`
|
||||
Url string `gorm:"not null" json:"url"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
ID string `json:"id"`
|
||||
ImageUrl string `json:"image_url"`
|
||||
Url string `json:"url"`
|
||||
StartDate *time.Time `json:"start_date"`
|
||||
EndDate *time.Time `json:"end_date"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type AdsResponse struct {
|
||||
Ads
|
||||
Clicked int64 `json:"clicked"`
|
||||
}
|
||||
|
||||
type AdsReq struct {
|
||||
Image string `json:"image" validate:"required"`
|
||||
URL string `json:"url" validate:"required"`
|
||||
StartDate *time.Time `json:"start_date" validate:"required"`
|
||||
EndDate *time.Time `json:"end_date" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -4,4 +4,5 @@ type AuthToken struct {
|
||||
Email string
|
||||
SessionID string
|
||||
Role string
|
||||
ID string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package logsdomain
|
||||
|
||||
import (
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
)
|
||||
|
||||
type LogsRequest struct {
|
||||
AdsID string `json:"ads_id" validate:"required"`
|
||||
}
|
||||
|
||||
type LogsSpec struct {
|
||||
ContentID string `json:"content_id" validate:"required"`
|
||||
IP *string
|
||||
UserID *string
|
||||
UserAgent *string
|
||||
Category string
|
||||
}
|
||||
|
||||
type LogResponse struct {
|
||||
ID string `json:"id"`
|
||||
News []adsdomain.Ads `json:"news"`
|
||||
}
|
||||
@@ -27,8 +27,8 @@ type News struct {
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
FeaturedImage string `json:"featured_image"`
|
||||
Tags []tagdomain.Tag `gorm:"many2many:news_tags" json:"tags"`
|
||||
Categories []categorydomain.Category `gorm:"many2many:news_categories" json:"categories"`
|
||||
Tags []tagdomain.Tag `gorm:"many2many:news_tags;foreignKey:ID;joinForeignKey:news_id;References:ID;joinReferences:tag_id" json:"tags"`
|
||||
Categories []categorydomain.Category `gorm:"many2many:news_categories;foreignKey:ID;joinForeignKey:news_id;References:ID;joinReferences:category_id" json:"categories"`
|
||||
IsPremium bool `json:"is_premium"`
|
||||
Slug string `json:"slug"`
|
||||
AuthorID string `json:"author_id"`
|
||||
@@ -39,6 +39,11 @@ type News struct {
|
||||
Author Staff `json:"author"`
|
||||
}
|
||||
|
||||
type NewsResponse struct {
|
||||
News
|
||||
Views int64 `json:"views"`
|
||||
}
|
||||
|
||||
type NewsUpdate struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
@@ -50,7 +55,13 @@ type NewsUpdate struct {
|
||||
LiveAt time.Time `json:"live_at"`
|
||||
}
|
||||
|
||||
type Filter struct {
|
||||
Category, Tags, Active, Search string
|
||||
}
|
||||
|
||||
type NewsFilter struct {
|
||||
Tags []string
|
||||
Category []string
|
||||
Active string
|
||||
Search string
|
||||
}
|
||||
|
||||
@@ -15,6 +15,12 @@ type StaffRegister struct {
|
||||
ProfilePicture string `json:"profile_picture"`
|
||||
}
|
||||
|
||||
type StaffUpdate struct {
|
||||
Email string `json:"email" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
ProfilePicture string `json:"profile_picture"`
|
||||
}
|
||||
|
||||
type StaffProfile struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
|
||||
@@ -11,6 +11,7 @@ type User struct {
|
||||
Password string `json:"password"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
Subscribe subscribe.Subscribe `gorm:"foreignKey:SubscribeID" json:"subscribe"`
|
||||
}
|
||||
@@ -26,6 +27,7 @@ type UserProfile struct {
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
Subscribe subscribe.Subscribe `gorm:"foreignKey:SubscribeID" json:"subscribe"`
|
||||
}
|
||||
|
||||
@@ -10,4 +10,5 @@ const (
|
||||
ISSUED_AT JWTClaim = "iat"
|
||||
RESOURCES JWTClaim = "resources"
|
||||
ROLE JWTClaim = "role"
|
||||
ID JWTClaim = "skb"
|
||||
)
|
||||
|
||||
@@ -21,6 +21,8 @@ func (i *impl) Create(spec adsdomain.AdsReq) error {
|
||||
ID: uuid.NewString(),
|
||||
ImageUrl: spec.Image,
|
||||
Url: spec.URL,
|
||||
StartDate: spec.StartDate,
|
||||
EndDate: spec.EndDate,
|
||||
}
|
||||
|
||||
return i.adsRepo.Create(newSpec)
|
||||
|
||||
@@ -2,6 +2,6 @@ package adssvc
|
||||
|
||||
import adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
|
||||
func (i *impl) GetAll() ([]adsdomain.Ads, error) {
|
||||
func (i *impl) GetAll() ([]adsdomain.AdsResponse, error) {
|
||||
return i.adsRepo.GetAll()
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ type impl struct {
|
||||
|
||||
type Ads interface {
|
||||
Create(adsdomain.AdsReq) error
|
||||
GetAll() ([]adsdomain.Ads, error)
|
||||
GetAll() ([]adsdomain.AdsResponse, error)
|
||||
Update(string, adsdomain.AdsReq) error
|
||||
Delete(string) error
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package adssvc
|
||||
|
||||
import (
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
timeutils "legalgo-BE-go/internal/utilities/time_utils"
|
||||
)
|
||||
|
||||
func (i *impl) Update(adsID string, spec adsdomain.AdsReq) error {
|
||||
newsSpec := adsdomain.Ads{
|
||||
ID: adsID,
|
||||
ImageUrl: spec.Image,
|
||||
Url: spec.URL,
|
||||
UpdatedAt: timeutils.Now(),
|
||||
StartDate: spec.StartDate,
|
||||
EndDate: spec.EndDate,
|
||||
}
|
||||
|
||||
return i.adsRepo.Update(newsSpec)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package authsvc
|
||||
|
||||
import (
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
)
|
||||
|
||||
func (as *impl) UpdateStaff(spec staffdomain.Staff) error {
|
||||
if _, err := as.staffRepo.GetStaffByID(spec.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := as.staffRepo.Update(spec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package logssvc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
logsdomain "legalgo-BE-go/internal/domain/logs"
|
||||
)
|
||||
|
||||
func (i *impl) CreateLogAds(spec logsdomain.LogsSpec) error {
|
||||
spec.Category = "ads"
|
||||
if err := i.logsRepo.CreateLog(spec); err != nil {
|
||||
return fmt.Errorf("failed to create ads log: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package logssvc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
logsdomain "legalgo-BE-go/internal/domain/logs"
|
||||
)
|
||||
|
||||
func (i *impl) CreateLogNews(spec logsdomain.LogsSpec) error {
|
||||
spec.Category = "news"
|
||||
if err := i.logsRepo.CreateLog(spec); err != nil {
|
||||
return fmt.Errorf("failed to create news log: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package logssvc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
)
|
||||
|
||||
func (i *impl) GetAllLogAds(userID string) ([]adsdomain.Ads, error) {
|
||||
var (
|
||||
logs []adsdomain.Ads
|
||||
err error
|
||||
)
|
||||
|
||||
logs, err = i.logsRepo.GetAllLogAds(userID)
|
||||
if err != nil {
|
||||
return logs, fmt.Errorf("failed to get user logs ads: %v", err)
|
||||
}
|
||||
|
||||
return logs, nil
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package logssvc
|
||||
|
||||
import (
|
||||
logrepository "legalgo-BE-go/internal/accessor/log"
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
logsdomain "legalgo-BE-go/internal/domain/logs"
|
||||
)
|
||||
|
||||
type impl struct {
|
||||
logsRepo logrepository.Log
|
||||
}
|
||||
|
||||
type Log interface {
|
||||
CreateLogAds(logsdomain.LogsSpec) error
|
||||
CreateLogNews(logsdomain.LogsSpec) error
|
||||
GetAllLogAds(string) ([]adsdomain.Ads, error)
|
||||
}
|
||||
|
||||
func New(
|
||||
logsRepo logrepository.Log,
|
||||
) Log {
|
||||
return &impl{
|
||||
logsRepo,
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,11 @@ package services
|
||||
|
||||
import (
|
||||
adssvc "legalgo-BE-go/internal/services/ads"
|
||||
serviceauth "legalgo-BE-go/internal/services/auth"
|
||||
categorysvc "legalgo-BE-go/internal/services/category"
|
||||
logssvc "legalgo-BE-go/internal/services/logs"
|
||||
newssvc "legalgo-BE-go/internal/services/news"
|
||||
"legalgo-BE-go/internal/services/oss"
|
||||
staffsvc "legalgo-BE-go/internal/services/staff"
|
||||
subscribesvc "legalgo-BE-go/internal/services/subscribe"
|
||||
subscribeplansvc "legalgo-BE-go/internal/services/subscribe_plan"
|
||||
tagsvc "legalgo-BE-go/internal/services/tag"
|
||||
@@ -16,7 +17,7 @@ import (
|
||||
|
||||
var Module = fx.Module("services",
|
||||
fx.Provide(
|
||||
serviceauth.New,
|
||||
staffsvc.New,
|
||||
subscribeplansvc.New,
|
||||
subscribesvc.New,
|
||||
tagsvc.New,
|
||||
@@ -25,5 +26,6 @@ var Module = fx.Module("services",
|
||||
oss.NewOSSService,
|
||||
usersvc.New,
|
||||
adssvc.New,
|
||||
logssvc.New,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -5,15 +5,15 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (i *impl) GetAll(categoriesCode, tagCodes string) ([]newsdomain.News, error) {
|
||||
func (i *impl) GetAll(filter newsdomain.Filter) ([]newsdomain.NewsResponse, error) {
|
||||
var err error
|
||||
|
||||
categories := []string{}
|
||||
tags := []string{}
|
||||
news := []newsdomain.News{}
|
||||
news := []newsdomain.NewsResponse{}
|
||||
|
||||
tagCodeArr := strings.Split(tagCodes, " ")
|
||||
categoryCodeArr := strings.Split(categoriesCode, " ")
|
||||
tagCodeArr := strings.Split(filter.Tags, " ")
|
||||
categoryCodeArr := strings.Split(filter.Category, " ")
|
||||
|
||||
if len(tagCodeArr) > 0 && tagCodeArr[0] != "" {
|
||||
tags, err = i.tagRepo.GetIDsByCodes(tagCodeArr)
|
||||
@@ -37,9 +37,11 @@ func (i *impl) GetAll(categoriesCode, tagCodes string) ([]newsdomain.News, error
|
||||
}
|
||||
}
|
||||
|
||||
filter := newsdomain.NewsFilter{
|
||||
filterSpec := newsdomain.NewsFilter{
|
||||
Tags: tags,
|
||||
Category: categories,
|
||||
Active: filter.Active,
|
||||
Search: filter.Search,
|
||||
}
|
||||
return i.newsRepo.GetAll(filter)
|
||||
return i.newsRepo.GetAll(filterSpec)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package newssvc
|
||||
|
||||
import newsdomain "legalgo-BE-go/internal/domain/news"
|
||||
|
||||
func (i *impl) GetByID(id string) (*newsdomain.News, error) {
|
||||
return i.newsRepo.GetByID(id)
|
||||
}
|
||||
@@ -16,8 +16,9 @@ type impl struct {
|
||||
}
|
||||
|
||||
type News interface {
|
||||
GetAll(string, string) ([]newsdomain.News, error)
|
||||
GetAll(filter newsdomain.Filter) ([]newsdomain.NewsResponse, error)
|
||||
GetBySlug(string) (*newsdomain.News, error)
|
||||
GetByID(string) (*newsdomain.News, error)
|
||||
Create(newsdomain.NewsReq, string) error
|
||||
Update(string, newsdomain.NewsUpdate) error
|
||||
Delete(string) error
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package authsvc
|
||||
package staffsvc
|
||||
|
||||
import (
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
)
|
||||
|
||||
func (as *impl) GetStaffProfile(email string) (*staffdomain.StaffProfile, error) {
|
||||
staff, err := as.staffRepo.GetStaffByEmail(email)
|
||||
func (as *impl) GetProfile(id string) (*staffdomain.StaffProfile, error) {
|
||||
staff, err := as.staffRepo.GetStaffByID(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package staffsvc
|
||||
|
||||
import staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
|
||||
func (i *impl) GetStaffs() ([]staffdomain.StaffProfile, error) {
|
||||
return i.staffRepo.GetStaffs()
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package authsvc
|
||||
package staffsvc
|
||||
|
||||
import userdomain "legalgo-BE-go/internal/domain/user"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package authsvc
|
||||
package staffsvc
|
||||
|
||||
import (
|
||||
staffrepository "legalgo-BE-go/internal/accessor/staff"
|
||||
@@ -17,11 +17,12 @@ type impl struct {
|
||||
}
|
||||
|
||||
type Auth interface {
|
||||
LoginAsStaff(staffdomain.StaffLogin) (string, error)
|
||||
RegisterStaff(staffdomain.StaffRegister) (string, error)
|
||||
GetStaffProfile(string) (*staffdomain.StaffProfile, error)
|
||||
Login(staffdomain.StaffLogin) (string, error)
|
||||
Register(staffdomain.StaffRegister) (string, error)
|
||||
GetProfile(string) (*staffdomain.StaffProfile, error)
|
||||
GetStaffs() ([]staffdomain.StaffProfile, error)
|
||||
GetUsers() ([]userdomain.UserProfile, error)
|
||||
UpdateStaff(staffdomain.Staff) error
|
||||
Update(string, staffdomain.StaffUpdate) error
|
||||
}
|
||||
|
||||
func New(
|
||||
@@ -1,8 +1,7 @@
|
||||
package authsvc
|
||||
package staffsvc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"fmt"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
@@ -10,26 +9,27 @@ import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (sv *impl) LoginAsStaff(spec staffdomain.StaffLogin) (string, error) {
|
||||
func (sv *impl) Login(spec staffdomain.StaffLogin) (string, error) {
|
||||
staff, err := sv.staffRepo.GetStaffByEmail(spec.Email)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
matchPassword := utils.ComparePassword(staff.Password, spec.Password)
|
||||
if !matchPassword {
|
||||
return "", errors.New("wrong password")
|
||||
return "", fmt.Errorf("wrong password")
|
||||
}
|
||||
|
||||
authToken := authdomain.AuthToken{
|
||||
Email: staff.Email,
|
||||
SessionID: uuid.NewString(),
|
||||
Role: "staff",
|
||||
ID: staff.ID,
|
||||
}
|
||||
|
||||
token, err := utils.GenerateToken(authToken)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
return token, nil
|
||||
@@ -1,8 +1,7 @@
|
||||
package authsvc
|
||||
package staffsvc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"fmt"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
@@ -10,10 +9,10 @@ import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (a *impl) RegisterStaff(spec staffdomain.StaffRegister) (string, error) {
|
||||
func (a *impl) Register(spec staffdomain.StaffRegister) (string, error) {
|
||||
_, err := a.staffRepo.GetStaffByEmail(spec.Email)
|
||||
if err == nil {
|
||||
return "", errors.New("this email address is already in use")
|
||||
return "", fmt.Errorf("this email address is already in use")
|
||||
}
|
||||
hashedPwd, err := utils.HashPassword(spec.Password)
|
||||
if err != nil {
|
||||
@@ -30,18 +29,19 @@ func (a *impl) RegisterStaff(spec staffdomain.StaffRegister) (string, error) {
|
||||
|
||||
err = a.staffRepo.Create(staff)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
authToken := authdomain.AuthToken{
|
||||
Email: staff.Email,
|
||||
SessionID: uuid.NewString(),
|
||||
Role: "staff",
|
||||
ID: staff.ID,
|
||||
}
|
||||
|
||||
token, err := utils.GenerateToken(authToken)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
return "", err
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package staffsvc
|
||||
|
||||
import (
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
)
|
||||
|
||||
func (as *impl) Update(id string, spec staffdomain.StaffUpdate) error {
|
||||
if _, err := as.staffRepo.GetStaffByID(id); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newSpec := staffdomain.Staff{
|
||||
ID: id,
|
||||
Email: spec.Email,
|
||||
Name: spec.Name,
|
||||
ProfilePicture: spec.ProfilePicture,
|
||||
}
|
||||
|
||||
if err := as.staffRepo.Update(newSpec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
userdomain "legalgo-BE-go/internal/domain/user"
|
||||
)
|
||||
|
||||
func (i *impl) GetUserProfile(email string) (*userdomain.UserProfile, error) {
|
||||
user, err := i.userRepo.GetUserProfile(email)
|
||||
func (i *impl) GetUserProfile(id string) (*userdomain.UserProfile, error) {
|
||||
user, err := i.userRepo.GetUserProfile(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package usersvc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"fmt"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
userdomain "legalgo-BE-go/internal/domain/user"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
@@ -13,23 +12,24 @@ import (
|
||||
func (i *impl) LoginAsUser(spec userdomain.UserLogin) (string, error) {
|
||||
user, err := i.userRepo.GetUserByEmail(spec.Email)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
matchPassword := utils.ComparePassword(user.Password, spec.Password)
|
||||
if !matchPassword {
|
||||
return "", errors.New("wrong password")
|
||||
return "", fmt.Errorf("wrong password")
|
||||
}
|
||||
|
||||
authToken := authdomain.AuthToken{
|
||||
Email: user.Email,
|
||||
SessionID: uuid.NewString(),
|
||||
Role: "user",
|
||||
ID: user.ID,
|
||||
}
|
||||
|
||||
token, err := utils.GenerateToken(authToken)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
return token, nil
|
||||
@@ -1,8 +1,7 @@
|
||||
package usersvc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"fmt"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
userdomain "legalgo-BE-go/internal/domain/user"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
@@ -14,7 +13,7 @@ func (i *impl) RegisterUser(spec userdomain.UserRegister) (string, error) {
|
||||
_, err := i.userRepo.GetUserByEmail(spec.Email)
|
||||
|
||||
if err == nil {
|
||||
return "", errors.New("this email address is already in use")
|
||||
return "", fmt.Errorf("this email address is already in use")
|
||||
}
|
||||
|
||||
if spec.SubscribePlanID == "" {
|
||||
@@ -28,7 +27,7 @@ func (i *impl) RegisterUser(spec userdomain.UserRegister) (string, error) {
|
||||
|
||||
_, err = i.subsPlanRepo.GetByID(spec.SubscribePlanID)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
subsId, err := i.subsRepo.Create(spec.SubscribePlanID)
|
||||
@@ -51,18 +50,19 @@ func (i *impl) RegisterUser(spec userdomain.UserRegister) (string, error) {
|
||||
|
||||
err = i.userRepo.CreateUser(user)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
return "", fmt.Errorf("create user failed: %v", err)
|
||||
}
|
||||
|
||||
authToken := authdomain.AuthToken{
|
||||
Email: user.Email,
|
||||
SessionID: uuid.NewString(),
|
||||
Role: "user",
|
||||
ID: user.ID,
|
||||
}
|
||||
|
||||
token, err := utils.GenerateToken(authToken)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
return "", fmt.Errorf("generate token failed: %v", err)
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
@@ -18,6 +18,7 @@ var (
|
||||
ErrUnauthorized = &ErrorCode{Code: "UNAUTHORIZED", Message: "UNAUTHORIZED", HttpCode: http.StatusUnauthorized}
|
||||
ErrDBRequest = &ErrorCode{Code: "BAD_DB_REQUEST", Message: "DB_ERROR", HttpCode: http.StatusBadRequest}
|
||||
ErrExpiryToken = &ErrorCode{Code: "EXPIRED_TOKEN", Message: "EXPIRED_TOKEN", HttpCode: http.StatusUnauthorized}
|
||||
ErrNotFound = &ErrorCode{Code: "NOT_FOUND", Message: "NOT_FOUND", HttpCode: http.StatusNotFound}
|
||||
|
||||
// 5xx
|
||||
ErrMarshal = &ErrorCode{Code: "FAILED_MARSHAL", Message: "FAILED_MARSHAL_BODY", HttpCode: http.StatusInternalServerError}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -13,16 +13,16 @@ func GetTokenDetail(r *http.Request) (authdomain.AuthToken, error) {
|
||||
var data authdomain.AuthToken
|
||||
|
||||
if authHeader == "" {
|
||||
return data, errors.New("unauthorized")
|
||||
return data, fmt.Errorf("unauthorized")
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(authHeader, "Bearer") {
|
||||
return data, errors.New("invalid token")
|
||||
return data, fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
token := strings.Split(authHeader, " ")
|
||||
if len(token) < 2 {
|
||||
return data, errors.New("invalid token")
|
||||
return data, fmt.Errorf("invalid token")
|
||||
}
|
||||
data, err := DestructToken(token[1])
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -37,6 +36,7 @@ func GenerateToken(data authdomain.AuthToken) (string, error) {
|
||||
string(jwtclaimenum.EMAIL): data.Email,
|
||||
string(jwtclaimenum.ROLE): data.Role,
|
||||
string(jwtclaimenum.SESSION_ID): data.SessionID,
|
||||
string(jwtclaimenum.ID): data.ID,
|
||||
string(jwtclaimenum.EXPIRED_AT): now.Add(time.Minute * time.Duration(config.REDIS_TIMEOUT)).Unix(),
|
||||
}
|
||||
|
||||
@@ -66,32 +66,38 @@ func DestructToken(s string) (authdomain.AuthToken, error) {
|
||||
claims, ok := token.Claims.(jwt.MapClaims)
|
||||
|
||||
if !ok {
|
||||
return data, errors.New("failed to parse token")
|
||||
return data, fmt.Errorf("failed to parse token")
|
||||
}
|
||||
|
||||
if !token.Valid {
|
||||
return data, errors.New("invalid token")
|
||||
return data, fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
email, ok := claims[string(jwtclaimenum.EMAIL)].(string)
|
||||
if !ok {
|
||||
return data, errors.New("invalid email")
|
||||
return data, fmt.Errorf("invalid email")
|
||||
}
|
||||
|
||||
sessionId, ok := claims[string(jwtclaimenum.SESSION_ID)].(string)
|
||||
if !ok {
|
||||
return data, errors.New("invalid session_id")
|
||||
return data, fmt.Errorf("invalid session_id")
|
||||
}
|
||||
|
||||
role, ok := claims[string(jwtclaimenum.ROLE)].(string)
|
||||
if !ok {
|
||||
return data, errors.New("invalid role")
|
||||
return data, fmt.Errorf("invalid role")
|
||||
}
|
||||
|
||||
id, ok := claims[string(jwtclaimenum.ID)].(string)
|
||||
if !ok {
|
||||
return data, fmt.Errorf("invalid id")
|
||||
}
|
||||
|
||||
data = authdomain.AuthToken{
|
||||
Email: email,
|
||||
SessionID: sessionId,
|
||||
Role: role,
|
||||
ID: id,
|
||||
}
|
||||
|
||||
return data, nil
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
@@ -11,14 +11,14 @@ func StructToMap(s any) (map[string]any, error) {
|
||||
val := reflect.ValueOf(s)
|
||||
|
||||
if val.Kind() != reflect.Struct {
|
||||
return nil, errors.New("provided value is not struct")
|
||||
return nil, fmt.Errorf("provided value is not struct")
|
||||
}
|
||||
|
||||
for i := range val.NumField() {
|
||||
field := val.Type().Field(i)
|
||||
value := val.Field(i)
|
||||
|
||||
if value.IsZero() || value.IsNil() {
|
||||
if !value.IsValid() {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user