Compare commits
95
Commits
4ec50cee8a
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
211f0154be | ||
|
|
136c4634c8 | ||
|
|
987ac2fe4a | ||
|
|
02d8a509ff | ||
|
|
e29bd7986f | ||
|
|
4bf318a9c2 | ||
|
|
52085a5be0 | ||
|
|
21c4c1efba | ||
|
|
c17540cc20 | ||
|
|
714b1ff4eb | ||
|
|
abc3ce8d2b | ||
|
|
cd1097d3d0 | ||
|
|
52991059c6 | ||
|
|
a7ef3f8ca2 | ||
|
|
6f1ac37915 | ||
|
|
e20c63e694 | ||
|
|
abcbc014a2 | ||
|
|
98b871a5ed | ||
|
|
3311b80943 | ||
|
|
16fef8706a | ||
|
|
4fbfa9c2c9 | ||
|
|
a68780f09e | ||
|
|
49dc0e4a7b | ||
|
|
09d9c4efb8 | ||
|
|
990026cece | ||
|
|
11051ae89c | ||
|
|
24f0fe6efa | ||
|
|
8d7500610e | ||
|
|
0c8133c802 | ||
|
|
d8f6968f64 | ||
|
|
290d7f6701 | ||
|
|
b0099dac1e | ||
|
|
d7fa8496b0 | ||
|
|
efab193793 | ||
|
|
7b529ba46e | ||
|
|
c0dcdb77fa | ||
|
|
ee8e8e140d | ||
|
|
11bc19360c | ||
|
|
1297c71200 | ||
|
|
47085ca0ae | ||
|
|
ce17e9dc73 | ||
|
|
ce341dbc13 | ||
|
|
52dfb7e0f2 | ||
|
|
ef6b17a363 | ||
|
|
1ae192ccef | ||
|
|
213d370332 | ||
|
|
13c976dcbf | ||
|
|
a47b7b7d3d | ||
|
|
c5eb6302ab | ||
|
|
68f33d101b | ||
|
|
479703dfd0 | ||
|
|
dc1a4dafbc | ||
|
|
fdf572cd3d | ||
|
|
c48a4b944b | ||
|
|
c410e651ce | ||
|
|
51b50a3132 | ||
|
|
e3a9b67e28 | ||
|
|
2046021e01 | ||
|
|
a2a6fe6374 | ||
|
|
d6a680634c | ||
|
|
cf410bdf05 | ||
|
|
efc87ee63e | ||
|
|
c037da4879 | ||
|
|
53fda59e3c | ||
|
|
2525eed2ea | ||
|
|
85247643e6 | ||
|
|
d217ec8a62 | ||
|
|
299fcf949b | ||
|
|
5c699dfa53 | ||
|
|
dd109c8aa0 | ||
|
|
567e0e32ca | ||
|
|
2b54a9343b | ||
|
|
30091f3362 | ||
|
|
43d5608a51 | ||
|
|
ed8c523b26 | ||
|
|
883ff8b7d1 | ||
|
|
e9b9a367a9 | ||
|
|
750a4dc3db | ||
|
|
c9f1e33c24 | ||
|
|
13a8481f22 | ||
|
|
642566c8b2 | ||
|
|
afe6f4e9a6 | ||
|
|
20c9660c3a | ||
|
|
c02d8cda69 | ||
|
|
55460653e3 | ||
|
|
915f12eaf7 | ||
|
|
f4ae93bc48 | ||
|
|
eb1584f8c4 | ||
|
|
bdf6dd131e | ||
|
|
acd80480dd | ||
|
|
613379c8a5 | ||
|
|
c29df8a3d6 | ||
|
|
2bef24fbb6 | ||
|
|
c23ee933c1 | ||
|
|
6b858b99fb |
@@ -14,3 +14,4 @@ REDIS_PORT=
|
|||||||
REDIS_PASSWORD=
|
REDIS_PASSWORD=
|
||||||
REDIS_TTL=
|
REDIS_TTL=
|
||||||
REDIS_DB=
|
REDIS_DB=
|
||||||
|
REDIS_TIMEOUT=
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
bin
|
bin
|
||||||
.env
|
.env
|
||||||
|
.DS_Store
|
||||||
|
/cmd/legalgo/env
|
||||||
|
|
||||||
|
__debug*
|
||||||
|
|||||||
Generated
+9
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
Generated
+119
@@ -0,0 +1,119 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AutoImportSettings">
|
||||||
|
<option name="autoReloadType" value="ALL" />
|
||||||
|
</component>
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="e5a7c631-b0eb-4bcf-9341-cd30afbc8d51" name="Changes" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/.idea/legalgo-BE-go.iml" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/config/auth.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/config/configs.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/config/db.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/config/http.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/config/jwt.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/config/module.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/config/oss.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/config/server.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/development.yaml" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/internal/accessor/oss/oss.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/internal/accessor/oss/upload.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/internal/api/http/oss/module.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/internal/api/http/oss/upload.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/internal/domain/oss/oss.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/internal/services/oss/impl.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/internal/services/oss/init.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/k8s/staging/deployment.yaml" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/k8s/staging/ingress.yaml" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/k8s/staging/namespace.yaml" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/k8s/staging/service.yaml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/cmd/gorm/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/cmd/gorm/main.go" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/cmd/legalgo/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/cmd/legalgo/main.go" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/database/new_db.go" beforeDir="false" afterPath="$PROJECT_DIR$/database/new_db.go" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/go.mod" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/go.sum" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/internal/accessor/module.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/accessor/module.go" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/internal/api/http/router.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/api/http/router.go" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/internal/services/module.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/services/module.go" afterDir="false" />
|
||||||
|
</list>
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="FileTemplateManagerImpl">
|
||||||
|
<option name="RECENT_TEMPLATES">
|
||||||
|
<list>
|
||||||
|
<option value="Go File" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="GOROOT" url="file:///opt/homebrew/Cellar/go/1.24.0/libexec" />
|
||||||
|
<component name="Git.Settings">
|
||||||
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="MarkdownSettingsMigration">
|
||||||
|
<option name="stateVersion" value="1" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectId" id="2tlQuDgnVjD2XCHsYVtzhu4hYTb" />
|
||||||
|
<component name="ProjectViewState">
|
||||||
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
|
<option name="showLibraryContents" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
|
"keyToString": {
|
||||||
|
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
|
"DefaultGoTemplateProperty": "Go File",
|
||||||
|
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||||
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
|
"RunOnceActivity.go.formatter.settings.were.checked": "true",
|
||||||
|
"RunOnceActivity.go.migrated.go.modules.settings": "true",
|
||||||
|
"RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
|
||||||
|
"RunOnceActivity.go.vendoring.notification.had.been.shown": "true",
|
||||||
|
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
|
"WebServerToolWindowFactoryState": "false",
|
||||||
|
"configurable..is.expanded": "false",
|
||||||
|
"configurable.GoLibrariesConfigurable.is.expanded": "true",
|
||||||
|
"go.import.settings.migrated": "true",
|
||||||
|
"go.sdk.automatically.set": "true",
|
||||||
|
"last_opened_file_path": "/Users/aditya.siregar/Personal/Altru/legalgo-news/legalgo-BE-go",
|
||||||
|
"node.js.detected.package.eslint": "true",
|
||||||
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
|
"settings.editor.selected.configurable": "go.sdk"
|
||||||
|
}
|
||||||
|
}]]></component>
|
||||||
|
<component name="RecentsManager">
|
||||||
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$" />
|
||||||
|
<recent name="$PROJECT_DIR$/internal/api/http/oss" />
|
||||||
|
<recent name="$PROJECT_DIR$/internal/services" />
|
||||||
|
<recent name="$PROJECT_DIR$/internal/accessor" />
|
||||||
|
<recent name="$PROJECT_DIR$/config" />
|
||||||
|
</key>
|
||||||
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$/internal/api/http/oss" />
|
||||||
|
</key>
|
||||||
|
</component>
|
||||||
|
<component name="RunManager">
|
||||||
|
<configuration name="go build legalgo-BE-go/cmd/legalgo" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
||||||
|
<module name="legalgo-BE-go" />
|
||||||
|
<working_directory value="$PROJECT_DIR$" />
|
||||||
|
<kind value="PACKAGE" />
|
||||||
|
<package value="legalgo-BE-go/cmd/legalgo" />
|
||||||
|
<directory value="$PROJECT_DIR$" />
|
||||||
|
<filePath value="$PROJECT_DIR$/cmd/legalgo/main.go" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<recent_temporary>
|
||||||
|
<list>
|
||||||
|
<item itemvalue="Go Build.go build legalgo-BE-go/cmd/legalgo" />
|
||||||
|
</list>
|
||||||
|
</recent_temporary>
|
||||||
|
</component>
|
||||||
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="3" />
|
||||||
|
</component>
|
||||||
|
<component name="VgoProject">
|
||||||
|
<settings-migrated>true</settings-migrated>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"arjun.swagger-viewer"
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+22
@@ -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": ""
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
FROM golang:1.24 AS build
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# RUN CGO_ENABLED=0 GOOS=linux go build -o /app cmd/klinik-core-service
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build -o /app cmd/legalgo/main.go
|
||||||
|
|
||||||
|
RUN ls -la /
|
||||||
|
|
||||||
|
FROM gcr.io/distroless/static
|
||||||
|
|
||||||
|
WORKDIR /
|
||||||
|
|
||||||
|
COPY --from=build /usr/share/zoneinfo /usr/share/zoneinfo
|
||||||
|
COPY --from=build /app /app
|
||||||
|
|
||||||
|
# RUN ls -la /
|
||||||
|
|
||||||
|
ENV TZ=Asia/Jakarta
|
||||||
|
|
||||||
|
ENTRYPOINT ["/app"]
|
||||||
@@ -148,6 +148,12 @@ make run
|
|||||||
|
|
||||||
This command will compile and execute your Go application.
|
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
|
**Note:** Ensure that your `Makefile` is correctly set up to handle these commands. If not, you may need to create
|
||||||
|
|||||||
+22
-3
@@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"legalgo-BE-go/config"
|
"legalgo-BE-go/config"
|
||||||
"legalgo-BE-go/database"
|
"legalgo-BE-go/database"
|
||||||
|
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@@ -24,23 +25,41 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.InitEnv()
|
config.InitEnv()
|
||||||
db, err := database.NewDB()
|
cfg := config.LoadConfig()
|
||||||
|
db, err := database.NewDB(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
var temp subscribeplandomain.SubscribePlan
|
var tempSP subscribeplandomain.SubscribePlan
|
||||||
|
var tempCtg categorydomain.Category
|
||||||
|
|
||||||
if err := db.Where("code = ?", "basic").First(&temp).Error; err != nil {
|
if err := db.Where("code = ?", "basic").First(&tempSP).Error; err != nil {
|
||||||
log.Print("seeding basic subscribe plan")
|
log.Print("seeding basic subscribe plan")
|
||||||
db.Create(&subscribeplandomain.SubscribePlan{
|
db.Create(&subscribeplandomain.SubscribePlan{
|
||||||
ID: uuid.NewString(),
|
ID: uuid.NewString(),
|
||||||
Code: "basic",
|
Code: "basic",
|
||||||
Name: "Basic",
|
Name: "Basic",
|
||||||
|
Length: 0,
|
||||||
|
Price: 0,
|
||||||
|
Status: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Where("code = ?", "spotlight").First(&tempCtg).Error; err != nil {
|
||||||
|
log.Print("seeding basic subscribe plan")
|
||||||
|
seq := 0
|
||||||
|
db.Create(&categorydomain.Category{
|
||||||
|
ID: uuid.NewString(),
|
||||||
|
Code: "spotlight",
|
||||||
|
Name: "Spotlight",
|
||||||
|
Sequence: &seq,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-2
@@ -15,6 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -32,16 +33,26 @@ func init() {
|
|||||||
config.InitEnv()
|
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{
|
lc.Append(fx.Hook{
|
||||||
OnStart: func(ctx context.Context) error {
|
OnStart: func(ctx context.Context) error {
|
||||||
fmt.Println("Application has started...")
|
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)
|
pkgconfig.Router(apiRouter)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
OnStop: func(ctx context.Context) error {
|
OnStop: func(ctx context.Context) error {
|
||||||
fmt.Println("Shutting down...")
|
fmt.Println("Shutting down...")
|
||||||
|
rdb.Close()
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -49,10 +60,11 @@ func run(lc fx.Lifecycle, db *database.DB, apiRouter chi.Router) {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fx.New(
|
app := fx.New(
|
||||||
|
config.Module,
|
||||||
database.Module,
|
database.Module,
|
||||||
repository.Module,
|
repository.Module,
|
||||||
internalhttp.Module,
|
|
||||||
services.Module,
|
services.Module,
|
||||||
|
internalhttp.Module,
|
||||||
fx.Invoke(run),
|
fx.Invoke(run),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type AuthConfig struct {
|
||||||
|
jwtTokenExpiresTTL int
|
||||||
|
jwtTokenSecret string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *AuthConfig) AccessTokenSecret() string {
|
||||||
|
return c.jwtTokenSecret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *AuthConfig) AccessTokenExpiresDate() time.Time {
|
||||||
|
duration := time.Duration(c.jwtTokenExpiresTTL)
|
||||||
|
return time.Now().UTC().Add(time.Minute * duration)
|
||||||
|
}
|
||||||
+24
-12
@@ -1,11 +1,11 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import "fmt"
|
||||||
"legalgo-BE-go/internal/utilities/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
APP_PORT int
|
APP_PORT,
|
||||||
|
REDIS_DB,
|
||||||
|
REDIS_TIMEOUT,
|
||||||
GRACEFULL_TIMEOUT int
|
GRACEFULL_TIMEOUT int
|
||||||
|
|
||||||
// DB
|
// DB
|
||||||
@@ -13,16 +13,28 @@ var (
|
|||||||
DB_USER,
|
DB_USER,
|
||||||
DB_PASSWORD,
|
DB_PASSWORD,
|
||||||
DB_NAME,
|
DB_NAME,
|
||||||
DB_PORT string
|
DB_PORT,
|
||||||
|
REDIS_PASSWORD,
|
||||||
|
REDIS_ADDR,
|
||||||
|
REDIS_USERNAME,
|
||||||
|
SALT_SECURITY string
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitEnv() {
|
func InitEnv() {
|
||||||
DB_HOST = utils.GetOrDefault("DB_HOST", "localhost")
|
DB_HOST = GetOrDefault("DB_HOST", "localhost")
|
||||||
DB_USER = utils.GetOrDefault("DB_USER", "")
|
DB_USER = GetOrDefault("DB_USER", "")
|
||||||
DB_PASSWORD = utils.GetOrDefault("DB_PASSWORD", "")
|
DB_PASSWORD = GetOrDefault("DB_PASSWORD", "")
|
||||||
DB_NAME = utils.GetOrDefault("DB_NAME", "")
|
DB_NAME = GetOrDefault("DB_NAME", "")
|
||||||
DB_PORT = utils.GetOrDefault("DB_PORT", "")
|
DB_PORT = GetOrDefault("DB_PORT", "")
|
||||||
|
|
||||||
APP_PORT = utils.GetOrDefault("APP_PORT", 3000)
|
SALT_SECURITY = GetOrDefault("SALT_SECURITY", "legalgo")
|
||||||
GRACEFULL_TIMEOUT = utils.GetOrDefault("GRACEFULL_TIMEOUT", 10)
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
_ "gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
YAML_PATH = "env/%s"
|
||||||
|
ENV_MODE = "ENV_MODE"
|
||||||
|
DEFAULT_ENV_MODE = "local"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
validEnvMode = map[string]struct{}{
|
||||||
|
"local": {},
|
||||||
|
"staging": {},
|
||||||
|
"production": {},
|
||||||
|
"debug": {},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Server Server `mapstructure:"server"`
|
||||||
|
Database Database `mapstructure:"postgresql"`
|
||||||
|
Jwt Jwt `mapstructure:"jwt"`
|
||||||
|
OSSConfig OSSConfig `mapstructure:"oss"`
|
||||||
|
Redis Redis `mapstructure:"redis"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
config *Config
|
||||||
|
configOnce sync.Once
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadConfig() *Config {
|
||||||
|
envMode := os.Getenv(ENV_MODE)
|
||||||
|
if _, ok := validEnvMode[envMode]; !ok {
|
||||||
|
envMode = DEFAULT_ENV_MODE // default env mode
|
||||||
|
}
|
||||||
|
cfgFilePath := fmt.Sprintf(YAML_PATH, envMode)
|
||||||
|
|
||||||
|
configOnce.Do(func() {
|
||||||
|
v := viper.New()
|
||||||
|
v.SetConfigType("yaml")
|
||||||
|
v.AddConfigPath(".")
|
||||||
|
v.SetConfigName(cfgFilePath)
|
||||||
|
if err := v.ReadInConfig(); err != nil {
|
||||||
|
panic(fmt.Errorf("failed to read config file: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
config = &Config{}
|
||||||
|
if err := v.Unmarshal(config); err != nil {
|
||||||
|
panic(fmt.Errorf("failed to unmarshal config: %s", err))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) Auth() *AuthConfig {
|
||||||
|
return &AuthConfig{
|
||||||
|
jwtTokenSecret: c.Jwt.Token.Secret,
|
||||||
|
jwtTokenExpiresTTL: c.Jwt.Token.ExpiresTTL,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Database struct {
|
||||||
|
Host string `mapstructure:"host"`
|
||||||
|
Port string `mapstructure:"port"`
|
||||||
|
DB string `mapstructure:"db"`
|
||||||
|
Driver string `mapstructure:"driver"`
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Database) DSN() string {
|
||||||
|
return fmt.Sprintf("host=%s port=%s dbname=%s user=%s password=%s sslmode=%s", c.Host, c.Port, c.DB, c.Username, c.Password, c.SslMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Database) ConnectionMaxLifetime() time.Duration {
|
||||||
|
return time.Duration(c.ConnectionMaxLifetimeInSecond) * time.Second
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type httpConfig struct {
|
||||||
|
host string
|
||||||
|
port int
|
||||||
|
detailedError bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *httpConfig) Address() string {
|
||||||
|
return fmt.Sprintf("%s:%d", c.host, c.port)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *httpConfig) DetailedError() bool {
|
||||||
|
return c.detailedError
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type Jwt struct {
|
||||||
|
Token Token `mapstructure:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Token struct {
|
||||||
|
ExpiresTTL int `mapstructure:"expires-ttl"`
|
||||||
|
Secret string `mapstructure:"secret"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.uber.org/fx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Module = fx.Module("config",
|
||||||
|
fx.Provide(
|
||||||
|
LoadConfig,
|
||||||
|
),
|
||||||
|
)
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type OSSConfig struct {
|
||||||
|
AccessKeyID string `mapstructure:"access_key_id"`
|
||||||
|
AccessKeySecret string `mapstructure:"access_key_secret"`
|
||||||
|
Endpoint string `mapstructure:"endpoint"`
|
||||||
|
BucketName string `mapstructure:"bucket_name"`
|
||||||
|
PhotoFolder string `mapstructure:"photo_folder"`
|
||||||
|
LogLevel string `mapstructure:"log_level"`
|
||||||
|
HostURL string `mapstructure:"host_url"`
|
||||||
|
PublicURL string `mapstructure:"public_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c OSSConfig) GetAccessKeyID() string {
|
||||||
|
return c.AccessKeyID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c OSSConfig) GetAccessKeySecret() string {
|
||||||
|
return c.AccessKeySecret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c OSSConfig) GetEndpoint() string {
|
||||||
|
return c.Endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c OSSConfig) GetBucketName() string {
|
||||||
|
return c.BucketName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c OSSConfig) GetLogLevel() string {
|
||||||
|
return c.LogLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c OSSConfig) GetHostURL() string {
|
||||||
|
return c.HostURL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c OSSConfig) GetPublicURL() string {
|
||||||
|
return c.PublicURL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c OSSConfig) GetPhotoFolder() string {
|
||||||
|
return c.PhotoFolder
|
||||||
|
}
|
||||||
@@ -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"`
|
||||||
|
SSL bool `mapstructure:"ssl"`
|
||||||
|
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"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
Port string `mapstructure:"port"`
|
||||||
|
BaseUrl string `mapstructure:"common-url"`
|
||||||
|
LocalUrl string `mapstructure:"local-url"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
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"`
|
||||||
|
StartDate *time.Time `gorm:"default:null" json:"start_date"`
|
||||||
|
EndDate *time.Time `gorm:"default:null" json:"end_date"`
|
||||||
|
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Category struct {
|
||||||
|
ID string `gorm:"primaryKey" json:"id"`
|
||||||
|
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"`
|
||||||
|
|
||||||
|
News []News `gorm:"many2many:news_categories" json:"news"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type ContentLog struct {
|
||||||
|
ID string `gorm:"primaryKey;not null" json:"id"`
|
||||||
|
ContentID string `gorm:"not null" json:"content_id"`
|
||||||
|
UserID string `gorm:"default:null" json:"user_id"`
|
||||||
|
IP string `gorm:"default:null" json:"ip"`
|
||||||
|
UserAgent string `gorm:"default:null" json:"user_agent"`
|
||||||
|
Category string `gorm:"not null" json:"category"`
|
||||||
|
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||||
|
}
|
||||||
+21
-7
@@ -13,14 +13,15 @@ type DB struct {
|
|||||||
*gorm.DB
|
*gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDB() (*DB, error) {
|
func NewDB(cfg *config.Config) (*DB, error) {
|
||||||
dsn := fmt.Sprintf(
|
dsn := fmt.Sprintf(
|
||||||
"host=%s user=%s password=%s dbname=%s port=%v sslmode=disable",
|
"host=%s user=%s password=%s dbname=%s port=%v sslmode=%s",
|
||||||
config.DB_HOST,
|
cfg.Database.Host,
|
||||||
config.DB_USER,
|
cfg.Database.Username,
|
||||||
config.DB_PASSWORD,
|
cfg.Database.Password,
|
||||||
config.DB_NAME,
|
cfg.Database.DB,
|
||||||
config.DB_PORT,
|
cfg.Database.Port,
|
||||||
|
cfg.Database.SslMode,
|
||||||
)
|
)
|
||||||
|
|
||||||
if dsn == "" {
|
if dsn == "" {
|
||||||
@@ -36,6 +37,14 @@ 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(
|
||||||
|
&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 +52,10 @@ func (db *DB) Migrate() error {
|
|||||||
&SubscribePlan{},
|
&SubscribePlan{},
|
||||||
&Subscribe{},
|
&Subscribe{},
|
||||||
&User{},
|
&User{},
|
||||||
|
&News{},
|
||||||
|
&Tag{},
|
||||||
|
&Category{},
|
||||||
|
&Ads{},
|
||||||
|
&ContentLog{},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,18 @@ 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 `json:"title"`
|
||||||
Title string `gorm:"default:null" json:"title"`
|
Content string `json:"content"`
|
||||||
Content string `gorm:"default:null" json:"content"`
|
Categories []Category `gorm:"many2many:news_categories" json:"categories"`
|
||||||
|
Tags []Tag `gorm:"many2many:news_tags" json:"tags"`
|
||||||
IsPremium bool `gorm:"default:false" json:"is_premium"`
|
IsPremium bool `gorm:"default:false" json:"is_premium"`
|
||||||
Slug string `gorm:"default:null" json:"slug"`
|
Slug string `gorm:"default:null" json:"slug"`
|
||||||
FeaturedImage string `gorm:"default:null" json:"featured_image"`
|
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"`
|
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"`
|
||||||
|
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
|
||||||
|
|
||||||
|
Author Staff `gorm:"foreignKey:AuthorID" json:"author"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ 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"`
|
Name string `gorm:"default:null" json:"name"`
|
||||||
Email string `gorm:"unique,not null" json:"email"`
|
ProfilePicture string `gorm:"default:null" json:"profile_picture"`
|
||||||
|
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"`
|
||||||
|
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,18 +9,22 @@ type Subscribe struct {
|
|||||||
SubscribePlanID string `gorm:"not null" json:"subscribe_plan_id"`
|
SubscribePlanID string `gorm:"not null" json:"subscribe_plan_id"`
|
||||||
StartDate time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
StartDate time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
||||||
EndDate time.Time `gorm:"default:null"`
|
EndDate time.Time `gorm:"default:null"`
|
||||||
Status string `gorm:"default:'inactive'"`
|
Status int8 `gorm:"default:0"`
|
||||||
AutoRenew bool `gorm:"default:true"`
|
AutoRenew bool `gorm:"default:true"`
|
||||||
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"`
|
||||||
|
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 {
|
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"`
|
||||||
|
Length int `gorm:"default:0" json:"length"`
|
||||||
|
Price float32 `gorm:"default:0" json:"price"`
|
||||||
|
Status int8 `gorm:"default:1" json:"status"`
|
||||||
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"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Tag struct {
|
||||||
|
ID string `gorm:"primaryKey" json:"id"`
|
||||||
|
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"`
|
||||||
|
|
||||||
|
News []News `gorm:"many2many:news_tags" json:"news"`
|
||||||
|
}
|
||||||
@@ -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,13 +5,14 @@ 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"`
|
||||||
|
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"`
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+43
@@ -0,0 +1,43 @@
|
|||||||
|
server:
|
||||||
|
base-url: https://api.legalgo.id/core
|
||||||
|
local-url: http://localhost:3300
|
||||||
|
port: 3300
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
token:
|
||||||
|
expires-ttl: 1440
|
||||||
|
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
host: dpg-d046h549c44c739arfv0-a.singapore-postgres.render.com
|
||||||
|
port: 5432
|
||||||
|
driver: postgres
|
||||||
|
db: legalgonews_prod
|
||||||
|
username: legalgo_admin
|
||||||
|
password: "656ogwc0JlLEVQyHnT5RrrYa7762iBQQ"
|
||||||
|
ssl-mode: require
|
||||||
|
max-idle-connections-in-second: 600
|
||||||
|
max-open-connections-in-second: 600
|
||||||
|
connection-max-life-time-in-second: 600
|
||||||
|
debug: false
|
||||||
|
|
||||||
|
oss:
|
||||||
|
access_key_id: GTK7i3SVy9llQeGH0Htv
|
||||||
|
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
|
||||||
|
endpoint: news-cdn.legalgo.id
|
||||||
|
bucket_name: uploads
|
||||||
|
log_level: Error
|
||||||
|
host_url: https://news-cdn.legalgo.id
|
||||||
|
public_url: https://news-cdn.legalgo.id
|
||||||
|
|
||||||
|
redis:
|
||||||
|
host: singapore-keyvalue.render.com
|
||||||
|
port: 6379
|
||||||
|
username: red-d046l42dbo4c73ea9iag
|
||||||
|
password: 7cZvu08JKuO9MPNxBb97tZCVNj0ZGNp2
|
||||||
|
db: 5
|
||||||
|
ssl: true
|
||||||
|
max-idle-connections-in-second: 600
|
||||||
|
max-open-connections-in-second: 600
|
||||||
|
connection-max-life-time-in-second: 600
|
||||||
|
debug: false
|
||||||
Vendored
+43
@@ -0,0 +1,43 @@
|
|||||||
|
server:
|
||||||
|
base-url: https://api.legalgo.id/core
|
||||||
|
local-url: http://localhost:3300
|
||||||
|
port: 3300
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
token:
|
||||||
|
expires-ttl: 1440
|
||||||
|
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
host: dpg-d04bi9juibrs73augcc0-a.singapore-postgres.render.com
|
||||||
|
port: 5432
|
||||||
|
driver: postgres
|
||||||
|
db: legalgonews_dev
|
||||||
|
username: legalgo_admin
|
||||||
|
password: "5h7DCBR1T8pug6AlbrHXqIDAr9o2vnky"
|
||||||
|
ssl-mode: require
|
||||||
|
max-idle-connections-in-second: 600
|
||||||
|
max-open-connections-in-second: 600
|
||||||
|
connection-max-life-time-in-second: 600
|
||||||
|
debug: false
|
||||||
|
|
||||||
|
oss:
|
||||||
|
access_key_id: GTK7i3SVy9llQeGH0Htv
|
||||||
|
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
|
||||||
|
endpoint: news-cdn.legalgo.id
|
||||||
|
bucket_name: uploads-staging
|
||||||
|
log_level: Error
|
||||||
|
host_url: https://news-cdn.legalgo.id
|
||||||
|
public_url: https://news-cdn.legalgo.id
|
||||||
|
|
||||||
|
redis:
|
||||||
|
host: singapore-keyvalue.render.com
|
||||||
|
port: 6379
|
||||||
|
username: red-d04c8k49c44c739ga8dg
|
||||||
|
password: ItPzniHv94yr8vY4HTrhCfKoibqBh61T
|
||||||
|
db: 5
|
||||||
|
ssl: true
|
||||||
|
max-idle-connections-in-second: 600
|
||||||
|
max-open-connections-in-second: 600
|
||||||
|
connection-max-life-time-in-second: 600
|
||||||
|
debug: false
|
||||||
Vendored
+42
@@ -0,0 +1,42 @@
|
|||||||
|
server:
|
||||||
|
base-url: https://api.legalgo.id/core
|
||||||
|
local-url: http://localhost:3300
|
||||||
|
port: 3300
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
token:
|
||||||
|
expires-ttl: 1440
|
||||||
|
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
host: dpg-d046h549c44c739arfv0-a
|
||||||
|
port: 5432
|
||||||
|
driver: postgres
|
||||||
|
db: legalgonews_prod
|
||||||
|
username: legalgo_admin
|
||||||
|
password: "656ogwc0JlLEVQyHnT5RrrYa7762iBQQ"
|
||||||
|
ssl-mode: disable
|
||||||
|
max-idle-connections-in-second: 600
|
||||||
|
max-open-connections-in-second: 600
|
||||||
|
connection-max-life-time-in-second: 600
|
||||||
|
debug: false
|
||||||
|
|
||||||
|
oss:
|
||||||
|
access_key_id: GTK7i3SVy9llQeGH0Htv
|
||||||
|
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
|
||||||
|
endpoint: news-cdn.legalgo.id
|
||||||
|
bucket_name: uploads
|
||||||
|
log_level: Error
|
||||||
|
host_url: https://news-cdn.legalgo.id
|
||||||
|
public_url: https://news-cdn.legalgo.id
|
||||||
|
|
||||||
|
redis:
|
||||||
|
host: red-d046l42dbo4c73ea9iag
|
||||||
|
port: 6379
|
||||||
|
password: 7cZvu08JKuO9MPNxBb97tZCVNj0ZGNp2
|
||||||
|
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
|
||||||
Vendored
+42
@@ -0,0 +1,42 @@
|
|||||||
|
server:
|
||||||
|
base-url: https://api.legalgo.id/core
|
||||||
|
local-url: http://localhost:3300
|
||||||
|
port: 3300
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
token:
|
||||||
|
expires-ttl: 1440
|
||||||
|
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
host: dpg-d04bi9juibrs73augcc0-a
|
||||||
|
port: 5432
|
||||||
|
driver: postgres
|
||||||
|
db: legalgonews_dev
|
||||||
|
username: legalgo_admin
|
||||||
|
password: "5h7DCBR1T8pug6AlbrHXqIDAr9o2vnky"
|
||||||
|
ssl-mode: disable
|
||||||
|
max-idle-connections-in-second: 600
|
||||||
|
max-open-connections-in-second: 600
|
||||||
|
connection-max-life-time-in-second: 600
|
||||||
|
debug: false
|
||||||
|
|
||||||
|
oss:
|
||||||
|
access_key_id: GTK7i3SVy9llQeGH0Htv
|
||||||
|
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
|
||||||
|
endpoint: news-cdn.legalgo.id
|
||||||
|
bucket_name: uploads-staging
|
||||||
|
log_level: Error
|
||||||
|
host_url: https://news-cdn.legalgo.id
|
||||||
|
public_url: https://news-cdn.legalgo.id
|
||||||
|
|
||||||
|
redis:
|
||||||
|
host: red-d04c8k49c44c739ga8dg
|
||||||
|
port: 6379
|
||||||
|
password: ItPzniHv94yr8vY4HTrhCfKoibqBh61T
|
||||||
|
db: 5
|
||||||
|
ssl: false
|
||||||
|
max-idle-connections-in-second: 600
|
||||||
|
max-open-connections-in-second: 600
|
||||||
|
connection-max-life-time-in-second: 600
|
||||||
|
debug: false
|
||||||
@@ -1,31 +1,48 @@
|
|||||||
module legalgo-BE-go
|
module legalgo-BE-go
|
||||||
|
|
||||||
go 1.24.0
|
go 1.24
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
|
github.com/spf13/viper v1.19.0
|
||||||
go.uber.org/fx v1.23.0
|
go.uber.org/fx v1.23.0
|
||||||
golang.org/x/crypto v0.34.0
|
golang.org/x/crypto v0.34.0
|
||||||
gorm.io/driver/postgres v1.5.11
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
gorm.io/driver/postgres v1.5.7
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/jackc/pgpassfile 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/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
github.com/jackc/pgx/v5 v5.7.2 // indirect
|
github.com/jackc/pgx/v5 v5.4.3 // indirect
|
||||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||||
|
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||||
|
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||||
|
github.com/spf13/afero v1.11.0 // indirect
|
||||||
|
github.com/spf13/cast v1.6.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||||
golang.org/x/net v0.34.0 // indirect
|
golang.org/x/net v0.34.0 // indirect
|
||||||
golang.org/x/text v0.22.0 // indirect
|
golang.org/x/text v0.22.0 // indirect
|
||||||
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/aws/aws-sdk-go v1.50.0
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/go-chi/chi/v5 v5.2.1
|
github.com/go-chi/chi/v5 v5.2.1
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
github.com/aws/aws-sdk-go v1.50.0 h1:HBtrLeO+QyDKnc3t1+5DR1RxodOHCGr8ZcrHudpv7jI=
|
||||||
|
github.com/aws/aws-sdk-go v1.50.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
||||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||||
@@ -5,10 +7,15 @@ github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0
|
|||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
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/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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=
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||||
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
|
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
|
||||||
@@ -25,35 +32,76 @@ github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0
|
|||||||
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
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 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
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/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
|
github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
|
||||||
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
|
||||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
|
||||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
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/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||||
|
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||||
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||||
|
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 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
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=
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||||
|
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
|
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 h1:4LhKRCIduqXqtvCUlaq9c8bdHOkICjDMrr1+Zb3osAc=
|
||||||
github.com/redis/go-redis/v9 v9.7.1/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
github.com/redis/go-redis/v9 v9.7.1/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||||
|
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=
|
||||||
|
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||||
|
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||||
|
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
|
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||||
|
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||||
|
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||||
|
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||||
|
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||||
|
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
||||||
|
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
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=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
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=
|
||||||
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
|
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
|
||||||
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
||||||
go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
|
go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
|
||||||
@@ -66,6 +114,8 @@ go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
|||||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||||
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
|
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/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/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
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/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||||
@@ -76,10 +126,16 @@ golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|||||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
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/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/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.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.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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=
|
gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
|
||||||
gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
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 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package adsrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *accessor) Delete(id string) error {
|
||||||
|
var ads adsdomain.Ads
|
||||||
|
if err := a.db.First(&ads, "id = ?", id).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return fmt.Errorf("ads with id %s is not found", id)
|
||||||
|
|
||||||
|
}
|
||||||
|
return fmt.Errorf("failed to g ads %s : %v", id, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := a.db.Delete(&ads).Error; err != nil {
|
||||||
|
return fmt.Errorf("failed to delete ads %s : %v", id, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package adsrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *accessor) GetAll() ([]adsdomain.AdsResponse, error) {
|
||||||
|
var ads []adsdomain.AdsResponse
|
||||||
|
|
||||||
|
if err := a.db.Table("ads").
|
||||||
|
Select("ads.*, COUNT(content_logs.content_id) as clicked").
|
||||||
|
Joins("LEFT JOIN content_logs ON content_logs.content_id = ads.id").
|
||||||
|
Group("ads.id").
|
||||||
|
Scan(&ads).Error; err != nil {
|
||||||
|
return ads, fmt.Errorf("failed to get all ads: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ads, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
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.AdsResponse, error)
|
||||||
|
Update(adsdomain.Ads) error
|
||||||
|
Delete(string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(
|
||||||
|
db *database.DB,
|
||||||
|
) Ads {
|
||||||
|
return &accessor{db}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package adsrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||||
|
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *accessor) Update(spec adsdomain.Ads) error {
|
||||||
|
if err := a.db.Clauses(clause.OnConflict{
|
||||||
|
Columns: []clause.Column{{Name: "id"}},
|
||||||
|
DoUpdates: clause.AssignmentColumns([]string{
|
||||||
|
"image_url",
|
||||||
|
"url",
|
||||||
|
"updated_at",
|
||||||
|
"start_date",
|
||||||
|
"end_date",
|
||||||
|
}),
|
||||||
|
}).Select(
|
||||||
|
"image_url",
|
||||||
|
"url",
|
||||||
|
"updated_at",
|
||||||
|
"start_date",
|
||||||
|
"end_date",
|
||||||
|
).Save(&spec).Error; err != nil {
|
||||||
|
return fmt.Errorf("failed to update tag: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
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.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 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package categoryrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *accessor) GetAllModel() ([]categorydomain.Category, error) {
|
||||||
|
var categories []categorydomain.Category
|
||||||
|
|
||||||
|
if err := a.db.Find(&categories).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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package categoryrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||||
|
)
|
||||||
|
|
||||||
|
type accessor struct {
|
||||||
|
db *database.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
type Category interface {
|
||||||
|
GetAllModel() ([]categorydomain.Category, error)
|
||||||
|
GetByIDs([]string) ([]categorydomain.Category, error)
|
||||||
|
GetIDByCode([]string) ([]string, error)
|
||||||
|
CreateModel(categorydomain.CategoryReq) error
|
||||||
|
Update(categorydomain.Category) error
|
||||||
|
Delete(string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(
|
||||||
|
db *database.DB,
|
||||||
|
) Category {
|
||||||
|
return &accessor{db}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package logrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
logsdomain "legalgo-BE-go/internal/domain/logs"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *accessor) CreateLog(spec logsdomain.LogsSpec) error {
|
||||||
|
newSpec := database.ContentLog{
|
||||||
|
ID: uuid.NewString(),
|
||||||
|
ContentID: spec.ContentID,
|
||||||
|
Category: spec.Category,
|
||||||
|
}
|
||||||
|
|
||||||
|
if spec.UserID != nil {
|
||||||
|
newSpec.UserID = *spec.UserID
|
||||||
|
}
|
||||||
|
|
||||||
|
if spec.IP != nil {
|
||||||
|
newSpec.IP = *spec.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
if spec.UserAgent != nil {
|
||||||
|
newSpec.UserAgent = *spec.UserAgent
|
||||||
|
}
|
||||||
|
if err := a.db.Create(&newSpec).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package logrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *accessor) GetAllLogAds(userID string) ([]adsdomain.Ads, error) {
|
||||||
|
var ads []adsdomain.Ads
|
||||||
|
|
||||||
|
// if err := a.db.Find(&ads, "user_id = ?", userID).Error; err != nil {
|
||||||
|
// return ads, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
if err := a.db.
|
||||||
|
Joins("JOIN log_ads ON ads.id = log_ads.ads_id").
|
||||||
|
Find(&ads, "log_ads.user_id = ?", userID).Error; err != nil {
|
||||||
|
return ads, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ads, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package logrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||||
|
logsdomain "legalgo-BE-go/internal/domain/logs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type accessor struct {
|
||||||
|
db *database.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
type Log interface {
|
||||||
|
CreateLog(logsdomain.LogsSpec) error
|
||||||
|
GetAllLogAds(string) ([]adsdomain.Ads, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(db *database.DB) Log {
|
||||||
|
return &accessor{db}
|
||||||
|
}
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
adsrepository "legalgo-BE-go/internal/accessor/ads"
|
||||||
|
categoryrepository "legalgo-BE-go/internal/accessor/category"
|
||||||
|
logrepository "legalgo-BE-go/internal/accessor/log"
|
||||||
|
newsrepository "legalgo-BE-go/internal/accessor/news"
|
||||||
|
"legalgo-BE-go/internal/accessor/oss"
|
||||||
redisaccessor "legalgo-BE-go/internal/accessor/redis"
|
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/subscribe_plan"
|
||||||
userrepository "legalgo-BE-go/internal/accessor/user_repository"
|
tagrepository "legalgo-BE-go/internal/accessor/tag"
|
||||||
|
userrepository "legalgo-BE-go/internal/accessor/user"
|
||||||
|
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
)
|
)
|
||||||
@@ -16,4 +22,10 @@ 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,
|
||||||
|
oss.New,
|
||||||
|
adsrepository.New,
|
||||||
|
logrepository.New,
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package newsrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
timeutils "legalgo-BE-go/internal/utilities/time_utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type is_active string
|
||||||
|
|
||||||
|
const (
|
||||||
|
active is_active = "true"
|
||||||
|
notActive is_active = "false"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *accessor) GetAll(filter newsdomain.NewsFilter) ([]newsdomain.NewsResponse, error) {
|
||||||
|
var news []newsdomain.NewsResponse
|
||||||
|
query := a.db.Table("news").
|
||||||
|
Preload("Tags").
|
||||||
|
Preload("Categories").
|
||||||
|
Preload("Author").
|
||||||
|
Joins("LEFT JOIN content_logs ON content_logs.content_id = news.id")
|
||||||
|
|
||||||
|
if len(filter.Category) > 0 {
|
||||||
|
query = query.Joins("JOIN news_categories nc ON nc.news_id = news.id").
|
||||||
|
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 filter.Active == string(active) {
|
||||||
|
query = query.Where("news.live_at <= ?", timeutils.Now())
|
||||||
|
}
|
||||||
|
|
||||||
|
if filter.Search != "" {
|
||||||
|
query = query.Where("news.title ILIKE ?", "%"+filter.Search+"%")
|
||||||
|
}
|
||||||
|
|
||||||
|
query.
|
||||||
|
Select("news.*, COUNT(content_logs.content_id) as views").
|
||||||
|
Group("news.id").
|
||||||
|
Order("news.created_at DESC")
|
||||||
|
|
||||||
|
if err := query.
|
||||||
|
Find(&news).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return news, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package newsrepository
|
||||||
|
|
||||||
|
import newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
|
||||||
|
func (a *accessor) GetByID(id string) (*newsdomain.News, error) {
|
||||||
|
var news newsdomain.News
|
||||||
|
|
||||||
|
if err := a.db.
|
||||||
|
Preload("Tags").
|
||||||
|
Preload("Categories").
|
||||||
|
Preload("Author").
|
||||||
|
First(&news, "id = ?", id).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &news, nil
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package newsrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||||
|
)
|
||||||
|
|
||||||
|
type accessor struct {
|
||||||
|
db *database.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
type News interface {
|
||||||
|
GetAll(filter newsdomain.NewsFilter) ([]newsdomain.NewsResponse, error)
|
||||||
|
GetBySlug(string) (*newsdomain.News, error)
|
||||||
|
GetByID(string) (*newsdomain.News, error)
|
||||||
|
Create(newsdomain.News) error
|
||||||
|
Update(newsdomain.News) error
|
||||||
|
Delete(string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(db *database.DB) News {
|
||||||
|
return &accessor{db}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package oss
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"legalgo-BE-go/config"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OSSConfig interface {
|
||||||
|
GetAccessKeyID() string
|
||||||
|
GetAccessKeySecret() string
|
||||||
|
GetEndpoint() string
|
||||||
|
GetBucketName() string
|
||||||
|
GetHostURL() string
|
||||||
|
GetPublicURL() string
|
||||||
|
}
|
||||||
|
|
||||||
|
const _awsRegion = "us-east-1"
|
||||||
|
const _s3ACL = "public-read"
|
||||||
|
|
||||||
|
type OssRepositoryImpl struct {
|
||||||
|
s3 *s3.S3
|
||||||
|
cfg OSSConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(cfg *config.Config) OSSRepository {
|
||||||
|
ossCfg := cfg.OSSConfig
|
||||||
|
sess, err := session.NewSession(&aws.Config{
|
||||||
|
S3ForcePathStyle: aws.Bool(true),
|
||||||
|
Endpoint: aws.String(ossCfg.GetEndpoint()),
|
||||||
|
Region: aws.String(_awsRegion),
|
||||||
|
Credentials: credentials.NewStaticCredentials(ossCfg.GetAccessKeyID(), ossCfg.GetAccessKeySecret(), ""),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to create AWS session:", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &OssRepositoryImpl{
|
||||||
|
s3: s3.New(sess),
|
||||||
|
cfg: ossCfg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OssRepositoryImpl) UploadFile(ctx context.Context, fileName string, fileContent []byte) (fileUrl string, err error) {
|
||||||
|
reader := bytes.NewReader(fileContent)
|
||||||
|
|
||||||
|
_, err = r.s3.PutObject(&s3.PutObjectInput{
|
||||||
|
Bucket: aws.String(r.cfg.GetBucketName()),
|
||||||
|
Key: aws.String(fileName),
|
||||||
|
Body: reader,
|
||||||
|
ACL: aws.String(_s3ACL),
|
||||||
|
})
|
||||||
|
|
||||||
|
return r.GetPublicURL(fileName), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OssRepositoryImpl) GetPublicURL(fileName string) string {
|
||||||
|
if fileName == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package oss
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package redisaccessor
|
package redisaccessor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"legalgo-BE-go/config"
|
||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
)
|
)
|
||||||
@@ -13,20 +14,22 @@ func Get() *redis.Client {
|
|||||||
return redisClient
|
return redisClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *redis.Client {
|
func New(cfg *config.Config) *redis.Client {
|
||||||
var (
|
addr := fmt.Sprintf("%s:%s", cfg.Redis.Host, cfg.Redis.Port)
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
redisClient = redis.NewClient(&redis.Options{
|
options := &redis.Options{
|
||||||
Username: username,
|
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
Password: password,
|
Password: cfg.Redis.Password,
|
||||||
DB: db,
|
DB: cfg.Redis.DB,
|
||||||
})
|
}
|
||||||
|
|
||||||
|
if cfg.Redis.Username != "" {
|
||||||
|
options.Username = cfg.Redis.Username
|
||||||
|
}
|
||||||
|
if cfg.Redis.SSL {
|
||||||
|
options.TLSConfig = &tls.Config{}
|
||||||
|
}
|
||||||
|
|
||||||
|
redisClient = redis.NewClient(options)
|
||||||
return redisClient
|
return redisClient
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package staffrepository
|
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) {
|
func (ur *accessor) Create(spec staffdomain.Staff) error {
|
||||||
if err := ur.DB.Create(&spec).Error; err != nil {
|
if err := ur.db.Create(&spec).Error; err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return spec, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,23 @@ package staffrepository
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (sr *StaffRepository) GetStaffByEmail(email string) (*authdomain.Staff, error) {
|
func (sr *accessor) GetStaffByEmail(email string) (*staffdomain.Staff, error) {
|
||||||
var staff authdomain.Staff
|
var staff staffdomain.Staff
|
||||||
|
|
||||||
if email == "" {
|
if email == "" {
|
||||||
return nil, errors.New("email is required")
|
return nil, fmt.Errorf("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, fmt.Errorf("staff not found")
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,22 @@ package staffrepository
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
"fmt"
|
||||||
|
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (sr *StaffRepository) GetStaffByID(ID string) (*authdomain.Staff, error) {
|
func (sr *accessor) GetStaffByID(ID string) (*staffdomain.Staff, error) {
|
||||||
var staff authdomain.Staff
|
var staff staffdomain.Staff
|
||||||
|
|
||||||
if ID == "" {
|
if ID == "" {
|
||||||
return nil, errors.New("id is required")
|
return nil, fmt.Errorf("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, fmt.Errorf("staff not found")
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package staffrepository
|
||||||
|
|
||||||
|
import staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||||
|
|
||||||
|
func (a *accessor) GetStaffs() ([]staffdomain.StaffProfile, error) {
|
||||||
|
var staffs []staffdomain.StaffProfile
|
||||||
|
|
||||||
|
if err := a.db.Table("staffs").Find(&staffs).Error; err != nil {
|
||||||
|
return staffs, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return staffs, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
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,
|
||||||
|
CreatedAt: user.CreatedAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
@@ -2,20 +2,23 @@ package staffrepository
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"legalgo-BE-go/database"
|
"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 {
|
type accessor struct {
|
||||||
DB *database.DB
|
db *database.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
type StaffIntf interface {
|
type Staff interface {
|
||||||
GetStaffByEmail(string) (*authdomain.Staff, error)
|
GetStaffByEmail(string) (*staffdomain.Staff, error)
|
||||||
GetStaffByID(string) (*authdomain.Staff, error)
|
GetStaffByID(string) (*staffdomain.Staff, error)
|
||||||
Create(*authdomain.Staff) (*authdomain.Staff, error)
|
GetUsers() ([]userdomain.UserProfile, error)
|
||||||
Update(authdomain.Staff) error
|
GetStaffs() ([]staffdomain.StaffProfile, error)
|
||||||
|
Create(staffdomain.Staff) error
|
||||||
|
Update(staffdomain.Staff) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(db *database.DB) StaffIntf {
|
func New(db *database.DB) Staff {
|
||||||
return &StaffRepository{db}
|
return &accessor{db}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
package staffrepository
|
package staffrepository
|
||||||
|
|
||||||
import (
|
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)
|
// val, err := utils.StructToMap(spec)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// 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(spec).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *SubsAccs) Create(subsPlanId string) (string, error) {
|
func (s *accessor) Create(subsPlanId string) (string, error) {
|
||||||
spec := &subscribedomain.Subscribe{
|
spec := &subscribedomain.Subscribe{
|
||||||
ID: uuid.NewString(),
|
ID: uuid.NewString(),
|
||||||
SubscribePlanID: subsPlanId,
|
SubscribePlanID: subsPlanId,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.DB.Create(&spec).Error; err != nil {
|
if err := s.db.Create(&spec).Error; err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -1,15 +1,20 @@
|
|||||||
package subscriberepository
|
package subscriberepository
|
||||||
|
|
||||||
import "legalgo-BE-go/database"
|
import (
|
||||||
|
"legalgo-BE-go/database"
|
||||||
|
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
|
||||||
|
)
|
||||||
|
|
||||||
type SubsAccs struct {
|
type accessor struct {
|
||||||
DB *database.DB
|
db *database.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubsIntf interface {
|
type Subscribe interface {
|
||||||
Create(string) (string, error)
|
Create(string) (string, error)
|
||||||
|
GetByID(string) (subscribedomain.Subscribe, error)
|
||||||
|
Update(subscribedomain.Subscribe) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(db *database.DB) SubsIntf {
|
func New(db *database.DB) Subscribe {
|
||||||
return &SubsAccs{db}
|
return &accessor{db}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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).Error; err != nil {
|
||||||
|
return fmt.Errorf("failed to change subscribe plan: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := a.db.Delete(&subsPlan, "id = ?", id).Error; err != nil {
|
||||||
|
return fmt.Errorf("failed to delete subscribe plan %s : %v", id, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
+2
-2
@@ -4,10 +4,10 @@ import (
|
|||||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
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
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package subscribeplanrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
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 errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return subscribePlan, fmt.Errorf("subscribe plan not found")
|
||||||
|
}
|
||||||
|
return subscribePlan, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return subscribePlan, nil
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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,33 @@
|
|||||||
|
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",
|
||||||
|
"length",
|
||||||
|
"price",
|
||||||
|
"status",
|
||||||
|
"updated_at",
|
||||||
|
}),
|
||||||
|
}).Select(
|
||||||
|
"name",
|
||||||
|
"code",
|
||||||
|
"length",
|
||||||
|
"price",
|
||||||
|
"status",
|
||||||
|
"updated_at",
|
||||||
|
).Save(&spec).Error; err != nil {
|
||||||
|
return fmt.Errorf("failed to update tag: %v", 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) 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.Where("code = ?", "basic").First(&subscribePlan).Error; err != nil {
|
|
||||||
s.DB.Create(&subscribeplandomain.SubscribePlan{
|
|
||||||
ID: uuid.NewString(),
|
|
||||||
Code: "basic",
|
|
||||||
Name: "Basic",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return subscribePlan, nil
|
|
||||||
}
|
|
||||||
@@ -1,22 +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)
|
|
||||||
GetDefault() (subscribeplandomain.SubscribePlan, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(
|
|
||||||
db *database.DB,
|
|
||||||
) SubsPlanIntf {
|
|
||||||
return &SubsPlan{db}
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
GetAll() ([]tagdomain.Tag, error)
|
||||||
|
GetByIDs([]string) ([]tagdomain.Tag, error)
|
||||||
|
GetIDsByCodes([]string) ([]string, error)
|
||||||
|
Update(tagdomain.Tag) error
|
||||||
|
Delete(string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(
|
||||||
|
db *database.DB,
|
||||||
|
) TagAccessor {
|
||||||
|
return &accessor{db}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package userrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
userdomain "legalgo-BE-go/internal/domain/user"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ur *accessor) GetUserByEmail(email string) (*userdomain.User, error) {
|
||||||
|
var user *userdomain.User
|
||||||
|
|
||||||
|
if email == "" {
|
||||||
|
return nil, fmt.Errorf("email is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ur.db.First(&user, "email = ?", email).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, fmt.Errorf("user not found")
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package userrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
userdomain "legalgo-BE-go/internal/domain/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ur *accessor) GetUserByID(id string) (*userdomain.User, error) {
|
||||||
|
var user userdomain.User
|
||||||
|
|
||||||
|
if id == "" {
|
||||||
|
return nil, fmt.Errorf("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,32 @@
|
|||||||
|
package userrepository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
userdomain "legalgo-BE-go/internal/domain/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ur *accessor) GetUserProfile(id string) (*userdomain.UserProfile, error) {
|
||||||
|
var user *userdomain.User
|
||||||
|
|
||||||
|
if id == "" {
|
||||||
|
return nil, fmt.Errorf("email is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ur.db.
|
||||||
|
Preload("Subscribe").
|
||||||
|
Preload("Subscribe.SubscribePlan").
|
||||||
|
First(&user, "id = ?", id).
|
||||||
|
Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
userProfile := &userdomain.UserProfile{
|
||||||
|
ID: user.ID,
|
||||||
|
Email: user.Email,
|
||||||
|
Phone: user.Phone,
|
||||||
|
Subscribe: user.Subscribe,
|
||||||
|
CreatedAt: user.CreatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
return userProfile, nil
|
||||||
|
}
|
||||||
@@ -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,26 +0,0 @@
|
|||||||
package userrepository
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
|
||||||
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ur *UserRepository) GetUserByEmail(email string) (*authdomain.User, error) {
|
|
||||||
var user authdomain.User
|
|
||||||
|
|
||||||
if email == "" {
|
|
||||||
return nil, errors.New("email is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ur.DB.Where("email = ?", email).First(&user).Error; err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, errors.New("user not found")
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &user, 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,22 +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)
|
|
||||||
CreateUser(*authdomain.User) (*authdomain.User, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(
|
|
||||||
db *database.DB,
|
|
||||||
) UserIntf {
|
|
||||||
return &UserRepository{db}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user