Compare commits
121
Commits
ae5b2cb975
...
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 | ||
|
|
4ec50cee8a | ||
|
|
84239864c1 | ||
|
|
5fb0764630 | ||
|
|
290c0edff7 | ||
|
|
ccd92c270a | ||
|
|
d2a43a88c4 | ||
|
|
33ba5fbbdc | ||
|
|
7b367f655e | ||
|
|
802692f6c1 | ||
|
|
14f38b792d | ||
|
|
da5b65b582 | ||
|
|
0a87f85358 | ||
|
|
0317ba04d9 | ||
|
|
775a9def75 | ||
|
|
27ff3996ed | ||
|
|
46472d01fe | ||
|
|
0100134527 | ||
|
|
ba075b67fd | ||
|
|
aee94a5c9c | ||
|
|
81c7a51256 | ||
|
|
3466a4b4c5 | ||
|
|
037acbe128 | ||
|
|
d492f3ce44 | ||
|
|
3b2321d5db | ||
|
|
bd305f0edf | ||
|
|
cb3d06fa02 |
@@ -3,3 +3,15 @@ DB_USER=
|
||||
DB_PASSWORD=
|
||||
DB_NAME=
|
||||
DB_PORT=
|
||||
|
||||
APP_PORT=
|
||||
GRACEFULL_TIMEOUT=
|
||||
SALT_SECURITY=
|
||||
|
||||
REDIS_HOST=
|
||||
REDIS_USERNAME=
|
||||
REDIS_PORT=
|
||||
REDIS_PASSWORD=
|
||||
REDIS_TTL=
|
||||
REDIS_DB=
|
||||
REDIS_TIMEOUT=
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
bin
|
||||
.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>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"default": true,
|
||||
"MD013": false,
|
||||
"MD026": false,
|
||||
"MD033": false,
|
||||
"MD040": false,
|
||||
"MD041": false
|
||||
}
|
||||
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"]
|
||||
@@ -9,32 +9,41 @@ Before proceeding, make sure you have the following installed on your computer:
|
||||
|
||||
## Steps to Install Go 1.24.0
|
||||
|
||||
### For Windows:
|
||||
### `go` For Windows:
|
||||
|
||||
1. Download the installer from [official Go website](https://golang.org/dl/).
|
||||
2. Run the downloaded `.msi` file and follow the installation wizard.
|
||||
3. During installation, you may be prompted to set the `GOPATH` and `GOROOT`. Choose the appropriate settings
|
||||
based on your preference or keep the default values.
|
||||
|
||||
### For macOS:
|
||||
### `go` For macOS:
|
||||
|
||||
1. Open Terminal.
|
||||
2. Download the package using Homebrew (if not installed, visit [Homebrew website](https://brew.sh/) for
|
||||
installation instructions):
|
||||
|
||||
```bash
|
||||
brew install go@1.24
|
||||
```
|
||||
|
||||
3. Link the installed version to your PATH:
|
||||
|
||||
```bash
|
||||
brew link --overwrite --force go@1.24
|
||||
```
|
||||
|
||||
### For Linux:
|
||||
### `go` For Linux:
|
||||
|
||||
1. Open Terminal.
|
||||
2. Download the appropriate tarball from [official Go website](https://golang.org/dl/).
|
||||
3. Extract the downloaded archive:
|
||||
|
||||
```bash
|
||||
tar -C /usr/local -xzf go1.24.linux-amd64.tar.gz
|
||||
```
|
||||
|
||||
4. Add Go to your PATH by editing your shell configuration file (e.g., `.bashrc`, `.zshrc`):
|
||||
|
||||
```bash
|
||||
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
|
||||
source ~/.bashrc
|
||||
@@ -43,25 +52,31 @@ installation instructions):
|
||||
## Verify Installation
|
||||
|
||||
After installation, verify that Go 1.24.0 is installed correctly by running:
|
||||
|
||||
```bash
|
||||
go version
|
||||
```
|
||||
|
||||
You should see an output like `go version go1.24 darwin/amd64` (or similar, depending on your OS).
|
||||
|
||||
## Install Make (if not already installed)
|
||||
|
||||
### For Windows:
|
||||
### `make` For Windows:
|
||||
|
||||
- Download and install [Make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm).
|
||||
- Add the installation directory to your PATH.
|
||||
|
||||
### For macOS:
|
||||
### `make` For macOS:
|
||||
|
||||
1. Open Terminal.
|
||||
2. Install Make using Homebrew:
|
||||
|
||||
```bash
|
||||
brew install make
|
||||
```
|
||||
|
||||
### For Linux:
|
||||
### `make` For Linux:
|
||||
|
||||
Make is usually pre-installed on most Linux distributions. If it's not installed, you can install it using your
|
||||
package manager (e.g., `sudo apt-get install make` for Ubuntu).
|
||||
|
||||
@@ -72,13 +87,53 @@ Open Terminal and navigate to the root directory of your Go project.
|
||||
## Resolve Dependencies with `go mod tidy`
|
||||
|
||||
Run the following command to download and resolve all dependencies specified in your `go.mod` file:
|
||||
|
||||
```bash
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
## Setup Database
|
||||
|
||||
In your Go application, you'll need to set the following environment variables to connect to your database:
|
||||
|
||||
```bash
|
||||
DB_HOST: The hostname or IP address of your database server (e.g., localhost, 127.0.0.1, or the actual DB server URL).
|
||||
DB_USER: The username for your database connection.
|
||||
DB_PASSWORD: The password associated with the DB_USER.
|
||||
DB_NAME: The name of the database you want to connect to.
|
||||
DB_PORT: The port number your database server is running on (default MySQL port is 3306, default PostgreSQL port is 5432).
|
||||
```
|
||||
|
||||
## Create `.env` File
|
||||
|
||||
It's best practice to keep sensitive information like database credentials in an environment file. Create or edit the .env file in the root directory of your project and add the following lines:
|
||||
|
||||
```bash
|
||||
DB_HOST=localhost
|
||||
DB_USER=your_db_user
|
||||
DB_PASSWORD=your_db_password
|
||||
DB_NAME=your_db_name
|
||||
DB_PORT=3306 # or 5432, depending on your DB type
|
||||
|
||||
APP_PORT=3000 # example
|
||||
GRACEFULL_TIMEOUT=10 #example
|
||||
SALT_SECURITY=your_secret_security
|
||||
|
||||
Make sure to replace the values with your actual database details.
|
||||
```
|
||||
|
||||
## Migrate the Database Using `make migrate`
|
||||
|
||||
Before running your application, let's setup your database first.
|
||||
|
||||
```bash
|
||||
make migrate
|
||||
```
|
||||
|
||||
## Build the Binary Using `make build`
|
||||
|
||||
Run the following command to build your project. The binary will be placed in the `bin` folder.
|
||||
|
||||
```bash
|
||||
make build
|
||||
```
|
||||
@@ -86,16 +141,24 @@ make build
|
||||
## Run the Program Using `make run`
|
||||
|
||||
Finally, you can run your program using:
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
|
||||
This command will compile and execute your Go application.
|
||||
|
||||
Or you can execute the compiled binary at `bin/legalgo` by:
|
||||
|
||||
```bash
|
||||
./bin/legalgo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Note:** Ensure that your `Makefile` is correctly set up to handle these commands. If not, you may need to create
|
||||
or adjust it accordingly.
|
||||
|
||||
```
|
||||
|
||||
Please follow the above instructions to set up Go version 1.24.0, manage dependencies using `go mod tidy`, build a
|
||||
|
||||
+63
-1
@@ -1,5 +1,67 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"legalgo-BE-go/config"
|
||||
"legalgo-BE-go/database"
|
||||
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Check if the .env file exists
|
||||
if _, err := os.Stat(".env"); err == nil {
|
||||
// Load environment variables from .env file if it exists
|
||||
if err := godotenv.Load(); err != nil {
|
||||
log.Println("Error loading .env file, continuing without it")
|
||||
}
|
||||
} else {
|
||||
log.Println(".env file not found, skipping load")
|
||||
}
|
||||
|
||||
config.InitEnv()
|
||||
cfg := config.LoadConfig()
|
||||
db, err := database.NewDB(cfg)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to connect to database: %v", err)
|
||||
}
|
||||
|
||||
// db.DropTables()
|
||||
|
||||
if err := db.Migrate(); err != nil {
|
||||
log.Fatal("Migration failed: ", err)
|
||||
}
|
||||
|
||||
var tempSP subscribeplandomain.SubscribePlan
|
||||
var tempCtg categorydomain.Category
|
||||
|
||||
if err := db.Where("code = ?", "basic").First(&tempSP).Error; err != nil {
|
||||
log.Print("seeding basic subscribe plan")
|
||||
db.Create(&subscribeplandomain.SubscribePlan{
|
||||
ID: uuid.NewString(),
|
||||
Code: "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,
|
||||
})
|
||||
}
|
||||
|
||||
log.Print("migrate success")
|
||||
}
|
||||
|
||||
+31
-13
@@ -4,38 +4,55 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"legalgo-BE-go/config"
|
||||
"legalgo-BE-go/database"
|
||||
repository "legalgo-BE-go/internal/accessor"
|
||||
internalhttp "legalgo-BE-go/internal/api/http"
|
||||
pkgconfig "legalgo-BE-go/internal/config"
|
||||
"legalgo-BE-go/internal/services"
|
||||
|
||||
"github.com/ardeman/project-legalgo-go/database"
|
||||
repository "github.com/ardeman/project-legalgo-go/internal/accessor"
|
||||
internalhttp "github.com/ardeman/project-legalgo-go/internal/api/http"
|
||||
pkgconfig "github.com/ardeman/project-legalgo-go/internal/config"
|
||||
"github.com/ardeman/project-legalgo-go/internal/services"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := godotenv.Load(); err != nil {
|
||||
log.Fatal("cannot load environment file")
|
||||
// Check if the .env file exists
|
||||
if _, err := os.Stat(".env"); err == nil {
|
||||
// Load environment variables from .env file if it exists
|
||||
if err := godotenv.Load(); err != nil {
|
||||
log.Println("Error loading .env file, continuing without it")
|
||||
}
|
||||
} else {
|
||||
log.Println(".env file not found, skipping load")
|
||||
}
|
||||
|
||||
config.InitEnv()
|
||||
}
|
||||
|
||||
func run(lc fx.Lifecycle, db *database.DB, apiRouter chi.Router) {
|
||||
func run(
|
||||
lc fx.Lifecycle,
|
||||
db *database.DB,
|
||||
apiRouter chi.Router,
|
||||
rdb *redis.Client,
|
||||
) {
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(ctx context.Context) error {
|
||||
fmt.Println("Application has started...")
|
||||
// Run migration
|
||||
if err := db.Migrate(); err != nil {
|
||||
log.Fatal("Migration failed: ", err)
|
||||
_, err := rdb.Ping(ctx).Result()
|
||||
if err != nil {
|
||||
log.Fatalf("Could not connect to Redis: %v", err)
|
||||
}
|
||||
|
||||
pkgconfig.Router(apiRouter)
|
||||
|
||||
return nil
|
||||
},
|
||||
OnStop: func(ctx context.Context) error {
|
||||
fmt.Println("Shutting down...")
|
||||
rdb.Close()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
@@ -43,10 +60,11 @@ func run(lc fx.Lifecycle, db *database.DB, apiRouter chi.Router) {
|
||||
|
||||
func main() {
|
||||
app := fx.New(
|
||||
config.Module,
|
||||
database.Module,
|
||||
repository.Module,
|
||||
internalhttp.Module,
|
||||
services.Module,
|
||||
internalhttp.Module,
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package config
|
||||
|
||||
import "fmt"
|
||||
|
||||
var (
|
||||
APP_PORT,
|
||||
REDIS_DB,
|
||||
REDIS_TIMEOUT,
|
||||
GRACEFULL_TIMEOUT int
|
||||
|
||||
// DB
|
||||
DB_HOST,
|
||||
DB_USER,
|
||||
DB_PASSWORD,
|
||||
DB_NAME,
|
||||
DB_PORT,
|
||||
REDIS_PASSWORD,
|
||||
REDIS_ADDR,
|
||||
REDIS_USERNAME,
|
||||
SALT_SECURITY string
|
||||
)
|
||||
|
||||
func InitEnv() {
|
||||
DB_HOST = GetOrDefault("DB_HOST", "localhost")
|
||||
DB_USER = GetOrDefault("DB_USER", "")
|
||||
DB_PASSWORD = GetOrDefault("DB_PASSWORD", "")
|
||||
DB_NAME = GetOrDefault("DB_NAME", "")
|
||||
DB_PORT = GetOrDefault("DB_PORT", "")
|
||||
|
||||
SALT_SECURITY = GetOrDefault("SALT_SECURITY", "legalgo")
|
||||
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func GetOrDefault[T any](key string, defaultValue T) T {
|
||||
value, exist := os.LookupEnv(key)
|
||||
|
||||
if !exist {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
var valueInstance T
|
||||
kind := reflect.ValueOf(valueInstance).Kind()
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
return any(value).(T)
|
||||
case reflect.Int:
|
||||
if val, err := strconv.Atoi(value); err == nil {
|
||||
return any(val).(T)
|
||||
}
|
||||
return any(defaultValue).(T)
|
||||
case reflect.Bool:
|
||||
if val, err := strconv.ParseBool(value); err == nil {
|
||||
return any(val).(T)
|
||||
}
|
||||
return any(defaultValue).(T)
|
||||
default:
|
||||
return any(defaultValue).(T)
|
||||
}
|
||||
}
|
||||
@@ -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"`
|
||||
}
|
||||
+30
-12
@@ -2,9 +2,9 @@ package database
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
|
||||
"legalgo-BE-go/config"
|
||||
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -13,17 +13,17 @@ type DB struct {
|
||||
*gorm.DB
|
||||
}
|
||||
|
||||
func NewDB() (*DB, error) {
|
||||
var (
|
||||
host = os.Getenv("DB_HOST")
|
||||
user = os.Getenv("DB_USER")
|
||||
password = os.Getenv("DB_PASSWORD")
|
||||
dbName = os.Getenv("DB_NAME")
|
||||
dbPort = os.Getenv("DB_PORT")
|
||||
func NewDB(cfg *config.Config) (*DB, error) {
|
||||
dsn := fmt.Sprintf(
|
||||
"host=%s user=%s password=%s dbname=%s port=%v sslmode=%s",
|
||||
cfg.Database.Host,
|
||||
cfg.Database.Username,
|
||||
cfg.Database.Password,
|
||||
cfg.Database.DB,
|
||||
cfg.Database.Port,
|
||||
cfg.Database.SslMode,
|
||||
)
|
||||
|
||||
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%v sslmode=disable", host, user, password, dbName, dbPort)
|
||||
|
||||
if dsn == "" {
|
||||
return nil, fmt.Errorf("DATABASE_URL environment is not set")
|
||||
}
|
||||
@@ -37,7 +37,25 @@ func NewDB() (*DB, error) {
|
||||
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 {
|
||||
// Auto Migrate the User model
|
||||
return db.AutoMigrate(&staffmodel.Staff{})
|
||||
return db.AutoMigrate(
|
||||
&Staff{},
|
||||
&SubscribePlan{},
|
||||
&Subscribe{},
|
||||
&User{},
|
||||
&News{},
|
||||
&Tag{},
|
||||
&Category{},
|
||||
&Ads{},
|
||||
&ContentLog{},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type News struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Title string `json:"title"`
|
||||
Content string `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"`
|
||||
Slug string `gorm:"default:null" json:"slug"`
|
||||
FeaturedImage string `gorm:"default:null" json:"featured_image"`
|
||||
AuthorID string `gorm:"not null" json:"author_id"`
|
||||
LiveAt time.Time `gorm:"not null" json:"live_at"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
|
||||
|
||||
Author Staff `gorm:"foreignKey:AuthorID" json:"author"`
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package staffmodel
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type Staff struct {
|
||||
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
|
||||
Email string `gorm:"unique,not null" json:"email"`
|
||||
Password string `gorm:"not null" json:"password"`
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Staff struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"default:null" json:"name"`
|
||||
ProfilePicture string `gorm:"default:null" json:"profile_picture"`
|
||||
Email string `gorm:"unique;not null" json:"email"`
|
||||
Password string `gorm:"not null" json:"password"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Subscribe struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
SubscribePlanID string `gorm:"not null" json:"subscribe_plan_id"`
|
||||
StartDate time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
||||
EndDate time.Time `gorm:"default:null"`
|
||||
Status int8 `gorm:"default:0"`
|
||||
AutoRenew bool `gorm:"default:true"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
||||
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
|
||||
|
||||
SubscribePlan SubscribePlan `gorm:"foreignKey:SubscribePlanID;constraint:OnDelete:CASCADE" json:"subscribe_plan"`
|
||||
}
|
||||
|
||||
type SubscribePlan struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Code string `gorm:"not null;unique" json:"code"`
|
||||
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"`
|
||||
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"`
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID string `gorm:"primaryKey;not null" json:"id"`
|
||||
SubscribeID string `gorm:"not null" json:"subscribe_id"`
|
||||
Email string `gorm:"unique;not null" json:"email"`
|
||||
Password string `gorm:"not null" json:"password"`
|
||||
Phone string `gorm:"default:not null;unique" json:"phone"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
|
||||
|
||||
Subscribe Subscribe `gorm:"foreignKey:SubscribeID;constraint:OnDelete:CASCADE" 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,40 +1,56 @@
|
||||
module github.com/ardeman/project-legalgo-go
|
||||
module legalgo-BE-go
|
||||
|
||||
go 1.24.0
|
||||
go 1.24
|
||||
|
||||
require (
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/spf13/viper v1.19.0
|
||||
go.uber.org/fx v1.23.0
|
||||
golang.org/x/crypto v0.34.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/postgres v1.5.7
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/go-playground/locales v0.14.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/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v5 v5.7.2 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jackc/pgx/v5 v5.4.3 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
golang.org/x/crypto v0.34.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/text v0.22.0 // indirect
|
||||
gorm.io/driver/postgres v1.5.11 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go v1.50.0
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/go-chi/chi v1.5.5
|
||||
github.com/go-chi/chi/v5 v5.2.1 // indirect
|
||||
github.com/go-chi/chi/v5 v5.2.1
|
||||
github.com/go-chi/cors v1.2.1
|
||||
github.com/go-playground/validator/v10 v10.25.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/redis/go-redis/v9 v9.7.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/redis/go-redis/v9 v9.7.1
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
go.uber.org/dig v1.18.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
go.uber.org/zap v1.26.0 // indirect
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
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/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/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.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/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/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
|
||||
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
|
||||
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
|
||||
github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
||||
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
@@ -21,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/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
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/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/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/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
|
||||
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||
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/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
|
||||
github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
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/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/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.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/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/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.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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
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.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/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
||||
go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
|
||||
@@ -60,10 +112,10 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
|
||||
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
@@ -71,15 +123,19 @@ golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
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 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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
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.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
||||
gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
|
||||
gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
|
||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||
|
||||
@@ -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,10 +1,31 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
staffrepository "github.com/ardeman/project-legalgo-go/internal/accessor/staff"
|
||||
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"
|
||||
staffrepository "legalgo-BE-go/internal/accessor/staff"
|
||||
subscriberepository "legalgo-BE-go/internal/accessor/subscribe"
|
||||
subscribeplanrepository "legalgo-BE-go/internal/accessor/subscribe_plan"
|
||||
tagrepository "legalgo-BE-go/internal/accessor/tag"
|
||||
userrepository "legalgo-BE-go/internal/accessor/user"
|
||||
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
var Module = fx.Module("repository", fx.Provide(
|
||||
staffrepository.New,
|
||||
userrepository.New,
|
||||
redisaccessor.New,
|
||||
subscribeplanrepository.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
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package redisaccessor
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"legalgo-BE-go/config"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
var redisClient *redis.Client
|
||||
|
||||
func Get() *redis.Client {
|
||||
return redisClient
|
||||
}
|
||||
|
||||
func New(cfg *config.Config) *redis.Client {
|
||||
addr := fmt.Sprintf("%s:%s", cfg.Redis.Host, cfg.Redis.Port)
|
||||
|
||||
options := &redis.Options{
|
||||
Addr: addr,
|
||||
Password: cfg.Redis.Password,
|
||||
DB: cfg.Redis.DB,
|
||||
}
|
||||
|
||||
if cfg.Redis.Username != "" {
|
||||
options.Username = cfg.Redis.Username
|
||||
}
|
||||
if cfg.Redis.SSL {
|
||||
options.TLSConfig = &tls.Config{}
|
||||
}
|
||||
|
||||
redisClient = redis.NewClient(options)
|
||||
return redisClient
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
)
|
||||
|
||||
func (ur *accessor) Create(spec staffdomain.Staff) error {
|
||||
if err := ur.db.Create(&spec).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (sr *accessor) GetStaffByEmail(email string) (*staffdomain.Staff, error) {
|
||||
var staff staffdomain.Staff
|
||||
|
||||
if email == "" {
|
||||
return nil, fmt.Errorf("email is required")
|
||||
}
|
||||
|
||||
if err := sr.db.First(&staff, "email = ?", email).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fmt.Errorf("staff not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &staff, nil
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (sr *accessor) GetStaffByID(ID string) (*staffdomain.Staff, error) {
|
||||
var staff staffdomain.Staff
|
||||
|
||||
if ID == "" {
|
||||
return nil, fmt.Errorf("id is required")
|
||||
}
|
||||
|
||||
if err := sr.db.First(&staff, "id = ? ", ID).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fmt.Errorf("staff not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &staff, nil
|
||||
}
|
||||
@@ -1,25 +1,13 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
import staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
|
||||
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
func (a *accessor) GetStaffs() ([]staffdomain.StaffProfile, error) {
|
||||
var staffs []staffdomain.StaffProfile
|
||||
|
||||
func (sr *StaffRepository) GetStaff(email string) (*staffmodel.Staff, error) {
|
||||
var staff staffmodel.Staff
|
||||
|
||||
if email == "" {
|
||||
return nil, errors.New("email is empty")
|
||||
if err := a.db.Table("staffs").Find(&staffs).Error; err != nil {
|
||||
return staffs, err
|
||||
}
|
||||
|
||||
if err := sr.DB.Where("email = ?", email).First(&staff).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("staff not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &staff, nil
|
||||
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
|
||||
}
|
||||
@@ -1,18 +1,24 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
"github.com/ardeman/project-legalgo-go/database"
|
||||
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
|
||||
"legalgo-BE-go/database"
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
userdomain "legalgo-BE-go/internal/domain/user"
|
||||
)
|
||||
|
||||
type StaffRepository struct {
|
||||
DB *database.DB
|
||||
type accessor struct {
|
||||
db *database.DB
|
||||
}
|
||||
|
||||
type StaffInterface interface {
|
||||
GetStaff(string) (*staffmodel.Staff, error)
|
||||
type Staff interface {
|
||||
GetStaffByEmail(string) (*staffdomain.Staff, error)
|
||||
GetStaffByID(string) (*staffdomain.Staff, error)
|
||||
GetUsers() ([]userdomain.UserProfile, error)
|
||||
GetStaffs() ([]staffdomain.StaffProfile, error)
|
||||
Create(staffdomain.Staff) error
|
||||
Update(staffdomain.Staff) error
|
||||
}
|
||||
|
||||
func New(db *database.DB) StaffInterface {
|
||||
return &StaffRepository{db}
|
||||
func New(db *database.DB) Staff {
|
||||
return &accessor{db}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
staffdomain "legalgo-BE-go/internal/domain/staff"
|
||||
)
|
||||
|
||||
func (ur *accessor) Update(spec staffdomain.Staff) error {
|
||||
// val, err := utils.StructToMap(spec)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
if err := ur.db.Model(&staffdomain.Staff{}).Where("id = ?", spec.ID).Updates(spec).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package subscriberepository
|
||||
|
||||
import (
|
||||
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (s *accessor) Create(subsPlanId string) (string, error) {
|
||||
spec := &subscribedomain.Subscribe{
|
||||
ID: uuid.NewString(),
|
||||
SubscribePlanID: subsPlanId,
|
||||
}
|
||||
|
||||
if err := s.db.Create(&spec).Error; err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return spec.ID, nil
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package subscriberepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
|
||||
)
|
||||
|
||||
type accessor struct {
|
||||
db *database.DB
|
||||
}
|
||||
|
||||
type Subscribe interface {
|
||||
Create(string) (string, error)
|
||||
GetByID(string) (subscribedomain.Subscribe, error)
|
||||
Update(subscribedomain.Subscribe) error
|
||||
}
|
||||
|
||||
func New(db *database.DB) Subscribe {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package subscribeplanrepository
|
||||
|
||||
import (
|
||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||
)
|
||||
|
||||
func (s *accessor) GetAll() ([]subscribeplandomain.SubscribePlan, error) {
|
||||
var subscribePlans []subscribeplandomain.SubscribePlan
|
||||
|
||||
if err := s.db.Find(&subscribePlans).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return subscribePlans, nil
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package adshttp
|
||||
|
||||
import (
|
||||
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
adssvc "legalgo-BE-go/internal/services/ads"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func Create(
|
||||
router chi.Router,
|
||||
adsSvc adssvc.Ads,
|
||||
validate *validator.Validate,
|
||||
) {
|
||||
router.
|
||||
With(authmiddleware.Authorize()).
|
||||
Post("/ads/create", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var spec adsdomain.AdsReq
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed to unmarshal body",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.(validator.ValidationErrors).Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := adsSvc.Create(spec); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string
|
||||
}{
|
||||
Message: "ads created successfully",
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package adshttp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
|
||||
adssvc "legalgo-BE-go/internal/services/ads"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func Delete(
|
||||
router chi.Router,
|
||||
adsSvc adssvc.Ads,
|
||||
) {
|
||||
router.
|
||||
With(authmiddleware.Authorize()).
|
||||
Delete("/ads/{ads_id}/delete", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
adsID := chi.URLParam(r, "ads_id")
|
||||
|
||||
if adsID == "" {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
fmt.Errorf("ads id is not provided"),
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"ads id is not provided",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := adsSvc.Delete(adsID); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string
|
||||
}{
|
||||
Message: "ads has been deleted",
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package adshttp
|
||||
|
||||
import (
|
||||
adssvc "legalgo-BE-go/internal/services/ads"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func GetAll(
|
||||
router chi.Router,
|
||||
adsSvc adssvc.Ads,
|
||||
) {
|
||||
router.Get("/ads", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
subsPlan, err := adsSvc.GetAll()
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, subsPlan)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package adshttp
|
||||
|
||||
import "go.uber.org/fx"
|
||||
|
||||
var Module = fx.Module("ads-http", fx.Invoke(
|
||||
Create,
|
||||
GetAll,
|
||||
Update,
|
||||
Delete,
|
||||
))
|
||||
@@ -0,0 +1,82 @@
|
||||
package adshttp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
|
||||
adsdomain "legalgo-BE-go/internal/domain/ads"
|
||||
adssvc "legalgo-BE-go/internal/services/ads"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func Update(
|
||||
router chi.Router,
|
||||
validate *validator.Validate,
|
||||
adsSvc adssvc.Ads,
|
||||
) {
|
||||
router.
|
||||
With(authmiddleware.Authorize()).
|
||||
Put("/ads/{ads_id}/update", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
adsID := chi.URLParam(r, "ads_id")
|
||||
|
||||
if adsID == "" {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
fmt.Errorf("ads id is not provided"),
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"ads id is not provided",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
var spec adsdomain.AdsReq
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed to unmarshal body",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.(validator.ValidationErrors).Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := adsSvc.Update(adsID, spec); err != nil {
|
||||
response.RespondJsonErrorWithCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string
|
||||
}{
|
||||
Message: "update ads success",
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package authhttp
|
||||
|
||||
import "go.uber.org/fx"
|
||||
|
||||
var Module = fx.Module("auth-api",
|
||||
fx.Invoke(
|
||||
LoginStaff,
|
||||
),
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user