Compare commits
6 Commits
c29df8a3d6
...
915f12eaf7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
915f12eaf7 | ||
|
|
f4ae93bc48 | ||
|
|
eb1584f8c4 | ||
|
|
bdf6dd131e | ||
|
|
acd80480dd | ||
|
|
613379c8a5 |
22
.vscode/launch.json
vendored
Normal file
22
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch Package",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "debug",
|
||||||
|
"program": "${workspaceFolder}/cmd/legalgo/",
|
||||||
|
"dlvLoadConfig":{
|
||||||
|
"followPointers": true,
|
||||||
|
"maxVariableRecurse": 1,
|
||||||
|
"maxStringLen": 512, // ĺ—符串最大长度
|
||||||
|
"maxArrayValues": 64,
|
||||||
|
"maxStructFields": -1
|
||||||
|
},
|
||||||
|
"dlvFlags": ["--check-go-version=false"],
|
||||||
|
"env": {
|
||||||
|
"TZ": ""
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
@ -29,6 +29,8 @@ func main() {
|
|||||||
log.Fatalf("failed to connect to database: %v", err)
|
log.Fatalf("failed to connect to database: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// db.DropTables()
|
||||||
|
|
||||||
if err := db.Migrate(); err != nil {
|
if err := db.Migrate(); err != nil {
|
||||||
log.Fatal("Migration failed: ", err)
|
log.Fatal("Migration failed: ", err)
|
||||||
}
|
}
|
||||||
|
|||||||
21
database/category_model.go
Normal file
21
database/category_model.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Category struct {
|
||||||
|
ID string `gorm:"primaryKey" json:"id"`
|
||||||
|
Code string `gorm:"not null;unique" json:"code"`
|
||||||
|
Name string `gorm:"not null" json:"name"`
|
||||||
|
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_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"`
|
||||||
|
}
|
||||||
@ -36,6 +36,18 @@ func NewDB() (*DB, error) {
|
|||||||
return &DB{db}, nil
|
return &DB{db}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) DropTables() error {
|
||||||
|
// Auto Migrate the User model
|
||||||
|
return db.Migrator().DropTable(
|
||||||
|
// &Staff{},
|
||||||
|
// &SubscribePlan{},
|
||||||
|
// &Subscribe{},
|
||||||
|
// &User{},
|
||||||
|
&Tag{},
|
||||||
|
&Category{},
|
||||||
|
&News{},
|
||||||
|
)
|
||||||
|
}
|
||||||
func (db *DB) Migrate() error {
|
func (db *DB) Migrate() error {
|
||||||
// Auto Migrate the User model
|
// Auto Migrate the User model
|
||||||
return db.AutoMigrate(
|
return db.AutoMigrate(
|
||||||
@ -43,5 +55,11 @@ func (db *DB) Migrate() error {
|
|||||||
&SubscribePlan{},
|
&SubscribePlan{},
|
||||||
&Subscribe{},
|
&Subscribe{},
|
||||||
&User{},
|
&User{},
|
||||||
|
// &Tag{},
|
||||||
|
// &Category{},
|
||||||
|
// &News{},
|
||||||
|
&NewsModel{},
|
||||||
|
&TagModel{},
|
||||||
|
&CategoryModel{},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,13 +5,31 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type News struct {
|
type News struct {
|
||||||
ID string `gorm:"primaryKey" json:"id"`
|
ID string `gorm:"primaryKey" json:"id"`
|
||||||
AuthorID string `gorm:"not null" json:"author_id"`
|
Title string `gorm:"default:null" json:"title"`
|
||||||
Title string `gorm:"default:null" json:"title"`
|
Tags []Tag `gorm:"many2many:news_tags" json:"tags"`
|
||||||
Content string `gorm:"default:null" json:"content"`
|
Categories []Category `gorm:"many2many:news_categories" json:"categories"`
|
||||||
IsPremium bool `gorm:"default:false" json:"is_premium"`
|
Content string `gorm:"default:null" json:"content"`
|
||||||
Slug string `gorm:"default:null" json:"slug"`
|
LiveAt time.Time `gorm:"not null" json:"live_at"`
|
||||||
FeaturedImage string `gorm:"default:null" json:"featured_image"`
|
AuthorID string `gorm:"not null" json:"author_id"`
|
||||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
IsPremium bool `gorm:"default:false" json:"is_premium"`
|
||||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
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"`
|
||||||
|
IsPremium bool `gorm:"default:false" json:"is_premium"`
|
||||||
|
Slug string `gorm:"default:null" json:"slug"`
|
||||||
|
FeaturedImage string `gorm:"default:null" json:"featured_image"`
|
||||||
|
AuthorID string `gorm:"not null" json:"author_id"`
|
||||||
|
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"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
type Staff struct {
|
type Staff struct {
|
||||||
ID string `gorm:"primaryKey" json:"id"`
|
ID string `gorm:"primaryKey" json:"id"`
|
||||||
Username string `gorm:"default:null" json:"username"`
|
Username string `gorm:"default:null;unique" json:"username"`
|
||||||
Email string `gorm:"unique,not null" json:"email"`
|
Email string `gorm:"unique;not null" json:"email"`
|
||||||
Password string `gorm:"not null" json:"password"`
|
Password string `gorm:"not null" json:"password"`
|
||||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||||
|
|||||||
@ -19,7 +19,7 @@ type Subscribe struct {
|
|||||||
|
|
||||||
type SubscribePlan struct {
|
type SubscribePlan struct {
|
||||||
ID string `gorm:"primaryKey" json:"id"`
|
ID string `gorm:"primaryKey" json:"id"`
|
||||||
Code string `gorm:"not null" json:"code"`
|
Code string `gorm:"not null;unique" json:"code"`
|
||||||
Name string `gorm:"not null" json:"name"`
|
Name string `gorm:"not null" json:"name"`
|
||||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
||||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
||||||
|
|||||||
21
database/tag_module.go
Normal file
21
database/tag_module.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Tag struct {
|
||||||
|
ID string `gorm:"primaryKey" json:"id"`
|
||||||
|
Code string `gorm:"not null;unique" json:"code"`
|
||||||
|
Name string `gorm:"not null" json:"name"`
|
||||||
|
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_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"`
|
||||||
|
}
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Tags struct {
|
|
||||||
ID string `gorm:"primaryKey;not null" json:"id"`
|
|
||||||
Code string `gorm:"not null" json:"code"`
|
|
||||||
Name string `gorm:"not null" json:"name"`
|
|
||||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
|
||||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
|
||||||
}
|
|
||||||
@ -5,11 +5,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID string `gorm:"primaryKey" json:"id"`
|
ID string `gorm:"primaryKey;not null" json:"id"`
|
||||||
SubscribeID string `gorm:"not null" json:"subscribe_id"`
|
SubscribeID string `gorm:"not null" json:"subscribe_id"`
|
||||||
Email string `gorm:"unique,not null" json:"email"`
|
Email string `gorm:"unique;not null" json:"email"`
|
||||||
Password string `gorm:"not null" json:"password"`
|
Password string `gorm:"not null" json:"password"`
|
||||||
Phone string `gorm:"default:null" json:"phone"`
|
Phone string `gorm:"default:not null;unique" json:"phone"`
|
||||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||||
|
|
||||||
|
|||||||
21
internal/accessor/category/create.go
Normal file
21
internal/accessor/category/create.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package categoryrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *accessor) Create(spec categorydomain.CategoryReq) error {
|
||||||
|
data := categorydomain.Category{
|
||||||
|
ID: uuid.NewString(),
|
||||||
|
Name: spec.Name,
|
||||||
|
Code: spec.Code,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := a.DB.Create(&data).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
22
internal/accessor/category/create_model.go
Normal file
22
internal/accessor/category/create_model.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
13
internal/accessor/category/get_all.go
Normal file
13
internal/accessor/category/get_all.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package categoryrepository
|
||||||
|
|
||||||
|
import categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
|
|
||||||
|
func (a *accessor) GetAll() ([]categorydomain.Category, error) {
|
||||||
|
var categories []categorydomain.Category
|
||||||
|
|
||||||
|
if err := a.DB.Find(&categories).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return categories, nil
|
||||||
|
}
|
||||||
15
internal/accessor/category/get_all_model.go
Normal file
15
internal/accessor/category/get_all_model.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
15
internal/accessor/category/get_bulk.go
Normal file
15
internal/accessor/category/get_bulk.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package categoryrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
|
)
|
||||||
|
|
||||||
|
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 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return categories, nil
|
||||||
|
}
|
||||||
15
internal/accessor/category/get_bulk_model.go
Normal file
15
internal/accessor/category/get_bulk_model.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
27
internal/accessor/category/impl.go
Normal file
27
internal/accessor/category/impl.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package categoryrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
|
)
|
||||||
|
|
||||||
|
type accessor struct {
|
||||||
|
DB *database.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
type Category interface {
|
||||||
|
Create(categorydomain.CategoryReq) error
|
||||||
|
CreateModel(categorydomain.CategoryReq) error
|
||||||
|
|
||||||
|
GetAll() ([]categorydomain.Category, error)
|
||||||
|
GetAllModel() ([]database.CategoryModel, error)
|
||||||
|
|
||||||
|
GetByIDs([]string) ([]categorydomain.Category, error)
|
||||||
|
GetBulks([]string) ([]database.CategoryModel, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(
|
||||||
|
db *database.DB,
|
||||||
|
) Category {
|
||||||
|
return &accessor{db}
|
||||||
|
}
|
||||||
@ -1,10 +1,13 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
categoryrepository "legalgo-BE-go/internal/accessor/category"
|
||||||
|
newsrepository "legalgo-BE-go/internal/accessor/news"
|
||||||
redisaccessor "legalgo-BE-go/internal/accessor/redis"
|
redisaccessor "legalgo-BE-go/internal/accessor/redis"
|
||||||
staffrepository "legalgo-BE-go/internal/accessor/staff"
|
staffrepository "legalgo-BE-go/internal/accessor/staff"
|
||||||
subscriberepository "legalgo-BE-go/internal/accessor/subscribe"
|
subscriberepository "legalgo-BE-go/internal/accessor/subscribe"
|
||||||
subscribeplanrepository "legalgo-BE-go/internal/accessor/subscribeplan"
|
subscribeplanrepository "legalgo-BE-go/internal/accessor/subscribeplan"
|
||||||
|
tagrepository "legalgo-BE-go/internal/accessor/tag"
|
||||||
userrepository "legalgo-BE-go/internal/accessor/user_repository"
|
userrepository "legalgo-BE-go/internal/accessor/user_repository"
|
||||||
|
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
@ -16,4 +19,7 @@ var Module = fx.Module("repository", fx.Provide(
|
|||||||
redisaccessor.New,
|
redisaccessor.New,
|
||||||
subscribeplanrepository.New,
|
subscribeplanrepository.New,
|
||||||
subscriberepository.New,
|
subscriberepository.New,
|
||||||
|
tagrepository.New,
|
||||||
|
categoryrepository.New,
|
||||||
|
newsrepository.New,
|
||||||
))
|
))
|
||||||
|
|||||||
13
internal/accessor/news/create.go
Normal file
13
internal/accessor/news/create.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package newsrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
13
internal/accessor/news/create_model.go
Normal file
13
internal/accessor/news/create_model.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
13
internal/accessor/news/get_all.go
Normal file
13
internal/accessor/news/get_all.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package newsrepository
|
||||||
|
|
||||||
|
import newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
|
||||||
|
func (a *accessor) GetAll() ([]newsdomain.News, error) {
|
||||||
|
var news []newsdomain.News
|
||||||
|
|
||||||
|
if err := a.db.Preload("Tags").Preload("Categories").Find(&news).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return news, nil
|
||||||
|
}
|
||||||
13
internal/accessor/news/get_all_model.go
Normal file
13
internal/accessor/news/get_all_model.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
21
internal/accessor/news/impl.go
Normal file
21
internal/accessor/news/impl.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package newsrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
)
|
||||||
|
|
||||||
|
type accessor struct {
|
||||||
|
db *database.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
type News interface {
|
||||||
|
GetAll() ([]newsdomain.News, error)
|
||||||
|
GetAllModel() ([]database.NewsModel, error)
|
||||||
|
Create(*newsdomain.News) error
|
||||||
|
CreateModel(database.NewsModel) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(db *database.DB) News {
|
||||||
|
return &accessor{db}
|
||||||
|
}
|
||||||
@ -15,7 +15,7 @@ func (sr *StaffRepository) GetStaffByEmail(email string) (*authdomain.Staff, err
|
|||||||
return nil, errors.New("email is required")
|
return nil, errors.New("email is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sr.DB.Where("email = ?", email).First(&staff).Error; err != nil {
|
if err := sr.DB.First(&staff, "email = ?", email).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, errors.New("staff not found")
|
return nil, errors.New("staff not found")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ func (sr *StaffRepository) GetStaffByID(ID string) (*authdomain.Staff, error) {
|
|||||||
return nil, errors.New("id is required")
|
return nil, errors.New("id is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sr.DB.Where("id = ? ", ID).First(&staff).Error; err != nil {
|
if err := sr.DB.First(&staff, "id = ? ", ID).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, errors.New("staff not found")
|
return nil, errors.New("staff not found")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import (
|
|||||||
func (s *SubsPlan) GetDefault() (subscribeplandomain.SubscribePlan, error) {
|
func (s *SubsPlan) GetDefault() (subscribeplandomain.SubscribePlan, error) {
|
||||||
var subscribePlan subscribeplandomain.SubscribePlan
|
var subscribePlan subscribeplandomain.SubscribePlan
|
||||||
|
|
||||||
if err := s.DB.Where("code = ?", "basic").First(&subscribePlan).Error; err != nil {
|
if err := s.DB.First(&subscribePlan, "code = ?", "basic").Error; err != nil {
|
||||||
s.DB.Create(&subscribeplandomain.SubscribePlan{
|
s.DB.Create(&subscribeplandomain.SubscribePlan{
|
||||||
ID: uuid.NewString(),
|
ID: uuid.NewString(),
|
||||||
Code: "basic",
|
Code: "basic",
|
||||||
|
|||||||
21
internal/accessor/tag/create.go
Normal file
21
internal/accessor/tag/create.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package tagrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (acc *accessor) Create(spec tagdomain.TagReq) error {
|
||||||
|
data := &tagdomain.Tag{
|
||||||
|
ID: uuid.NewString(),
|
||||||
|
Code: spec.Code,
|
||||||
|
Name: spec.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := acc.DB.Create(&data).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
22
internal/accessor/tag/create_model.go
Normal file
22
internal/accessor/tag/create_model.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
15
internal/accessor/tag/get_all.go
Normal file
15
internal/accessor/tag/get_all.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package tagrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (acc *accessor) GetAll() ([]tagdomain.Tag, error) {
|
||||||
|
var tags []tagdomain.Tag
|
||||||
|
|
||||||
|
if err := acc.DB.Find(&tags).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags, nil
|
||||||
|
}
|
||||||
13
internal/accessor/tag/get_all_model.go
Normal file
13
internal/accessor/tag/get_all_model.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
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
internal/accessor/tag/get_bulk.go
Normal file
13
internal/accessor/tag/get_bulk.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package tagrepository
|
||||||
|
|
||||||
|
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 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags, nil
|
||||||
|
}
|
||||||
13
internal/accessor/tag/get_bulk_model.go
Normal file
13
internal/accessor/tag/get_bulk_model.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
25
internal/accessor/tag/impl.go
Normal file
25
internal/accessor/tag/impl.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package tagrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||||
|
)
|
||||||
|
|
||||||
|
type accessor struct {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(
|
||||||
|
db *database.DB,
|
||||||
|
) TagAccessor {
|
||||||
|
return &accessor{db}
|
||||||
|
}
|
||||||
@ -15,7 +15,7 @@ func (ur *UserRepository) GetUserByEmail(email string) (*authdomain.User, error)
|
|||||||
return nil, errors.New("email is empty")
|
return nil, errors.New("email is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ur.DB.Where("email = ?", email).First(&user).Error; err != nil {
|
if err := ur.DB.Find(&user, "email = ?", email).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, errors.New("user not found")
|
return nil, errors.New("user not found")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ func (ur *UserRepository) GetUserProfile(email string) (*authdomain.UserProfile,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := ur.DB.Table("users u").
|
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").
|
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 subscribes s on s.id = u.subscribe_id").
|
||||||
Joins("join subscribe_plans sp on s.subscribe_plan_id = sp.id").
|
Joins("join subscribe_plans sp on s.subscribe_plan_id = sp.id").
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
package authhttp
|
package authhttp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
authsvc "legalgo-BE-go/internal/services/auth"
|
authsvc "legalgo-BE-go/internal/services/auth"
|
||||||
"legalgo-BE-go/internal/utilities/response"
|
"legalgo-BE-go/internal/utilities/response"
|
||||||
"legalgo-BE-go/internal/utilities/utils"
|
"legalgo-BE-go/internal/utilities/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
)
|
)
|
||||||
@ -17,46 +15,7 @@ func GetStaffProfile(
|
|||||||
) {
|
) {
|
||||||
router.Get("/staff/profile", func(w http.ResponseWriter, r *http.Request) {
|
router.Get("/staff/profile", func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
authHeader := r.Header.Get("Authorization")
|
destructedToken, err := utils.GetTokenDetail(r)
|
||||||
|
|
||||||
if authHeader == "" {
|
|
||||||
response.ResponseWithErrorCode(
|
|
||||||
ctx,
|
|
||||||
w,
|
|
||||||
errors.New("provided auth is empty"),
|
|
||||||
response.ErrBadRequest.Code,
|
|
||||||
response.ErrBadRequest.HttpCode,
|
|
||||||
"required params is not provided",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.HasPrefix(authHeader, "Bearer") {
|
|
||||||
response.ResponseWithErrorCode(
|
|
||||||
ctx,
|
|
||||||
w,
|
|
||||||
errors.New("invalid authorization token"),
|
|
||||||
response.ErrBadRequest.Code,
|
|
||||||
response.ErrBadRequest.HttpCode,
|
|
||||||
"invalid required token",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
token := strings.Split(authHeader, " ")
|
|
||||||
if len(token) < 2 {
|
|
||||||
response.ResponseWithErrorCode(
|
|
||||||
ctx,
|
|
||||||
w,
|
|
||||||
errors.New("invalid authorization"),
|
|
||||||
response.ErrBadRequest.Code,
|
|
||||||
response.ErrBadRequest.HttpCode,
|
|
||||||
"invalid required token",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
destructedToken, err := utils.DestructToken(token[1])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.ResponseWithErrorCode(
|
response.ResponseWithErrorCode(
|
||||||
ctx,
|
ctx,
|
||||||
@ -92,46 +51,7 @@ func GetUserProfile(
|
|||||||
) {
|
) {
|
||||||
router.Get("/user/profile", func(w http.ResponseWriter, r *http.Request) {
|
router.Get("/user/profile", func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
authHeader := r.Header.Get("Authorization")
|
destructedToken, err := utils.GetTokenDetail(r)
|
||||||
|
|
||||||
if authHeader == "" {
|
|
||||||
response.ResponseWithErrorCode(
|
|
||||||
ctx,
|
|
||||||
w,
|
|
||||||
errors.New("provided auth is empty"),
|
|
||||||
response.ErrBadRequest.Code,
|
|
||||||
response.ErrBadRequest.HttpCode,
|
|
||||||
"required params is not provided",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.HasPrefix(authHeader, "Bearer") {
|
|
||||||
response.ResponseWithErrorCode(
|
|
||||||
ctx,
|
|
||||||
w,
|
|
||||||
errors.New("invalid authorization token"),
|
|
||||||
response.ErrBadRequest.Code,
|
|
||||||
response.ErrBadRequest.HttpCode,
|
|
||||||
"invalid required token",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
token := strings.Split(authHeader, " ")
|
|
||||||
if len(token) < 2 {
|
|
||||||
response.ResponseWithErrorCode(
|
|
||||||
ctx,
|
|
||||||
w,
|
|
||||||
errors.New("invalid authorization"),
|
|
||||||
response.ErrBadRequest.Code,
|
|
||||||
response.ErrBadRequest.HttpCode,
|
|
||||||
"invalid required token",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
destructedToken, err := utils.DestructToken(token[1])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.ResponseWithErrorCode(
|
response.ResponseWithErrorCode(
|
||||||
ctx,
|
ctx,
|
||||||
|
|||||||
67
internal/api/http/category/create.go
Normal file
67
internal/api/http/category/create.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package categoryhttp
|
||||||
|
|
||||||
|
import (
|
||||||
|
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 Create(
|
||||||
|
router chi.Router,
|
||||||
|
validate *validator.Validate,
|
||||||
|
categorySvc categorysvc.Category,
|
||||||
|
) {
|
||||||
|
router.Post("/category/create", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
|
var spec categorydomain.CategoryReq
|
||||||
|
|
||||||
|
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrBadRequest.Code,
|
||||||
|
response.ErrBadRequest.HttpCode,
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.Struct(spec); err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrBadRequest.Code,
|
||||||
|
response.ErrBadRequest.HttpCode,
|
||||||
|
err.(validator.ValidationErrors).Error(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := categorySvc.Create(spec); err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrCreateEntity.Code,
|
||||||
|
response.ErrCreateEntity.HttpCode,
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response.RespondJsonSuccess(ctx, w, struct {
|
||||||
|
Message string
|
||||||
|
}{
|
||||||
|
Message: "category created successfully",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
33
internal/api/http/category/get_all.go
Normal file
33
internal/api/http/category/get_all.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package categoryhttp
|
||||||
|
|
||||||
|
import (
|
||||||
|
categorysvc "legalgo-BE-go/internal/services/category"
|
||||||
|
"legalgo-BE-go/internal/utilities/response"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetAll(
|
||||||
|
router chi.Router,
|
||||||
|
categorySvc categorysvc.Category,
|
||||||
|
) {
|
||||||
|
router.Get("/category", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
subsPlan, err := categorySvc.GetAllModel()
|
||||||
|
// subsPlan, err := categorySvc.GetAll()
|
||||||
|
if err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrBadRequest.Code,
|
||||||
|
response.ErrBadRequest.HttpCode,
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response.RespondJsonSuccess(ctx, w, subsPlan)
|
||||||
|
})
|
||||||
|
}
|
||||||
8
internal/api/http/category/module.go
Normal file
8
internal/api/http/category/module.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package categoryhttp
|
||||||
|
|
||||||
|
import "go.uber.org/fx"
|
||||||
|
|
||||||
|
var Module = fx.Module("categories", fx.Invoke(
|
||||||
|
Create,
|
||||||
|
GetAll,
|
||||||
|
))
|
||||||
93
internal/api/http/news/create.go
Normal file
93
internal/api/http/news/create.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package newshttp
|
||||||
|
|
||||||
|
import (
|
||||||
|
staffrepository "legalgo-BE-go/internal/accessor/staff"
|
||||||
|
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
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"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Create(
|
||||||
|
validate *validator.Validate,
|
||||||
|
newsSvc newssvc.News,
|
||||||
|
staffRepo staffrepository.StaffIntf,
|
||||||
|
router chi.Router,
|
||||||
|
) {
|
||||||
|
router.Post("/news/create", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
var spec newsdomain.NewsReq
|
||||||
|
|
||||||
|
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrBadRequest.Code,
|
||||||
|
response.ErrBadRequest.HttpCode,
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.Struct(spec); err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrBadRequest.Code,
|
||||||
|
response.ErrBadRequest.HttpCode,
|
||||||
|
err.(validator.ValidationErrors).Error(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
destructedToken, err := utils.GetTokenDetail(r)
|
||||||
|
if err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrBadRequest.Code,
|
||||||
|
response.ErrBadRequest.HttpCode,
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
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.CreateModel(spec, staffProfile.ID); 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 created successfully.",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
32
internal/api/http/news/get_all.go
Normal file
32
internal/api/http/news/get_all.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
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 GetAll(
|
||||||
|
router chi.Router,
|
||||||
|
newsSvc newssvc.News,
|
||||||
|
) {
|
||||||
|
router.Get("/news", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
news, err := newsSvc.GetAllModel()
|
||||||
|
if err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrBadRequest.Code,
|
||||||
|
response.ErrBadRequest.HttpCode,
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response.RespondJsonSuccess(ctx, w, news)
|
||||||
|
})
|
||||||
|
}
|
||||||
8
internal/api/http/news/module.go
Normal file
8
internal/api/http/news/module.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package newshttp
|
||||||
|
|
||||||
|
import "go.uber.org/fx"
|
||||||
|
|
||||||
|
var Module = fx.Module("news", fx.Invoke(
|
||||||
|
GetAll,
|
||||||
|
Create,
|
||||||
|
))
|
||||||
@ -2,7 +2,10 @@ package internalhttp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
authhttp "legalgo-BE-go/internal/api/http/auth"
|
authhttp "legalgo-BE-go/internal/api/http/auth"
|
||||||
|
categoryhttp "legalgo-BE-go/internal/api/http/category"
|
||||||
|
newshttp "legalgo-BE-go/internal/api/http/news"
|
||||||
subscribeplanhttp "legalgo-BE-go/internal/api/http/subscribe_plan"
|
subscribeplanhttp "legalgo-BE-go/internal/api/http/subscribe_plan"
|
||||||
|
taghttp "legalgo-BE-go/internal/api/http/tag"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/cors"
|
"github.com/go-chi/cors"
|
||||||
@ -19,6 +22,9 @@ var Module = fx.Module("router",
|
|||||||
),
|
),
|
||||||
authhttp.Module,
|
authhttp.Module,
|
||||||
subscribeplanhttp.Module,
|
subscribeplanhttp.Module,
|
||||||
|
taghttp.Module,
|
||||||
|
categoryhttp.Module,
|
||||||
|
newshttp.Module,
|
||||||
)
|
)
|
||||||
|
|
||||||
func initRouter() chi.Router {
|
func initRouter() chi.Router {
|
||||||
|
|||||||
67
internal/api/http/tag/create.go
Normal file
67
internal/api/http/tag/create.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package taghttp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||||
|
tagsvc "legalgo-BE-go/internal/services/tag"
|
||||||
|
"legalgo-BE-go/internal/utilities/response"
|
||||||
|
"legalgo-BE-go/internal/utilities/utils"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Create(
|
||||||
|
router chi.Router,
|
||||||
|
validate *validator.Validate,
|
||||||
|
tagSvc tagsvc.TagIntf,
|
||||||
|
) {
|
||||||
|
router.Post("/tag/create", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
|
var spec tagdomain.TagReq
|
||||||
|
|
||||||
|
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrBadRequest.Code,
|
||||||
|
response.ErrBadRequest.HttpCode,
|
||||||
|
"failed to unmarshal request",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.Struct(spec); err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrBadRequest.Code,
|
||||||
|
response.ErrBadRequest.HttpCode,
|
||||||
|
err.(validator.ValidationErrors).Error(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tagSvc.Create(spec); err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrCreateEntity.Code,
|
||||||
|
response.ErrCreateEntity.HttpCode,
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response.RespondJsonSuccess(ctx, w, struct {
|
||||||
|
Message string
|
||||||
|
}{
|
||||||
|
Message: "tag created successfully.",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
33
internal/api/http/tag/get_all.go
Normal file
33
internal/api/http/tag/get_all.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package taghttp
|
||||||
|
|
||||||
|
import (
|
||||||
|
tagsvc "legalgo-BE-go/internal/services/tag"
|
||||||
|
"legalgo-BE-go/internal/utilities/response"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetAll(
|
||||||
|
router chi.Router,
|
||||||
|
tagSvc tagsvc.TagIntf,
|
||||||
|
) {
|
||||||
|
router.Get("/tag", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
tags, err := tagSvc.GetAllModel()
|
||||||
|
// tags, err := tagSvc.GetAll()
|
||||||
|
if err != nil {
|
||||||
|
response.ResponseWithErrorCode(
|
||||||
|
ctx,
|
||||||
|
w,
|
||||||
|
err,
|
||||||
|
response.ErrBadRequest.Code,
|
||||||
|
response.ErrBadRequest.HttpCode,
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response.RespondJsonSuccess(ctx, w, tags)
|
||||||
|
})
|
||||||
|
}
|
||||||
8
internal/api/http/tag/module.go
Normal file
8
internal/api/http/tag/module.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package taghttp
|
||||||
|
|
||||||
|
import "go.uber.org/fx"
|
||||||
|
|
||||||
|
var Module = fx.Module("tag", fx.Invoke(
|
||||||
|
Create,
|
||||||
|
GetAll,
|
||||||
|
))
|
||||||
@ -3,7 +3,7 @@ package authdomain
|
|||||||
type RegisterUserReq struct {
|
type RegisterUserReq struct {
|
||||||
Email string `json:"email" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password" validate:"required"`
|
||||||
Phone string `json:"phone"`
|
Phone string `json:"phone" validate:"required"`
|
||||||
SubscribePlanID string `json:"subscribe_plan_id"`
|
SubscribePlanID string `json:"subscribe_plan_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
internal/domain/category/spec.go
Normal file
12
internal/domain/category/spec.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package categorydomain
|
||||||
|
|
||||||
|
type Category struct {
|
||||||
|
ID string `json:"id" gorm:"primaryKey"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CategoryReq struct {
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Code string `json:"code" validate:"required"`
|
||||||
|
}
|
||||||
@ -1,12 +0,0 @@
|
|||||||
package newsdomain
|
|
||||||
|
|
||||||
type News struct {
|
|
||||||
Title string `json:"title"`
|
|
||||||
Content string `json:"content"`
|
|
||||||
FeaturedImage string `json:"featured_image"`
|
|
||||||
Tags []string `json:"tags"`
|
|
||||||
Categories []string `json:"categories"`
|
|
||||||
IsPremium bool `json:"is_premium"`
|
|
||||||
Slug string `json:"slug"`
|
|
||||||
Author string `json:"author"`
|
|
||||||
}
|
|
||||||
32
internal/domain/news/spec.go
Normal file
32
internal/domain/news/spec.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package newsdomain
|
||||||
|
|
||||||
|
import (
|
||||||
|
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
|
tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NewsReq struct {
|
||||||
|
Title string `json:"title" validate:"required"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
FeaturedImage string `json:"featured_image"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
Categories []string `json:"categories"`
|
||||||
|
IsPremium bool `json:"is_premium"`
|
||||||
|
LiveAt string `json:"live_at" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type News struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
FeaturedImage string `json:"featured_image"`
|
||||||
|
Tags []tagdomain.Tag `json:"tags"`
|
||||||
|
Categories []categorydomain.Category `json:"categories"`
|
||||||
|
IsPremium bool `json:"is_premium"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
AuthorID string `json:"author_id"`
|
||||||
|
LiveAt time.Time `json:"live_at"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
12
internal/domain/tag/spec.go
Normal file
12
internal/domain/tag/spec.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package tagdomain
|
||||||
|
|
||||||
|
type TagReq struct {
|
||||||
|
Code string `json:"code" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Tag struct {
|
||||||
|
ID string `json:"id" gorm:"primaryKey"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
8
internal/services/category/create.go
Normal file
8
internal/services/category/create.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package categorysvc
|
||||||
|
|
||||||
|
import categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
|
|
||||||
|
func (i *impl) Create(spec categorydomain.CategoryReq) error {
|
||||||
|
return i.categoryRepo.CreateModel(spec)
|
||||||
|
// return i.categoryRepo.Create(spec)
|
||||||
|
}
|
||||||
7
internal/services/category/get_all.go
Normal file
7
internal/services/category/get_all.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package categorysvc
|
||||||
|
|
||||||
|
import categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
|
|
||||||
|
func (i *impl) GetAll() ([]categorydomain.Category, error) {
|
||||||
|
return i.categoryRepo.GetAll()
|
||||||
|
}
|
||||||
9
internal/services/category/get_all_model.go
Normal file
9
internal/services/category/get_all_model.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package categorysvc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *impl) GetAllModel() ([]database.CategoryModel, error) {
|
||||||
|
return i.categoryRepo.GetAllModel()
|
||||||
|
}
|
||||||
25
internal/services/category/impl.go
Normal file
25
internal/services/category/impl.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package categorysvc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
categoryrepository "legalgo-BE-go/internal/accessor/category"
|
||||||
|
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
|
)
|
||||||
|
|
||||||
|
type impl struct {
|
||||||
|
categoryRepo categoryrepository.Category
|
||||||
|
}
|
||||||
|
|
||||||
|
type Category interface {
|
||||||
|
Create(categorydomain.CategoryReq) error
|
||||||
|
GetAll() ([]categorydomain.Category, error)
|
||||||
|
GetAllModel() ([]database.CategoryModel, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(
|
||||||
|
categoryRepo categoryrepository.Category,
|
||||||
|
) Category {
|
||||||
|
return &impl{
|
||||||
|
categoryRepo: categoryRepo,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,8 +2,11 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
serviceauth "legalgo-BE-go/internal/services/auth"
|
serviceauth "legalgo-BE-go/internal/services/auth"
|
||||||
|
categorysvc "legalgo-BE-go/internal/services/category"
|
||||||
|
newssvc "legalgo-BE-go/internal/services/news"
|
||||||
subscribesvc "legalgo-BE-go/internal/services/subscribe"
|
subscribesvc "legalgo-BE-go/internal/services/subscribe"
|
||||||
subscribeplansvc "legalgo-BE-go/internal/services/subscribe_plan"
|
subscribeplansvc "legalgo-BE-go/internal/services/subscribe_plan"
|
||||||
|
tagsvc "legalgo-BE-go/internal/services/tag"
|
||||||
|
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
)
|
)
|
||||||
@ -13,5 +16,8 @@ var Module = fx.Module("services",
|
|||||||
serviceauth.New,
|
serviceauth.New,
|
||||||
subscribeplansvc.New,
|
subscribeplansvc.New,
|
||||||
subscribesvc.New,
|
subscribesvc.New,
|
||||||
|
tagsvc.New,
|
||||||
|
categorysvc.New,
|
||||||
|
newssvc.New,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
47
internal/services/news/create.go
Normal file
47
internal/services/news/create.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package newssvc
|
||||||
|
|
||||||
|
import (
|
||||||
|
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *impl) Create(spec newsdomain.NewsReq, staffId string) error {
|
||||||
|
slug := strings.ToLower(strings.ReplaceAll(spec.Title, " ", "-"))
|
||||||
|
|
||||||
|
tags, err := i.tagRepo.GetByIDs(spec.Tags)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
categories, err := i.categoryRepo.GetByIDs(spec.Categories)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedTime, err := time.Parse(time.RFC3339, spec.LiveAt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newSpec := &newsdomain.News{
|
||||||
|
ID: uuid.NewString(),
|
||||||
|
Title: spec.Title,
|
||||||
|
Content: spec.Content,
|
||||||
|
FeaturedImage: spec.FeaturedImage,
|
||||||
|
IsPremium: spec.IsPremium,
|
||||||
|
Slug: slug,
|
||||||
|
LiveAt: parsedTime,
|
||||||
|
AuthorID: staffId,
|
||||||
|
Tags: tags,
|
||||||
|
Categories: categories,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := i.newsRepo.Create(newSpec); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
48
internal/services/news/create_model.go
Normal file
48
internal/services/news/create_model.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package newssvc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *impl) CreateModel(spec newsdomain.NewsReq, staffId string) error {
|
||||||
|
slug := strings.ToLower(strings.ReplaceAll(spec.Title, " ", "-"))
|
||||||
|
|
||||||
|
tags, err := i.tagRepo.GetBulks(spec.Tags)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
categories, err := i.categoryRepo.GetBulks(spec.Categories)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedTime, err := time.Parse(time.RFC3339, spec.LiveAt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newSpec := database.NewsModel{
|
||||||
|
ID: uuid.NewString(),
|
||||||
|
Title: spec.Title,
|
||||||
|
Content: spec.Content,
|
||||||
|
FeaturedImage: spec.FeaturedImage,
|
||||||
|
IsPremium: spec.IsPremium,
|
||||||
|
Slug: slug,
|
||||||
|
LiveAt: parsedTime,
|
||||||
|
AuthorID: staffId,
|
||||||
|
Tags: tags,
|
||||||
|
Categories: categories,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := i.newsRepo.CreateModel(newSpec); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
7
internal/services/news/get_all.go
Normal file
7
internal/services/news/get_all.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package newssvc
|
||||||
|
|
||||||
|
import newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
|
||||||
|
func (i *impl) GetAll() ([]newsdomain.News, error) {
|
||||||
|
return i.newsRepo.GetAll()
|
||||||
|
}
|
||||||
9
internal/services/news/get_all_model.go
Normal file
9
internal/services/news/get_all_model.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package newssvc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *impl) GetAllModel() ([]database.NewsModel, error) {
|
||||||
|
return i.newsRepo.GetAllModel()
|
||||||
|
}
|
||||||
34
internal/services/news/impl.go
Normal file
34
internal/services/news/impl.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package newssvc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
categoryrepository "legalgo-BE-go/internal/accessor/category"
|
||||||
|
newsrepository "legalgo-BE-go/internal/accessor/news"
|
||||||
|
tagrepository "legalgo-BE-go/internal/accessor/tag"
|
||||||
|
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
)
|
||||||
|
|
||||||
|
type impl struct {
|
||||||
|
newsRepo newsrepository.News
|
||||||
|
tagRepo tagrepository.TagAccessor
|
||||||
|
categoryRepo categoryrepository.Category
|
||||||
|
}
|
||||||
|
|
||||||
|
type News interface {
|
||||||
|
GetAll() ([]newsdomain.News, error)
|
||||||
|
GetAllModel() ([]database.NewsModel, error)
|
||||||
|
Create(newsdomain.NewsReq, string) error
|
||||||
|
CreateModel(newsdomain.NewsReq, string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(
|
||||||
|
newsRepo newsrepository.News,
|
||||||
|
tagRepo tagrepository.TagAccessor,
|
||||||
|
categoryRepo categoryrepository.Category,
|
||||||
|
) News {
|
||||||
|
return &impl{
|
||||||
|
newsRepo,
|
||||||
|
tagRepo,
|
||||||
|
categoryRepo,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,10 +5,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *SubsPlanSvc) GetAllPlan() ([]subscribeplandomain.SubscribePlan, error) {
|
func (s *SubsPlanSvc) GetAllPlan() ([]subscribeplandomain.SubscribePlan, error) {
|
||||||
subsPlan, err := s.subsAccs.GetAll()
|
return s.subsAccs.GetAll()
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return subsPlan, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
8
internal/services/tag/create.go
Normal file
8
internal/services/tag/create.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package tagsvc
|
||||||
|
|
||||||
|
import tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||||
|
|
||||||
|
func (i *impl) Create(spec tagdomain.TagReq) error {
|
||||||
|
// return i.tagRepo.Create(spec)
|
||||||
|
return i.tagRepo.CreateModel(spec)
|
||||||
|
}
|
||||||
7
internal/services/tag/get_all.go
Normal file
7
internal/services/tag/get_all.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package tagsvc
|
||||||
|
|
||||||
|
import tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||||
|
|
||||||
|
func (i *impl) GetAll() ([]tagdomain.Tag, error) {
|
||||||
|
return i.tagRepo.GetAll()
|
||||||
|
}
|
||||||
9
internal/services/tag/get_all_model.go
Normal file
9
internal/services/tag/get_all_model.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package tagsvc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *impl) GetAllModel() ([]database.TagModel, error) {
|
||||||
|
return i.tagRepo.GetAllModel()
|
||||||
|
}
|
||||||
23
internal/services/tag/impl.go
Normal file
23
internal/services/tag/impl.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package tagsvc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
tagrepository "legalgo-BE-go/internal/accessor/tag"
|
||||||
|
tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||||
|
)
|
||||||
|
|
||||||
|
type impl struct {
|
||||||
|
tagRepo tagrepository.TagAccessor
|
||||||
|
}
|
||||||
|
|
||||||
|
type TagIntf interface {
|
||||||
|
Create(tagdomain.TagReq) error
|
||||||
|
GetAll() ([]tagdomain.Tag, error)
|
||||||
|
GetAllModel() ([]database.TagModel, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(
|
||||||
|
tagRepo tagrepository.TagAccessor,
|
||||||
|
) TagIntf {
|
||||||
|
return &impl{tagRepo}
|
||||||
|
}
|
||||||
34
internal/utilities/utils/get_token_detail.go
Normal file
34
internal/utilities/utils/get_token_detail.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetTokenDetail(r *http.Request) (authdomain.AuthToken, error) {
|
||||||
|
authHeader := r.Header.Get("Authorization")
|
||||||
|
|
||||||
|
var data authdomain.AuthToken
|
||||||
|
|
||||||
|
if authHeader == "" {
|
||||||
|
return data, errors.New("unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasPrefix(authHeader, "Bearer") {
|
||||||
|
return data, errors.New("invalid token")
|
||||||
|
}
|
||||||
|
|
||||||
|
token := strings.Split(authHeader, " ")
|
||||||
|
if len(token) < 2 {
|
||||||
|
return data, errors.New("invalid token")
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := DestructToken(token[1])
|
||||||
|
if err != nil {
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
9
makefile
9
makefile
@ -17,9 +17,12 @@ build-migrate:
|
|||||||
@echo "Building the Migrate..."
|
@echo "Building the Migrate..."
|
||||||
go build -o $(OUTPUT_MIGRATE_DIR) $(BINARY_MIGRATE_NAME)
|
go build -o $(OUTPUT_MIGRATE_DIR) $(BINARY_MIGRATE_NAME)
|
||||||
|
|
||||||
migrate: build-migrate
|
# migrate: build-migrate
|
||||||
@echo "Building and running Migrate..."
|
# @echo "Building and running Migrate..."
|
||||||
$(OUTPUT_MIGRATE_DIR)
|
# $(OUTPUT_MIGRATE_DIR)
|
||||||
|
|
||||||
|
migrate:
|
||||||
|
go run $(BINARY_MIGRATE_NAME)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@echo "Cleaning the build..."
|
@echo "Cleaning the build..."
|
||||||
|
|||||||
464
openapi.yml
464
openapi.yml
@ -5,6 +5,43 @@ info:
|
|||||||
description: API for handling staff and user login, registration, and subscription plan creation.
|
description: API for handling staff and user login, registration, and subscription plan creation.
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
|
/staff/profile:
|
||||||
|
get:
|
||||||
|
summary: "get staff profile"
|
||||||
|
tags:
|
||||||
|
- Staff
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Success get profile
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
"400":
|
||||||
|
description: Bad request
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
|
||||||
/staff/login:
|
/staff/login:
|
||||||
post:
|
post:
|
||||||
summary: Login for staff
|
summary: Login for staff
|
||||||
@ -120,62 +157,11 @@ paths:
|
|||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
/staff/profile:
|
|
||||||
get:
|
|
||||||
summary: "get staff profile"
|
|
||||||
tags:
|
|
||||||
- Staff
|
|
||||||
parameters:
|
|
||||||
- name: "id"
|
|
||||||
in: query
|
|
||||||
description: "staff id"
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: Success get profile
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
data:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
email:
|
|
||||||
type: string
|
|
||||||
username:
|
|
||||||
type: string
|
|
||||||
"400":
|
|
||||||
description: Bad request
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
error:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
code:
|
|
||||||
type: string
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
/user/profile:
|
/user/profile:
|
||||||
get:
|
get:
|
||||||
summary: "get staff profile"
|
summary: "get staff profile"
|
||||||
tags:
|
tags:
|
||||||
- User
|
- User
|
||||||
parameters:
|
|
||||||
- name: "id"
|
|
||||||
in: query
|
|
||||||
description: "user id"
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: Success get profile
|
description: Success get profile
|
||||||
@ -429,3 +415,379 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
/tag:
|
||||||
|
get:
|
||||||
|
summary: Get all tags
|
||||||
|
tags:
|
||||||
|
- Tags
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successfully retrieved all tags
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
"400":
|
||||||
|
description: Bad request
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
/tag/create:
|
||||||
|
post:
|
||||||
|
summary: Create a new tag
|
||||||
|
tags:
|
||||||
|
- Tags
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- code
|
||||||
|
- name
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Tag created
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
example: "tag created successfully."
|
||||||
|
"400":
|
||||||
|
description: Bad request
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
"409":
|
||||||
|
description: Conflict (tag code already exists)
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
/category:
|
||||||
|
get:
|
||||||
|
summary: Get all categories
|
||||||
|
tags:
|
||||||
|
- Category
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successfully retrieved all categories
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
"400":
|
||||||
|
description: Bad request
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
/category/create:
|
||||||
|
post:
|
||||||
|
summary: Create a new category
|
||||||
|
tags:
|
||||||
|
- Category
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- code
|
||||||
|
- name
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Category created
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
example: "category created successfully."
|
||||||
|
"400":
|
||||||
|
description: Bad request
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
"409":
|
||||||
|
description: Conflict (category code already exists)
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
/news/create:
|
||||||
|
post:
|
||||||
|
summary: Create a new news article
|
||||||
|
tags:
|
||||||
|
- News
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
content:
|
||||||
|
type: string
|
||||||
|
featured_image:
|
||||||
|
type: string
|
||||||
|
format: uri
|
||||||
|
tags:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
categories:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
is_premium:
|
||||||
|
type: boolean
|
||||||
|
live_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
required:
|
||||||
|
- title
|
||||||
|
- content
|
||||||
|
- featured_image
|
||||||
|
- tags
|
||||||
|
- categories
|
||||||
|
- is_premium
|
||||||
|
- live_at
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: News article created
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
example: "news created successfully."
|
||||||
|
"400":
|
||||||
|
description: Bad request
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
"409":
|
||||||
|
description: Conflict (e.g., duplicate title or invalid tag/category)
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
/news:
|
||||||
|
get:
|
||||||
|
summary: Get all news articles
|
||||||
|
tags:
|
||||||
|
- News
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successfully retrieved all news articles
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
content:
|
||||||
|
type: string
|
||||||
|
categories:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
created_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
updated_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
tags:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
created_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
updated_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
is_premium:
|
||||||
|
type: boolean
|
||||||
|
slug:
|
||||||
|
type: string
|
||||||
|
featured_image:
|
||||||
|
type: string
|
||||||
|
format: uri
|
||||||
|
author_id:
|
||||||
|
type: string
|
||||||
|
live_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
created_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
updated_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
"400":
|
||||||
|
description: Bad request
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user