35 Commits
Author SHA1 Message Date
ericprd 1ae192ccef feat: get all ads 2025-03-09 00:55:40 +08:00
ericprd 213d370332 feat: create ads 2025-03-09 00:47:24 +08:00
ericprd 13c976dcbf fix: update user plan and rearrange structur project 2025-03-08 22:46:05 +08:00
Ardeman a47b7b7d3d feat: update Category model and request struct to use pointers for description and sequence fields 2025-03-08 00:05:04 +08:00
Ardeman c5eb6302ab feat: add description and sequence fields to Create and Update category functions 2025-03-07 23:58:53 +08:00
Ardeman 68f33d101b feat: add description and sequence fields to Category model and update request struct 2025-03-07 23:41:54 +08:00
Ardeman 479703dfd0 feat: add description field to Category model and clean up migration code 2025-03-07 23:26:54 +08:00
ericprd dc1a4dafbc fix: failed to migrate 2025-03-07 19:29:34 +08:00
ericprd fdf572cd3d feat: refactor auth package and add get users for staff 2025-03-07 17:39:26 +08:00
ericprd c48a4b944b fix: update tags and categories not updated 2025-03-07 15:16:05 +08:00
ericprd c410e651ce fix: categories filter is multiple now 2025-03-07 14:30:31 +08:00
ericprd 51b50a3132 fix: get news by query category and tags filters 2025-03-07 00:55:50 +08:00
ericprd e3a9b67e28 feat: update news 2025-03-06 23:55:46 +08:00
ericprd 2046021e01 Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-03-06 13:30:39 +08:00
ericprd a2a6fe6374 fix: use redis config 2025-03-06 13:30:24 +08:00
Ardeman d6a680634c chore: remove deprecated jwt dependency and update to v5 2025-03-06 12:58:28 +08:00
ericprd cf410bdf05 feat: add redis config env 2025-03-06 12:56:35 +08:00
ericprd efc87ee63e Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-03-06 11:59:17 +08:00
ericprd c037da4879 feat: add vendor 2025-03-06 11:59:05 +08:00
0xCA7andGitHub 53fda59e3c Delete .DS_Store 2025-03-06 11:17:10 +08:00
ericprd 2525eed2ea Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-03-06 11:07:04 +08:00
ericprd 85247643e6 feat: get news by slug and and author detail 2025-03-06 11:06:06 +08:00
ericprd d217ec8a62 feat: delete news, tag, and category 2025-03-05 23:55:41 +08:00
ericprd 299fcf949b feat: update and delete tags and categories 2025-03-05 23:13:24 +08:00
ericprd 5c699dfa53 fix: create and get news 2025-03-05 22:15:39 +08:00
ericprd dd109c8aa0 chores: remove unused code 2025-03-05 21:27:37 +08:00
ericprd 567e0e32ca chores: refactor struct and structure project 2025-03-05 21:21:44 +08:00
altru 2b54a9343b Merge pull request 'Update Env' (#4) from feature-test into main
Reviewed-on: #4
2025-03-03 12:56:18 +00:00
altru 43d5608a51 Merge pull request 'update docker' (#3) from feature-test into main
Reviewed-on: #3
2025-03-03 12:39:25 +00:00
altru 883ff8b7d1 Merge pull request 'add docker file' (#2) from feature-test into main
Reviewed-on: #2
2025-03-03 12:30:23 +00:00
altru 750a4dc3db Merge pull request 'Add Infra' (#1) from feature-test into main
Reviewed-on: #1
2025-03-03 12:03:19 +00:00
ericprd 13a8481f22 fix: payload update staff 2025-03-03 13:23:04 +08:00
ericprd 642566c8b2 Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-03-03 10:39:38 +08:00
ericprd afe6f4e9a6 fix: change username to name and add profile pic to staff 2025-03-03 10:39:01 +08:00
Ardeman 20c9660c3a docs: add instruction to execute binary directly 2025-03-02 22:43:39 +08:00
236 changed files with 5119 additions and 3364 deletions
+1
View File
@@ -14,3 +14,4 @@ REDIS_PORT=
REDIS_PASSWORD=
REDIS_TTL=
REDIS_DB=
REDIS_TIMEOUT=
+2
View File
@@ -1,2 +1,4 @@
bin
.env
.DS_Store
/cmd/legalgo/env
+6
View File
@@ -148,6 +148,12 @@ make run
This command will compile and execute your Go application.
Or you can execute the compiled binary at `bin/legalgo` by:
```bash
./bin/legalgo
```
---
**Note:** Ensure that your `Makefile` is correctly set up to handle these commands. If not, you may need to create
+12 -1
View File
@@ -15,6 +15,7 @@ import (
"github.com/go-chi/chi/v5"
"github.com/joho/godotenv"
"github.com/redis/go-redis/v9"
"go.uber.org/fx"
)
@@ -32,16 +33,26 @@ func init() {
config.InitEnv()
}
func run(lc fx.Lifecycle, db *database.DB, apiRouter chi.Router) {
func run(
lc fx.Lifecycle,
db *database.DB,
apiRouter chi.Router,
rdb *redis.Client,
) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
fmt.Println("Application has started...")
_, err := rdb.Ping(ctx).Result()
if err != nil {
log.Fatalf("Could not connect to Redis: %v", err)
}
pkgconfig.Router(apiRouter)
return nil
},
OnStop: func(ctx context.Context) error {
fmt.Println("Shutting down...")
rdb.Close()
return nil
},
})
+14 -1
View File
@@ -1,7 +1,11 @@
package config
import "fmt"
var (
APP_PORT int
APP_PORT,
REDIS_DB,
REDIS_TIMEOUT,
GRACEFULL_TIMEOUT int
// DB
@@ -10,6 +14,9 @@ var (
DB_PASSWORD,
DB_NAME,
DB_PORT,
REDIS_PASSWORD,
REDIS_ADDR,
REDIS_USERNAME,
SALT_SECURITY string
)
@@ -24,4 +31,10 @@ func InitEnv() {
APP_PORT = GetOrDefault("APP_PORT", 3000)
GRACEFULL_TIMEOUT = GetOrDefault("GRACEFULL_TIMEOUT", 10)
REDIS_DB = GetOrDefault("REDIS_DB", 0)
REDIS_PASSWORD = GetOrDefault("REDIS_PASSWORD", "")
REDIS_ADDR = fmt.Sprintf("%s:%s", GetOrDefault("REDIS_HOST", "localhost"), GetOrDefault("REDIS_PORT", "6379"))
REDIS_USERNAME = GetOrDefault("REDIS_USERNAME", "")
REDIS_TIMEOUT = GetOrDefault("REDIS_TIMEOUT", 60)
}
+1
View File
@@ -28,6 +28,7 @@ type Config struct {
Database Database `mapstructure:"postgresql"`
Jwt Jwt `mapstructure:"jwt"`
OSSConfig OSSConfig `mapstructure:"oss"`
Redis Redis `mapstructure:"redis"`
}
var (
+14
View File
@@ -0,0 +1,14 @@
package config
type Redis struct {
Host string `mapstructure:"host"`
Port string `mapstructure:"port"`
DB int `mapstructure:"db"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
SslMode string `mapstructure:"ssl-mode"`
Debug bool `mapstructure:"debug"`
MaxIdleConnectionsInSecond int `mapstructure:"max-idle-connections-in-second"`
MaxOpenConnectionsInSecond int `mapstructure:"max-open-connections-in-second"`
ConnectionMaxLifetimeInSecond int64 `mapstructure:"connection-max-life-time-in-second"`
}
+11
View File
@@ -0,0 +1,11 @@
package database
import "time"
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"`
}
+5 -8
View File
@@ -6,16 +6,13 @@ import (
type Category struct {
ID string `gorm:"primaryKey" json:"id"`
Code string `gorm:"not null;unique" json:"code"`
Name string `gorm:"not null" json:"name"`
Code string `gorm:"not null;unique" json:"code"`
Description string `gorm:"default:null" json:"description"`
Sequence int `gorm:"default:null" json:"sequence"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
}
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
type CategoryModel struct {
ID string `gorm:"primaryKey" json:"id"`
Name string `gorm:"not null;unique" json:"name"`
Code string `gorm:"not null" json:"code"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
News []News `gorm:"many2many:news_categories" json:"news"`
}
+4 -10
View File
@@ -39,10 +39,6 @@ func NewDB(cfg *config.Config) (*DB, error) {
func (db *DB) DropTables() error {
// Auto Migrate the User model
return db.Migrator().DropTable(
// &Staff{},
// &SubscribePlan{},
// &Subscribe{},
// &User{},
&Tag{},
&Category{},
&News{},
@@ -55,11 +51,9 @@ func (db *DB) Migrate() error {
&SubscribePlan{},
&Subscribe{},
&User{},
// &Tag{},
// &Category{},
// &News{},
&NewsModel{},
&TagModel{},
&CategoryModel{},
&News{},
&Tag{},
&Category{},
&Ads{},
)
}
+5 -17
View File
@@ -5,26 +5,11 @@ import (
)
type News struct {
ID string `gorm:"primaryKey" json:"id"`
Title string `gorm:"default:null" json:"title"`
Tags []Tag `gorm:"many2many:news_tags" json:"tags"`
Categories []Category `gorm:"many2many:news_categories" json:"categories"`
Content string `gorm:"default:null" json:"content"`
LiveAt time.Time `gorm:"not null" json:"live_at"`
AuthorID string `gorm:"not null" json:"author_id"`
IsPremium bool `gorm:"default:false" json:"is_premium"`
Slug string `gorm:"default:null" json:"slug"`
FeaturedImage string `gorm:"default:null" json:"featured_image"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
}
type NewsModel struct {
ID string `gorm:"primaryKey" json:"id"`
Title string `json:"title"`
Content string `json:"content"`
Categories []CategoryModel `gorm:"many2many:news_categories" json:"categories"`
Tags []TagModel `gorm:"many2many:news_tags" json:"tags"`
Categories []Category `gorm:"many2many:news_categories" json:"categories"`
Tags []Tag `gorm:"many2many:news_tags" json:"tags"`
IsPremium bool `gorm:"default:false" json:"is_premium"`
Slug string `gorm:"default:null" json:"slug"`
FeaturedImage string `gorm:"default:null" json:"featured_image"`
@@ -32,4 +17,7 @@ type NewsModel struct {
LiveAt time.Time `gorm:"not null" json:"live_at"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
Author Staff `gorm:"foreignKey:AuthorID" json:"author"`
}
+3 -1
View File
@@ -6,9 +6,11 @@ import (
type Staff struct {
ID string `gorm:"primaryKey" json:"id"`
Username string `gorm:"default:null;unique" json:"username"`
Name string `gorm:"default:null" json:"name"`
ProfilePicture string `gorm:"default:null" json:"profile_picture"`
Email string `gorm:"unique;not null" json:"email"`
Password string `gorm:"not null" json:"password"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
}
+2 -1
View File
@@ -13,8 +13,9 @@ type Subscribe struct {
AutoRenew bool `gorm:"default:true"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
SubscribePlan SubscribePlan `gorm:"foreignKey:SubscribePlanID;constraint:OnDelete:CASCADE"`
SubscribePlan SubscribePlan `gorm:"foreignKey:SubscribePlanID;constraint:OnDelete:CASCADE" json:"subscribe_plan"`
}
type SubscribePlan struct {
@@ -6,16 +6,11 @@ import (
type Tag struct {
ID string `gorm:"primaryKey" json:"id"`
Code string `gorm:"not null;unique" json:"code"`
Name string `gorm:"not null" json:"name"`
Code string `gorm:"not null;unique" json:"code"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
}
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
type TagModel struct {
ID string `gorm:"primaryKey" json:"id"`
Name string `gorm:"not null;unique" json:"name"`
Code string `gorm:"not null" json:"code"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
News []News `gorm:"many2many:news_tags" json:"news"`
}
+2 -1
View File
@@ -12,6 +12,7 @@ type User struct {
Phone string `gorm:"default:not null;unique" json:"phone"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
Subscribe Subscribe `gorm:"foreignKey:SubscribeID;constraint:OnDelete:CASCADE"`
Subscribe Subscribe `gorm:"foreignKey:SubscribeID;constraint:OnDelete:CASCADE" json:"subscribe"`
}
+12 -1
View File
@@ -14,7 +14,7 @@ postgresql:
driver: postgres
db: legalgonews-dev
username: legalgo_admin
password: 'K4K!2Kg7c@KW6H&4A2aBy2dFCRY3Sh'
password: "K4K!2Kg7c@KW6H&4A2aBy2dFCRY3Sh"
ssl-mode: disable
max-idle-connections-in-second: 600
max-open-connections-in-second: 600
@@ -29,3 +29,14 @@ oss:
log_level: Error
host_url: https://sin1.contabostorage.com
public_url: https://sin1.contabostorage.com/fda98c2228f246f29a7e466b86b3b9e7
redis:
host: 62.72.45.250
port: 26379
password: mDtpsyEW8W26vwLhglpO
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
+2 -2
View File
@@ -9,7 +9,7 @@ require (
go.uber.org/fx v1.23.0
golang.org/x/crypto v0.34.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/postgres v1.4.7
gorm.io/driver/postgres v1.5.7
)
require (
@@ -20,7 +20,7 @@ require (
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.2.0 // indirect
github.com/jackc/pgx/v5 v5.4.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
+4 -55
View File
@@ -6,7 +6,6 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -41,16 +40,12 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8=
github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk=
github.com/jackc/puddle/v2 v2.1.2/go.mod h1:2lpufsF5mRHO6SuZkm0fNYxM6SWHfvyFj62KwNzgels=
github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
@@ -59,13 +54,8 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
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/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
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 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
@@ -81,7 +71,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.7.1 h1:4LhKRCIduqXqtvCUlaq9c8bdHOkICjDMrr1+Zb3osAc=
github.com/redis/go-redis/v9 v9.7.1/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
@@ -105,7 +94,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
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=
@@ -114,8 +102,6 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
@@ -126,67 +112,30 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
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.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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=
gorm.io/driver/postgres v1.4.7 h1:J06jXZCNq7Pdf7LIPn8tZn9LsWjd81BRSKveKNr0ZfA=
gorm.io/driver/postgres v1.4.7/go.mod h1:UJChCNLFKeBqQRE+HrkFUbKbq9idPXmTOk2u4Wok8S4=
gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
+14
View File
@@ -0,0 +1,14 @@
package adsrepository
import (
"fmt"
adsdomain "legalgo-BE-go/internal/domain/ads"
)
func (a *accessor) Create(spec adsdomain.Ads) error {
if err := a.db.Create(&spec).Error; err != nil {
return fmt.Errorf("failed to create ads: %v", err)
}
return nil
}
+15
View File
@@ -0,0 +1,15 @@
package adsrepository
import (
"fmt"
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 {
return ads, fmt.Errorf("failed to get all ads: %v", err)
}
return ads, nil
}
+21
View File
@@ -0,0 +1,21 @@
package adsrepository
import (
"legalgo-BE-go/database"
adsdomain "legalgo-BE-go/internal/domain/ads"
)
type accessor struct {
db *database.DB
}
type Ads interface {
Create(adsdomain.Ads) error
GetAll() ([]adsdomain.Ads, error)
}
func New(
db *database.DB,
) Ads {
return &accessor{db}
}
+6 -3
View File
@@ -1,19 +1,22 @@
package categoryrepository
import (
"legalgo-BE-go/database"
categorydomain "legalgo-BE-go/internal/domain/category"
"github.com/google/uuid"
)
func (a *accessor) Create(spec categorydomain.CategoryReq) error {
data := categorydomain.Category{
func (a *accessor) CreateModel(spec categorydomain.CategoryReq) error {
data := database.Category{
ID: uuid.NewString(),
Name: spec.Name,
Code: spec.Code,
Description: *spec.Description,
Sequence: *spec.Sequence,
}
if err := a.DB.Create(&data).Error; err != nil {
if err := a.db.Create(&data).Error; err != nil {
return err
}
@@ -1,22 +0,0 @@
package categoryrepository
import (
"legalgo-BE-go/database"
categorydomain "legalgo-BE-go/internal/domain/category"
"github.com/google/uuid"
)
func (a *accessor) CreateModel(spec categorydomain.CategoryReq) error {
data := database.CategoryModel{
ID: uuid.NewString(),
Name: spec.Name,
Code: spec.Code,
}
if err := a.DB.Create(&data).Error; err != nil {
return err
}
return nil
}
+24
View File
@@ -0,0 +1,24 @@
package categoryrepository
import (
"fmt"
"legalgo-BE-go/database"
)
func (a *accessor) Delete(id string) error {
var category database.Category
if err := a.db.First(&category, "id = ?", id).Error; err != nil {
return fmt.Errorf("failed to find category: %v", err)
}
if err := a.db.Model(&category).Association("News").Clear(); err != nil {
return fmt.Errorf("failed to remove categories association: %v", err)
}
if err := a.db.Delete(&category).Error; err != nil {
return fmt.Errorf("failed to delete category %s : %v", id, err)
}
return nil
}
+5 -3
View File
@@ -1,11 +1,13 @@
package categoryrepository
import categorydomain "legalgo-BE-go/internal/domain/category"
import (
categorydomain "legalgo-BE-go/internal/domain/category"
)
func (a *accessor) GetAll() ([]categorydomain.Category, error) {
func (a *accessor) GetAllModel() ([]categorydomain.Category, error) {
var categories []categorydomain.Category
if err := a.DB.Find(&categories).Error; err != nil {
if err := a.db.Find(&categories).Error; err != nil {
return nil, err
}
@@ -1,15 +0,0 @@
package categoryrepository
import (
"legalgo-BE-go/database"
)
func (a *accessor) GetAllModel() ([]database.CategoryModel, error) {
var categories []database.CategoryModel
if err := a.DB.Find(&categories).Error; err != nil {
return nil, err
}
return categories, nil
}
@@ -1,15 +0,0 @@
package categoryrepository
import (
"legalgo-BE-go/database"
)
func (a *accessor) GetBulks(ids []string) ([]database.CategoryModel, error) {
var categories []database.CategoryModel
if err := a.DB.Find(&categories, "id IN ?", ids).Error; err != nil {
return nil, err
}
return categories, nil
}
@@ -0,0 +1,19 @@
package categoryrepository
import (
categorydomain "legalgo-BE-go/internal/domain/category"
)
func (a *accessor) GetIDByCode(codes []string) ([]string, error) {
var categories []string
if err := a.db.
Model(&categorydomain.Category{}).
Select("id").Where("code IN ?", codes).
Pluck("id", &categories).
Error; err != nil {
return nil, err
}
return categories, nil
}
@@ -7,7 +7,7 @@ import (
func (a *accessor) GetByIDs(ids []string) ([]categorydomain.Category, error) {
var categories []categorydomain.Category
if err := a.DB.Find(&categories, "id IN ?", ids).Error; err != nil {
if err := a.db.Find(&categories, "id IN ?", ids).Error; err != nil {
return nil, err
}
+6 -8
View File
@@ -6,18 +6,16 @@ import (
)
type accessor struct {
DB *database.DB
db *database.DB
}
type Category interface {
Create(categorydomain.CategoryReq) error
CreateModel(categorydomain.CategoryReq) error
GetAll() ([]categorydomain.Category, error)
GetAllModel() ([]database.CategoryModel, error)
GetAllModel() ([]categorydomain.Category, error)
GetByIDs([]string) ([]categorydomain.Category, error)
GetBulks([]string) ([]database.CategoryModel, error)
GetIDByCode([]string) ([]string, error)
CreateModel(categorydomain.CategoryReq) error
Update(categorydomain.Category) error
Delete(string) error
}
func New(
+19
View File
@@ -0,0 +1,19 @@
package categoryrepository
import (
"fmt"
categorydomain "legalgo-BE-go/internal/domain/category"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec categorydomain.Category) error {
if err := a.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{"name", "code", "sequence", "description", "updated_at"}),
}).Select("name", "code", "sequence", "description", "updated_at").Save(&spec).Error; err != nil {
return fmt.Errorf("failed to update category: %v", err)
}
return nil
}
+4 -2
View File
@@ -1,15 +1,16 @@
package repository
import (
adsrepository "legalgo-BE-go/internal/accessor/ads"
categoryrepository "legalgo-BE-go/internal/accessor/category"
newsrepository "legalgo-BE-go/internal/accessor/news"
"legalgo-BE-go/internal/accessor/oss"
redisaccessor "legalgo-BE-go/internal/accessor/redis"
staffrepository "legalgo-BE-go/internal/accessor/staff"
subscriberepository "legalgo-BE-go/internal/accessor/subscribe"
subscribeplanrepository "legalgo-BE-go/internal/accessor/subscribeplan"
subscribeplanrepository "legalgo-BE-go/internal/accessor/subscribe_plan"
tagrepository "legalgo-BE-go/internal/accessor/tag"
userrepository "legalgo-BE-go/internal/accessor/user_repository"
userrepository "legalgo-BE-go/internal/accessor/user"
"go.uber.org/fx"
)
@@ -24,4 +25,5 @@ var Module = fx.Module("repository", fx.Provide(
categoryrepository.New,
newsrepository.New,
oss.New,
adsrepository.New,
))
+1 -1
View File
@@ -5,7 +5,7 @@ import (
newsdomain "legalgo-BE-go/internal/domain/news"
)
func (a *accessor) Create(spec *newsdomain.News) error {
func (a *accessor) Create(spec newsdomain.News) error {
if err := a.db.Create(&spec).Error; err != nil {
return fmt.Errorf("failed to create news: %w", err)
}
-13
View File
@@ -1,13 +0,0 @@
package newsrepository
import (
"fmt"
"legalgo-BE-go/database"
)
func (a *accessor) CreateModel(spec database.NewsModel) error {
if err := a.db.Create(&spec).Error; err != nil {
return fmt.Errorf("failed to create news: %w", err)
}
return nil
}
+28
View File
@@ -0,0 +1,28 @@
package newsrepository
import (
"fmt"
newsdomain "legalgo-BE-go/internal/domain/news"
)
func (a *accessor) Delete(id string) error {
var news newsdomain.News
if err := a.db.Preload("Categories").Preload("Tags").First(&news, "id = ?", id).Error; err != nil {
return fmt.Errorf("failed to find news: %v", err)
}
if err := a.db.Model(&news).Association("Categories").Clear(); err != nil {
return fmt.Errorf("failed to remove categories association: %v", err)
}
if err := a.db.Model(&news).Association("Tags").Clear(); err != nil {
return fmt.Errorf("failed to remove tags association: %v", err)
}
if err := a.db.Delete(&news, "id = ?", id).Error; err != nil {
return fmt.Errorf("failed to delete news %s : %v", id, err)
}
return nil
}
+17 -2
View File
@@ -2,10 +2,25 @@ package newsrepository
import newsdomain "legalgo-BE-go/internal/domain/news"
func (a *accessor) GetAll() ([]newsdomain.News, error) {
func (a *accessor) GetAll(filter newsdomain.NewsFilter) ([]newsdomain.News, error) {
var news []newsdomain.News
query := a.db.
Preload("Tags").
Preload("Categories").
Preload("Author")
if err := a.db.Preload("Tags").Preload("Categories").Find(&news).Error; err != nil {
if len(filter.Category) > 0 {
query = query.Joins("JOIN news_categories nc ON nc.news_id = news.id").
Where("nc.category_id IN (?)", filter.Category)
}
if len(filter.Tags) > 0 {
query = query.Joins("JOIN news_tags nt ON nt.news_id = news.id").
Where("nt.tag_id IN (?)", filter.Tags)
}
if err := query.
Find(&news).Error; err != nil {
return nil, err
}
-13
View File
@@ -1,13 +0,0 @@
package newsrepository
import "legalgo-BE-go/database"
func (a *accessor) GetAllModel() ([]database.NewsModel, error) {
var news []database.NewsModel
if err := a.db.Preload("Tags").Preload("Categories").Find(&news).Error; err != nil {
return nil, err
}
return news, nil
}
+17
View File
@@ -0,0 +1,17 @@
package newsrepository
import newsdomain "legalgo-BE-go/internal/domain/news"
func (a *accessor) GetBySlug(slug string) (*newsdomain.News, error) {
var news newsdomain.News
if err := a.db.
Preload("Tags").
Preload("Categories").
Preload("Author").
First(&news, "slug = ?", slug).Error; err != nil {
return nil, err
}
return &news, nil
}
+5 -4
View File
@@ -10,10 +10,11 @@ type accessor struct {
}
type News interface {
GetAll() ([]newsdomain.News, error)
GetAllModel() ([]database.NewsModel, error)
Create(*newsdomain.News) error
CreateModel(database.NewsModel) error
GetAll(filter newsdomain.NewsFilter) ([]newsdomain.News, error)
GetBySlug(string) (*newsdomain.News, error)
Create(newsdomain.News) error
Update(newsdomain.News) error
Delete(string) error
}
func New(db *database.DB) News {
+69
View File
@@ -0,0 +1,69 @@
package newsrepository
import (
"fmt"
categorydomain "legalgo-BE-go/internal/domain/category"
newsdomain "legalgo-BE-go/internal/domain/news"
tagdomain "legalgo-BE-go/internal/domain/tag"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec newsdomain.News) error {
tx := a.db.Begin()
if err := tx.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{
"title",
"content",
"featured_image",
"is_premium",
"slug",
"author_id",
"live_at",
"updated_at",
}),
}).Select(
"title",
"content",
"featured_image",
"is_premium",
"slug",
"author_id",
"live_at",
"updated_at",
).Save(&spec).Error; err != nil {
tx.Rollback()
return fmt.Errorf("failed to update news: %v", err)
}
tagsDeleted := make([]tagdomain.Tag, len(spec.Tags))
copy(tagsDeleted, spec.Tags)
if err := tx.Model(&spec).Association("Tags").Clear(); err != nil {
tx.Rollback()
return fmt.Errorf("failed to remove previous tags: %v", err)
}
if err := tx.Model(&spec).Association("Tags").Append(tagsDeleted); err != nil {
tx.Rollback()
return fmt.Errorf("failed to add tags: %v", err)
}
categoriesDeleted := make([]categorydomain.Category, len(spec.Categories))
copy(categoriesDeleted, spec.Categories)
if err := tx.Model(&spec).Association("Categories").Clear(); err != nil {
tx.Rollback()
return fmt.Errorf("failed to remove previous categories: %v", err)
}
if err := tx.Model(&spec).Association("Categories").Append(categoriesDeleted); err != nil {
tx.Rollback()
return fmt.Errorf("failed to add categories: %v", err)
}
if err := tx.Commit().Error; err != nil {
return fmt.Errorf("failed to commit transaction: %v", err)
}
return nil
}
+16
View File
@@ -68,3 +68,19 @@ func (r *OssRepositoryImpl) GetPublicURL(fileName string) string {
}
return fmt.Sprintf("%s:%s%s", r.cfg.GetPublicURL(), r.cfg.GetBucketName(), fileName)
}
func (r *OssRepositoryImpl) DeleteObject(ctx context.Context, fileName string) error {
if fileName == "" {
return fmt.Errorf("file name is not provided")
}
_, err := r.s3.DeleteObject(&s3.DeleteObjectInput{
Key: aws.String(fileName),
})
if err != nil {
return fmt.Errorf("failed to delete object %s from bucket: %v", fileName, err)
}
return nil
}
+1
View File
@@ -7,4 +7,5 @@ import (
type OSSRepository interface {
UploadFile(ctx context.Context, fileName string, fileContent []byte) (fileUrl string, err error)
GetPublicURL(fileName string) string
DeleteObject(ctx context.Context, fileName string) error
}
+5 -11
View File
@@ -2,7 +2,7 @@ package redisaccessor
import (
"fmt"
"os"
"legalgo-BE-go/config"
"github.com/redis/go-redis/v9"
)
@@ -13,19 +13,13 @@ func Get() *redis.Client {
return redisClient
}
func New() *redis.Client {
var (
username = os.Getenv("REDIS_USERNAME")
addr = fmt.Sprintf("%s:%s", os.Getenv("REDIS_HOST"), os.Getenv("REDIS_PORT"))
password = os.Getenv("REDIS_PASSWORD")
db = 2 // TODO: change later
)
func New(cfg *config.Config) *redis.Client {
addr := fmt.Sprintf("%s:%s", cfg.Redis.Host, cfg.Redis.Port)
redisClient = redis.NewClient(&redis.Options{
Username: username,
Addr: addr,
Password: password,
DB: db,
Password: cfg.Redis.Password,
DB: cfg.Redis.DB,
})
return redisClient
+7 -5
View File
@@ -1,11 +1,13 @@
package staffrepository
import authdomain "legalgo-BE-go/internal/domain/auth"
import (
staffdomain "legalgo-BE-go/internal/domain/staff"
)
func (ur *StaffRepository) Create(spec *authdomain.Staff) (*authdomain.Staff, error) {
if err := ur.DB.Create(&spec).Error; err != nil {
return nil, err
func (ur *accessor) Create(spec staffdomain.Staff) error {
if err := ur.db.Create(&spec).Error; err != nil {
return err
}
return spec, nil
return nil
}
+4 -4
View File
@@ -3,19 +3,19 @@ package staffrepository
import (
"errors"
authdomain "legalgo-BE-go/internal/domain/auth"
staffdomain "legalgo-BE-go/internal/domain/staff"
"gorm.io/gorm"
)
func (sr *StaffRepository) GetStaffByEmail(email string) (*authdomain.Staff, error) {
var staff authdomain.Staff
func (sr *accessor) GetStaffByEmail(email string) (*staffdomain.Staff, error) {
var staff staffdomain.Staff
if email == "" {
return nil, errors.New("email is required")
}
if err := sr.DB.First(&staff, "email = ?", email).Error; err != nil {
if err := sr.db.First(&staff, "email = ?", email).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("staff not found")
}
+4 -4
View File
@@ -2,19 +2,19 @@ package staffrepository
import (
"errors"
authdomain "legalgo-BE-go/internal/domain/auth"
staffdomain "legalgo-BE-go/internal/domain/staff"
"gorm.io/gorm"
)
func (sr *StaffRepository) GetStaffByID(ID string) (*authdomain.Staff, error) {
var staff authdomain.Staff
func (sr *accessor) GetStaffByID(ID string) (*staffdomain.Staff, error) {
var staff staffdomain.Staff
if ID == "" {
return nil, errors.New("id is required")
}
if err := sr.DB.First(&staff, "id = ? ", ID).Error; err != nil {
if err := sr.db.First(&staff, "id = ? ", ID).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("staff not found")
}
+27
View File
@@ -0,0 +1,27 @@
package staffrepository
import userdomain "legalgo-BE-go/internal/domain/user"
func (a *accessor) GetUsers() ([]userdomain.UserProfile, error) {
var usersRaw []userdomain.User
if err := a.db.
Preload("Subscribe").
Preload("Subscribe.SubscribePlan").
Find(&usersRaw).
Error; err != nil {
return nil, err
}
users := []userdomain.UserProfile{}
for _, user := range usersRaw {
users = append(users, userdomain.UserProfile{
ID: user.ID,
Email: user.Email,
Phone: user.Phone,
Subscribe: user.Subscribe,
})
}
return users, nil
}
+12 -10
View File
@@ -2,20 +2,22 @@ package staffrepository
import (
"legalgo-BE-go/database"
authdomain "legalgo-BE-go/internal/domain/auth"
staffdomain "legalgo-BE-go/internal/domain/staff"
userdomain "legalgo-BE-go/internal/domain/user"
)
type StaffRepository struct {
DB *database.DB
type accessor struct {
db *database.DB
}
type StaffIntf interface {
GetStaffByEmail(string) (*authdomain.Staff, error)
GetStaffByID(string) (*authdomain.Staff, error)
Create(*authdomain.Staff) (*authdomain.Staff, error)
Update(authdomain.Staff) error
type Staff interface {
GetStaffByEmail(string) (*staffdomain.Staff, error)
GetStaffByID(string) (*staffdomain.Staff, error)
GetUsers() ([]userdomain.UserProfile, error)
Create(staffdomain.Staff) error
Update(staffdomain.Staff) error
}
func New(db *database.DB) StaffIntf {
return &StaffRepository{db}
func New(db *database.DB) Staff {
return &accessor{db}
}
+3 -3
View File
@@ -1,17 +1,17 @@
package staffrepository
import (
authdomain "legalgo-BE-go/internal/domain/auth"
staffdomain "legalgo-BE-go/internal/domain/staff"
"legalgo-BE-go/internal/utilities/utils"
)
func (ur *StaffRepository) Update(spec authdomain.Staff) error {
func (ur *accessor) Update(spec staffdomain.Staff) error {
val, err := utils.StructToMap(spec)
if err != nil {
return err
}
if err := ur.DB.Model(&authdomain.Staff{}).Where("id = ?", spec.ID).Updates(val).Error; err != nil {
if err := ur.db.Model(&staffdomain.Staff{}).Where("id = ?", spec.ID).Updates(val).Error; err != nil {
return err
}
+2 -2
View File
@@ -6,13 +6,13 @@ import (
"github.com/google/uuid"
)
func (s *SubsAccs) Create(subsPlanId string) (string, error) {
func (s *accessor) Create(subsPlanId string) (string, error) {
spec := &subscribedomain.Subscribe{
ID: uuid.NewString(),
SubscribePlanID: subsPlanId,
}
if err := s.DB.Create(&spec).Error; err != nil {
if err := s.db.Create(&spec).Error; err != nil {
return "", err
}
+23
View File
@@ -0,0 +1,23 @@
package subscriberepository
import (
"errors"
"fmt"
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
"gorm.io/gorm"
)
func (s *accessor) GetByID(id string) (subscribedomain.Subscribe, error) {
var subscribe subscribedomain.Subscribe
if err := s.db.First(&subscribe, "id = ?", id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return subscribe, fmt.Errorf("subscribe data not found: %v", err)
}
return subscribe, err
}
return subscribe, nil
}
+11 -6
View File
@@ -1,15 +1,20 @@
package subscriberepository
import "legalgo-BE-go/database"
import (
"legalgo-BE-go/database"
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
)
type SubsAccs struct {
DB *database.DB
type accessor struct {
db *database.DB
}
type SubsIntf interface {
type Subscribe interface {
Create(string) (string, error)
GetByID(string) (subscribedomain.Subscribe, error)
Update(subscribedomain.Subscribe) error
}
func New(db *database.DB) SubsIntf {
return &SubsAccs{db}
func New(db *database.DB) Subscribe {
return &accessor{db}
}
+19
View File
@@ -0,0 +1,19 @@
package subscriberepository
import (
"fmt"
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec subscribedomain.Subscribe) error {
if err := a.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{"status", "subscribe_plan_id", "start_date"}),
}).Create(&spec).Error; err != nil {
return fmt.Errorf("failed to update status: %v", err)
}
return nil
}
@@ -0,0 +1,13 @@
package subscribeplanrepository
import (
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
)
func (s *accessor) Create(spec subscribeplandomain.SubscribePlan) error {
if err := s.db.Create(&spec).Error; err != nil {
return err
}
return nil
}
@@ -0,0 +1,30 @@
package subscribeplanrepository
import (
"fmt"
"legalgo-BE-go/database"
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
)
func (a *accessor) Delete(id string) error {
var subsPlan database.SubscribePlan
var basicPlan subscribeplandomain.SubscribePlan
if err := a.db.First(&basicPlan, "code = ?", "basic").Error; err != nil {
return fmt.Errorf("failed to find basic plan: %v", err)
}
if err := a.db.
Model(&subscribedomain.Subscribe{}).
Where("subscribe_plan_id = ?", id).
Update("subscribe_plan_id", basicPlan.ID); err != nil {
return fmt.Errorf("failed to change subscribe plan: %v", err)
}
if err := a.db.Where("id = ?", id).Delete(&subsPlan).Error; err != nil {
return fmt.Errorf("failed to delete subscribe plan %s : %v", id, err)
}
return nil
}
@@ -4,10 +4,10 @@ import (
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
)
func (s *SubsPlan) GetAll() ([]subscribeplandomain.SubscribePlan, error) {
func (s *accessor) GetAll() ([]subscribeplandomain.SubscribePlan, error) {
var subscribePlans []subscribeplandomain.SubscribePlan
if err := s.DB.Find(&subscribePlans).Error; err != nil {
if err := s.db.Find(&subscribePlans).Error; err != nil {
return nil, err
}
@@ -7,10 +7,10 @@ import (
"gorm.io/gorm"
)
func (s *SubsPlan) GetByID(id string) (subscribeplandomain.SubscribePlan, error) {
var subscribePlan subscribeplandomain.SubscribePlan
func (s *accessor) GetByID(id string) (*subscribeplandomain.SubscribePlan, error) {
var subscribePlan *subscribeplandomain.SubscribePlan
if err := s.DB.First(&subscribePlan, "id = ? ", id).Error; err != nil {
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")
}
@@ -0,0 +1,22 @@
package subscribeplanrepository
import (
"legalgo-BE-go/database"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
"github.com/google/uuid"
)
func (s *accessor) GetDefault() (*subscribeplandomain.SubscribePlan, error) {
var subscribePlan *subscribeplandomain.SubscribePlan
if err := s.db.First(&subscribePlan, "code = ?", "basic").Error; err != nil {
s.db.Create(&database.SubscribePlan{
ID: uuid.NewString(),
Code: "basic",
Name: "Basic",
})
}
return subscribePlan, nil
}
+25
View File
@@ -0,0 +1,25 @@
package subscribeplanrepository
import (
"legalgo-BE-go/database"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
)
type accessor struct {
db *database.DB
}
type SubscribePlan interface {
Create(subscribeplandomain.SubscribePlan) error
GetAll() ([]subscribeplandomain.SubscribePlan, error)
GetByID(string) (*subscribeplandomain.SubscribePlan, error)
GetDefault() (*subscribeplandomain.SubscribePlan, error)
Update(subscribeplandomain.SubscribePlan) error
Delete(string) error
}
func New(
db *database.DB,
) SubscribePlan {
return &accessor{db}
}
@@ -0,0 +1,23 @@
package subscribeplanrepository
import (
"fmt"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec subscribeplandomain.SubscribePlan) error {
if err := a.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{
"name",
"code",
"updated_at",
}),
}).Select("name", "code", "updated_at").Save(&spec).Error; err != nil {
return fmt.Errorf("failed to update tag: %v", err)
}
return nil
}
-21
View File
@@ -1,21 +0,0 @@
package subscribeplanrepository
import (
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
"github.com/google/uuid"
)
func (s *SubsPlan) Create(spec subscribeplandomain.SubscribePlanReq) error {
data := &subscribeplandomain.SubscribePlan{
ID: uuid.NewString(),
Code: spec.Code,
Name: spec.Name,
}
if err := s.DB.Create(&data).Error; err != nil {
return err
}
return nil
}
@@ -1,21 +0,0 @@
package subscribeplanrepository
import (
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
"github.com/google/uuid"
)
func (s *SubsPlan) GetDefault() (subscribeplandomain.SubscribePlan, error) {
var subscribePlan subscribeplandomain.SubscribePlan
if err := s.DB.First(&subscribePlan, "code = ?", "basic").Error; err != nil {
s.DB.Create(&subscribeplandomain.SubscribePlan{
ID: uuid.NewString(),
Code: "basic",
Name: "Basic",
})
}
return subscribePlan, nil
}
-23
View File
@@ -1,23 +0,0 @@
package subscribeplanrepository
import (
"legalgo-BE-go/database"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
)
type SubsPlan struct {
DB *database.DB
}
type SubsPlanIntf interface {
Create(subscribeplandomain.SubscribePlanReq) error
GetAll() ([]subscribeplandomain.SubscribePlan, error)
GetByID(string) (subscribeplandomain.SubscribePlan, error)
GetDefault() (subscribeplandomain.SubscribePlan, error)
}
func New(
db *database.DB,
) SubsPlanIntf {
return &SubsPlan{db}
}
+1 -1
View File
@@ -13,7 +13,7 @@ func (acc *accessor) Create(spec tagdomain.TagReq) error {
Name: spec.Name,
}
if err := acc.DB.Create(&data).Error; err != nil {
if err := acc.db.Create(&data).Error; err != nil {
return err
}
-22
View File
@@ -1,22 +0,0 @@
package tagrepository
import (
"legalgo-BE-go/database"
tagdomain "legalgo-BE-go/internal/domain/tag"
"github.com/google/uuid"
)
func (acc *accessor) CreateModel(spec tagdomain.TagReq) error {
data := &database.TagModel{
ID: uuid.NewString(),
Code: spec.Code,
Name: spec.Name,
}
if err := acc.DB.Create(&data).Error; err != nil {
return err
}
return nil
}
+24
View File
@@ -0,0 +1,24 @@
package tagrepository
import (
"fmt"
"legalgo-BE-go/database"
)
func (a *accessor) Delete(id string) error {
var tag database.Tag
if err := a.db.First(&tag, "id = ?", id).Error; err != nil {
return fmt.Errorf("failed to find tag: %v", err)
}
if err := a.db.Model(&tag).Association("News").Clear(); err != nil {
return fmt.Errorf("failed to remove tag association: %v", err)
}
if err := a.db.Delete(&tag).Error; err != nil {
return fmt.Errorf("failed to delete tag %s : %v", id, err)
}
return nil
}
+1 -1
View File
@@ -7,7 +7,7 @@ import (
func (acc *accessor) GetAll() ([]tagdomain.Tag, error) {
var tags []tagdomain.Tag
if err := acc.DB.Find(&tags).Error; err != nil {
if err := acc.db.Find(&tags).Error; err != nil {
return nil, err
}
-13
View File
@@ -1,13 +0,0 @@
package tagrepository
import "legalgo-BE-go/database"
func (acc *accessor) GetAllModel() ([]database.TagModel, error) {
var tags []database.TagModel
if err := acc.DB.Find(&tags).Error; err != nil {
return nil, err
}
return tags, nil
}
-13
View File
@@ -1,13 +0,0 @@
package tagrepository
import "legalgo-BE-go/database"
func (a *accessor) GetBulks(ids []string) ([]database.TagModel, error) {
var tags []database.TagModel
if err := a.DB.Find(&tags, "id IN ?", ids).Error; err != nil {
return nil, err
}
return tags, nil
}
+17
View File
@@ -0,0 +1,17 @@
package tagrepository
import tagdomain "legalgo-BE-go/internal/domain/tag"
func (a *accessor) GetIDsByCodes(codes []string) ([]string, error) {
var tags []string
if err := a.db.
Model(&tagdomain.Tag{}).
Select("id").Where("code IN ?", codes).
Pluck("id", &tags).
Error; err != nil {
return nil, err
}
return tags, nil
}
@@ -5,7 +5,7 @@ import tagdomain "legalgo-BE-go/internal/domain/tag"
func (a *accessor) GetByIDs(ids []string) ([]tagdomain.Tag, error) {
var tags []tagdomain.Tag
if err := a.DB.Find(&tags, "id IN ?", ids).Error; err != nil {
if err := a.db.Find(&tags, "id IN ?", ids).Error; err != nil {
return nil, err
}
+4 -4
View File
@@ -6,16 +6,16 @@ import (
)
type accessor struct {
DB *database.DB
db *database.DB
}
type TagAccessor interface {
Create(tagdomain.TagReq) error
CreateModel(tagdomain.TagReq) error
GetAll() ([]tagdomain.Tag, error)
GetAllModel() ([]database.TagModel, error)
GetByIDs([]string) ([]tagdomain.Tag, error)
GetBulks(ids []string) ([]database.TagModel, error)
GetIDsByCodes([]string) ([]string, error)
Update(tagdomain.Tag) error
Delete(string) error
}
func New(
+23
View File
@@ -0,0 +1,23 @@
package tagrepository
import (
"fmt"
tagdomain "legalgo-BE-go/internal/domain/tag"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec tagdomain.Tag) error {
if err := a.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{
"name",
"code",
"updated_at",
}),
}).Select("name", "code", "updated_at").Save(&spec).Error; err != nil {
return fmt.Errorf("failed to update tag: %v", err)
}
return nil
}
+13
View File
@@ -0,0 +1,13 @@
package userrepository
import (
userdomain "legalgo-BE-go/internal/domain/user"
)
func (ur *accessor) CreateUser(spec userdomain.User) error {
if err := ur.db.Create(&spec).Error; err != nil {
return err
}
return nil
}
@@ -2,25 +2,24 @@ package userrepository
import (
"errors"
authdomain "legalgo-BE-go/internal/domain/auth"
userdomain "legalgo-BE-go/internal/domain/user"
"gorm.io/gorm"
)
func (ur *UserRepository) GetUserByEmail(email string) (*authdomain.User, error) {
var user authdomain.User
func (ur *accessor) GetUserByEmail(email string) (*userdomain.User, error) {
var user *userdomain.User
if email == "" {
return nil, errors.New("email is empty")
}
if err := ur.DB.First(&user, "email = ?", email).Error; err != nil {
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, err
}
return &user, nil
return user, nil
}
+24
View File
@@ -0,0 +1,24 @@
package userrepository
import (
"errors"
userdomain "legalgo-BE-go/internal/domain/user"
)
func (ur *accessor) GetUserByID(id string) (*userdomain.User, error) {
var user userdomain.User
if id == "" {
return nil, errors.New("id is empty")
}
if err := ur.db.
Preload("Subscribe").
Preload("Subscribe.SubscribePlan").
First(&user, "id = ?", id).Error; err != nil {
return nil, err
}
return &user, nil
}
@@ -0,0 +1,31 @@
package userrepository
import (
"errors"
userdomain "legalgo-BE-go/internal/domain/user"
)
func (ur *accessor) GetUserProfile(email string) (*userdomain.UserProfile, error) {
var user *userdomain.User
if email == "" {
return nil, errors.New("email is empty")
}
if err := ur.db.
Preload("Subscribe").
Preload("Subscribe.SubscribePlan").
First(&user, "email = ?", email).
Error; err != nil {
return nil, err
}
userProfile := &userdomain.UserProfile{
ID: user.ID,
Email: user.Email,
Phone: user.Phone,
Subscribe: user.Subscribe,
}
return userProfile, nil
}
+23
View File
@@ -0,0 +1,23 @@
package userrepository
import (
"legalgo-BE-go/database"
userdomain "legalgo-BE-go/internal/domain/user"
)
type accessor struct {
db *database.DB
}
type User interface {
GetUserByEmail(string) (*userdomain.User, error)
GetUserByID(string) (*userdomain.User, error)
GetUserProfile(string) (*userdomain.UserProfile, error)
CreateUser(userdomain.User) error
}
func New(
db *database.DB,
) User {
return &accessor{db}
}
@@ -1,13 +0,0 @@
package userrepository
import (
authdomain "legalgo-BE-go/internal/domain/auth"
)
func (ur *UserRepository) CreateUser(spec *authdomain.User) (*authdomain.User, error) {
if err := ur.DB.Create(&spec).Error; err != nil {
return nil, err
}
return spec, nil
}
@@ -1,30 +0,0 @@
package userrepository
import (
"errors"
authdomain "legalgo-BE-go/internal/domain/auth"
"gorm.io/gorm"
)
func (ur *UserRepository) GetUserByID(email string) (*authdomain.UserProfile, error) {
var users []authdomain.UserProfile
if email == "" {
return nil, errors.New("email is empty")
}
if err := ur.DB.Table("users u").
Select("u.email, u.id, s.status as subscribe_status, sp.code as subscribe_plan_code, sp.name as subscribe_plan_name").
Joins("join subscribes s on s.id = u.subscribe_id").
Joins("join subscribe_plans sp on s.subscribe_plan_id = sp.id").
Scan(&users).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("user not found")
}
return nil, err
}
return &users[0], nil
}
@@ -1,30 +0,0 @@
package userrepository
import (
"errors"
authdomain "legalgo-BE-go/internal/domain/auth"
"gorm.io/gorm"
)
func (ur *UserRepository) GetUserProfile(email string) (*authdomain.UserProfile, error) {
var users []authdomain.UserProfile
if email == "" {
return nil, errors.New("email is empty")
}
if err := ur.DB.Table("users u").
Where("email = ?", email).
Select("u.email, u.id, s.status as subscribe_status, sp.code as subscribe_plan_code, sp.name as subscribe_plan_name").
Joins("join subscribes s on s.id = u.subscribe_id").
Joins("join subscribe_plans sp on s.subscribe_plan_id = sp.id").
Scan(&users).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("user not found")
}
return nil, err
}
return &users[0], nil
}
-23
View File
@@ -1,23 +0,0 @@
package userrepository
import (
"legalgo-BE-go/database"
authdomain "legalgo-BE-go/internal/domain/auth"
)
type UserRepository struct {
DB *database.DB
}
type UserIntf interface {
GetUserByEmail(string) (*authdomain.User, error)
GetUserByID(string) (*authdomain.UserProfile, error)
GetUserProfile(string) (*authdomain.UserProfile, error)
CreateUser(*authdomain.User) (*authdomain.User, error)
}
func New(
db *database.DB,
) UserIntf {
return &UserRepository{db}
}
+106
View File
@@ -0,0 +1,106 @@
package adshttp
import (
"fmt"
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
adsdomain "legalgo-BE-go/internal/domain/ads"
"legalgo-BE-go/internal/domain/oss"
adssvc "legalgo-BE-go/internal/services/ads"
"legalgo-BE-go/internal/utilities/response"
"net/http"
"github.com/go-chi/chi/v5"
)
const _oneMB = 1 << 20
const _maxUploadSize = 2 * _oneMB
const _folderName = "/file"
func Create(
router chi.Router,
adsSvc adssvc.Ads,
) {
router.With(authmiddleware.Authorize()).Post("/ads/create", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
err := r.ParseMultipartForm(10 << 20) // 10 MB
if err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"unable to parse form",
)
return
}
url := r.FormValue("url")
if url == "" {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"URL is missing",
)
return
}
file, header, err := r.FormFile("image")
if err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"unable to retrieve image",
)
return
}
defer file.Close()
if header.Size > int64(_maxUploadSize) {
response.ResponseWithErrorCode(
ctx,
w,
fmt.Errorf("file too big"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
fmt.Sprintf("The file is too big. The maximum size is %d MB", _maxUploadSize/_oneMB),
)
return
}
imageRequest := &oss.UploadFileRequest{
FileHeader: header,
FolderName: _folderName,
}
adsReq := adsdomain.AdsReq{
Image: imageRequest,
Url: url,
}
if err := adsSvc.Create(ctx, adsReq); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, struct {
Message string
}{
Message: "ads created successfully",
})
})
}
+32
View File
@@ -0,0 +1,32 @@
package adshttp
import (
adssvc "legalgo-BE-go/internal/services/ads"
"legalgo-BE-go/internal/utilities/response"
"net/http"
"github.com/go-chi/chi/v5"
)
func GetAll(
router chi.Router,
adsSvc adssvc.Ads,
) {
router.Get("/ads", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
subsPlan, err := adsSvc.GetAll()
if err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, subsPlan)
})
}
+8
View File
@@ -0,0 +1,8 @@
package adshttp
import "go.uber.org/fx"
var Module = fx.Module("ads-http", fx.Invoke(
Create,
GetAll,
))
-15
View File
@@ -1,15 +0,0 @@
package authhttp
import "go.uber.org/fx"
var Module = fx.Module("auth-api",
fx.Invoke(
LoginStaff,
LoginUser,
RegisterUser,
RegisterStaff,
UpdateStaff,
GetStaffProfile,
GetUserProfile,
),
)
+4 -1
View File
@@ -1,6 +1,7 @@
package categoryhttp
import (
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
categorydomain "legalgo-BE-go/internal/domain/category"
categorysvc "legalgo-BE-go/internal/services/category"
"legalgo-BE-go/internal/utilities/response"
@@ -16,7 +17,9 @@ func Create(
validate *validator.Validate,
categorySvc categorysvc.Category,
) {
router.Post("/category/create", func(w http.ResponseWriter, r *http.Request) {
router.
With(authmiddleware.Authorize()).
Post("/category/create", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var spec categorydomain.CategoryReq
+53
View File
@@ -0,0 +1,53 @@
package categoryhttp
import (
"fmt"
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
categorysvc "legalgo-BE-go/internal/services/category"
"legalgo-BE-go/internal/utilities/response"
"net/http"
"github.com/go-chi/chi/v5"
)
func Delete(
router chi.Router,
categorySvc categorysvc.Category,
) {
router.
With(authmiddleware.Authorize()).
Delete("/category/{category_id}/delete", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
categoryID := chi.URLParam(r, "category_id")
if categoryID == "" {
response.RespondJsonErrorWithCode(
ctx,
w,
fmt.Errorf("category id is not provided"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"category id is not provided",
)
return
}
if err := categorySvc.Delete(categoryID); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, struct {
Message string
}{
Message: "category has been deleted",
})
})
}
+1 -2
View File
@@ -14,8 +14,7 @@ func GetAll(
) {
router.Get("/category", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
subsPlan, err := categorySvc.GetAllModel()
// subsPlan, err := categorySvc.GetAll()
subsPlan, err := categorySvc.GetAll()
if err != nil {
response.ResponseWithErrorCode(
ctx,
+2
View File
@@ -5,4 +5,6 @@ import "go.uber.org/fx"
var Module = fx.Module("categories", fx.Invoke(
Create,
GetAll,
Update,
Delete,
))
+82
View File
@@ -0,0 +1,82 @@
package categoryhttp
import (
"fmt"
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
categorydomain "legalgo-BE-go/internal/domain/category"
categorysvc "legalgo-BE-go/internal/services/category"
"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,
categorySvc categorysvc.Category,
) {
router.
With(authmiddleware.Authorize()).
Put("/category/{category_id}/update", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
categoryID := chi.URLParam(r, "category_id")
if categoryID == "" {
response.RespondJsonErrorWithCode(
ctx,
w,
fmt.Errorf("category id is not provided"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"category id is not provided",
)
return
}
var spec categorydomain.CategoryReq
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 := categorySvc.Update(categoryID, 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 category success",
})
})
}
-5
View File
@@ -1,5 +0,0 @@
package contenthttp
import "go.uber.org/fx"
var Module = fx.Module("content-api", fx.Invoke())
+57 -119
View File
@@ -1,138 +1,76 @@
package authmiddleware
// import (
// "context"
// "fmt"
// "net/http"
// "strings"
import (
"context"
"fmt"
"net/http"
"time"
// redisaccessor "legalgo-BE-go/internal/accessor/redis"
// contextkeyenum "legalgo-BE-go/internal/enums/context_key"
// jwtclaimenum "legalgo-BE-go/internal/enums/jwt"
// resourceenum "legalgo-BE-go/internal/enums/resource"
// "legalgo-BE-go/internal/services/auth"
// "github.com/golang-jwt/jwt/v5"
// )
redisaccessor "legalgo-BE-go/internal/accessor/redis"
"legalgo-BE-go/internal/utilities/response"
"legalgo-BE-go/internal/utilities/utils"
// const SessionHeader = "Authorization"
"github.com/golang-jwt/jwt/v5"
)
// func Authorization() func(next http.Handler) http.Handler {
// return func(next http.Handler) http.Handler {
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// ctx := r.Context()
const SessionHeader = "Authorization"
// tokenString, err := GetToken(r)
// if err != nil {
// RespondWithError(w, r, err, "Invalid auth header")
// return
// }
func Authorize() func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// token, err := ValidateToken(ctx, tokenString)
// if err != nil {
// RespondWithError(w, r, err, err.Error())
// return
// }
tokenString, err := utils.GetToken(r)
if err != nil {
response.RespondWithError(w, r, err, "Invalid auth header")
return
}
// if isAuthorized, ctx := VerifyClaims(ctx, token, nil); !isAuthorized {
// RespondWithError(w, r, errorcode.ErrCodeUnauthorized, errorcode.ErrCodeUnauthorized.Message)
// return
// } else {
// next.ServeHTTP(w, r.WithContext(ctx))
// return
// }
// })
// }
// }
spec, err := utils.GetTokenDetail(r)
// func GetToken(r *http.Request) (string, error) {
// tokenString := GetTokenFromHeader(r)
// if tokenString == "" {
// tokenString = getTokenFromQuery(r)
// }
token, err := ValidateToken(ctx, spec.Email)
if err != nil {
response.RespondWithError(w, r, err, err.Error())
return
}
// if tokenString == "" {
// return "", fmt.Errorf("token not found")
// }
isValid := token == tokenString
// return tokenString, nil
// }
if !isValid {
response.RespondWithError(w, r, err, "invalid token")
return
}
// func GetTokenFromHeader(r *http.Request) string {
// session := r.Header.Get(SessionHeader)
// arr := strings.Split(session, " ")
next.ServeHTTP(w, r.WithContext(ctx))
})
}
}
// if len(arr) != 2 || strings.ToUpper(arr[0]) != "BEARER" {
// return ""
// }
func ValidateToken(ctx context.Context, id string) (string, error) {
redisClient := redisaccessor.Get()
redisToken, err := utils.GetTokenRedis(ctx, redisClient, id)
// return arr[1]
// }
if err != nil {
return "", err
}
// func getTokenFromQuery(r *http.Request) string {
// token := r.URL.Query().Get("token")
// return token
// }
token, err := utils.ParseToken(redisToken)
// func VerifyClaims(ctx context.Context, token *jwt.Token,
// requiredResources []resourceenum.Resource) (bool, context.Context) {
// if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
// rawResources := []interface{}{}
// if claimValue, exist := claims[string(jwtclaimenum.RESOURCES)]; exist {
// rawResources = claimValue.([]interface{})
// }
if err != nil {
return "", fmt.Errorf("invalid token: %w", err)
}
// resources := []resourceenum.Resource{}
// resourceMap := map[string]bool{}
// Check if the token is valid
if !token.Valid {
return "", fmt.Errorf("invalid token: token is not valid")
}
// for _, v := range rawResources {
// value := v.(string)
// resources = append(resources, resourceenum.Resource(value))
// resourceMap[value] = true
// }
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
expirationTime := claims["exp"].(float64) // Expiration time in Unix timestamp format
if time.Unix(int64(expirationTime), 0).Before(time.Now()) {
return "", fmt.Errorf("token has expired")
}
}
// ctx = context.WithValue(ctx, contextkeyenum.Authorization, UserAuthorization{
// Type: claims[string(jwtclaimenum.TYPE)].(string),
// UserId: claims[string(jwtclaimenum.AUDIENCE)].(string),
// Username: claims[string(jwtclaimenum.USERNAME)].(string),
// Resources: resources,
// })
// isResourceFulfilled := false
// for _, v := range requiredResources {
// if _, ok := resourceMap[string(v)]; ok {
// isResourceFulfilled = true
// ctx = context.WithValue(ctx, contextkeyenum.Resource, v)
// break
// }
// }
// if isResourceFulfilled || len(requiredResources) == 0 {
// return true, ctx
// }
// }
// return false, nil
// }
// func ValidateToken(ctx context.Context, tokenString string) (*jwt.Token, error) {
// redisClient := redisaccessor.Get()
// redisToken, err := redisClient.Exists(ctx, fmt.Sprintf("%s:%s", auth.BLACKLISTED_TOKEN_KEY, tokenString)).Result()
// if err != nil || redisToken > 0 {
// return nil, fmt.Errorf("session already expired")
// }
// token, err := jwt.Parse(tokenString, authsvc.VerifyToken(conf.JWTAccessToken))
// if err != nil {
// if ve, ok := err.(*jwt.ValidationError); ok {
// if ve.Errors&jwt.ValidationErrorExpired != 0 {
// err = errorcode.ErrCodeExpiredToken
// }
// }
// return nil, err
// }
// return token, nil
// }
return redisToken, nil
}
+2 -2
View File
@@ -15,7 +15,7 @@ import (
func Create(
validate *validator.Validate,
newsSvc newssvc.News,
staffRepo staffrepository.StaffIntf,
staffRepo staffrepository.Staff,
router chi.Router,
) {
router.Post("/news/create", func(w http.ResponseWriter, r *http.Request) {
@@ -72,7 +72,7 @@ func Create(
return
}
if err := newsSvc.CreateModel(spec, staffProfile.ID); err != nil {
if err := newsSvc.Create(spec, staffProfile.ID); err != nil {
response.ResponseWithErrorCode(
ctx,
w,
+53
View File
@@ -0,0 +1,53 @@
package newshttp
import (
"fmt"
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
newssvc "legalgo-BE-go/internal/services/news"
"legalgo-BE-go/internal/utilities/response"
"net/http"
"github.com/go-chi/chi/v5"
)
func Delete(
router chi.Router,
newsSvc newssvc.News,
) {
router.
With(authmiddleware.Authorize()).
Delete("/news/{news_id}/delete", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
newsID := chi.URLParam(r, "news_id")
if newsID == "" {
response.RespondJsonErrorWithCode(
ctx,
w,
fmt.Errorf("category id is not provided"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"news id is not provided",
)
return
}
if err := newsSvc.Delete(newsID); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, struct {
Message string
}{
Message: "news has been deleted",
})
})
}
+12 -1
View File
@@ -1,6 +1,7 @@
package newshttp
import (
newsdomain "legalgo-BE-go/internal/domain/news"
newssvc "legalgo-BE-go/internal/services/news"
"legalgo-BE-go/internal/utilities/response"
"net/http"
@@ -13,8 +14,18 @@ func GetAll(
newsSvc newssvc.News,
) {
router.Get("/news", func(w http.ResponseWriter, r *http.Request) {
var (
news []newsdomain.News
err error
)
ctx := r.Context()
news, err := newsSvc.GetAllModel()
query := r.URL.Query()
category := query.Get("categories")
tags := query.Get("tags")
news, err = newsSvc.GetAll(category, tags)
if err != nil {
response.ResponseWithErrorCode(
ctx,
+34
View File
@@ -0,0 +1,34 @@
package newshttp
import (
newssvc "legalgo-BE-go/internal/services/news"
"legalgo-BE-go/internal/utilities/response"
"net/http"
"github.com/go-chi/chi/v5"
)
func GetBySlug(
router chi.Router,
newsSvc newssvc.News,
) {
router.Get("/news/{slug}", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
slug := chi.URLParam(r, "slug")
news, err := newsSvc.GetBySlug(slug)
if err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, news)
})
}
+3
View File
@@ -4,5 +4,8 @@ import "go.uber.org/fx"
var Module = fx.Module("news", fx.Invoke(
GetAll,
GetBySlug,
Create,
Update,
Delete,
))
+97
View File
@@ -0,0 +1,97 @@
package newshttp
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"
"legalgo-BE-go/internal/utilities/response"
"legalgo-BE-go/internal/utilities/utils"
"net/http"
"github.com/go-chi/chi/v5"
)
func Update(
router chi.Router,
newsSvc newssvc.News,
authSvc authsvc.Auth,
) {
router.With(authmiddleware.Authorize()).
Put("/news/{news_id}/update", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
newsID := chi.URLParam(r, "news_id")
if newsID == "" {
response.ResponseWithErrorCode(
ctx,
w,
fmt.Errorf("news id is not provided"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"news id is not provided",
)
return
}
destructedToken, err := utils.GetTokenDetail(r)
if err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
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(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
spec.ID = newsID
if err := newsSvc.Update(staff.ID, spec); err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, struct {
Message string
}{
Message: "news updated successfully.",
})
})
}
+8 -2
View File
@@ -1,12 +1,15 @@
package internalhttp
import (
authhttp "legalgo-BE-go/internal/api/http/auth"
adshttp "legalgo-BE-go/internal/api/http/ads"
categoryhttp "legalgo-BE-go/internal/api/http/category"
newshttp "legalgo-BE-go/internal/api/http/news"
osshttp "legalgo-BE-go/internal/api/http/oss"
staffhttp "legalgo-BE-go/internal/api/http/staffhttp"
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"
userhttp "legalgo-BE-go/internal/api/http/user"
"github.com/go-chi/chi/v5"
"github.com/go-chi/cors"
@@ -21,12 +24,15 @@ var Module = fx.Module("router",
initRouter,
validator.New,
),
authhttp.Module,
staffhttp.Module,
subscribeplanhttp.Module,
taghttp.Module,
categoryhttp.Module,
newshttp.Module,
osshttp.Module,
userhttp.Module,
subscribehttp.Module,
adshttp.Module,
)
func initRouter() chi.Router {

Some files were not shown because too many files have changed in this diff Show More